diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index c3f502a..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 디폴트 무시된 파일 -/shelf/ -/workspace.xml -# 에디터 기반 HTTP 클라이언트 요청 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/PDFWiz-App.iml b/.idea/PDFWiz-App.iml new file mode 100644 index 0000000..e3969c4 --- /dev/null +++ b/.idea/PDFWiz-App.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..2979000 --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 639900d..b1b8ebb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 5006e03..27abf36 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 01d5f14..98712e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,12 +16,17 @@ "@types/node": "^16.18.48", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", + "@xeger/quill-image-actions": "^0.7.2", + "@xeger/quill-image-formats": "^0.7.2", "antd": "^5.8.6", "html2canvas": "^1.4.1", "pdf-lib": "^1.17.1", "pdfjs-dist": "^3.10.174", + "quill-better-table": "^1.2.10", + "quill-table-ui": "^1.0.7", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-quill": "^2.0.0", "react-scripts": "5.0.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4" @@ -36,9 +41,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==" + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==" }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", @@ -129,11 +134,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -219,11 +224,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dependencies": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -355,12 +360,12 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -502,9 +507,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } @@ -552,9 +557,9 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -565,9 +570,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -2038,19 +2043,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.20.tgz", - "integrity": "sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.19", - "debug": "^4.1.0", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2058,12 +2063,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.19", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", - "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.19", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -3783,9 +3788,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz", - "integrity": "sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -4322,6 +4327,14 @@ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" }, + "node_modules/@types/quill": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", + "integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==", + "dependencies": { + "parchment": "^1.1.2" + } + }, "node_modules/@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", @@ -4791,6 +4804,29 @@ "@xtuc/long": "4.2.2" } }, + "node_modules/@xeger/quill-image-actions": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@xeger/quill-image-actions/-/quill-image-actions-0.7.2.tgz", + "integrity": "sha512-OhaZnYCie9J1ZLx2+Nsznj+qkdHn9Yx7q3iOCCKFs6kAzcZUVBPv2fMjK+nzURySLyCVQOP3Ur2mZx1yYqgppw==", + "dependencies": { + "core-js": "^3.0", + "deepmerge": "^4.2" + }, + "peerDependencies": { + "quill": "^1.3.6" + } + }, + "node_modules/@xeger/quill-image-formats": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@xeger/quill-image-formats/-/quill-image-formats-0.7.2.tgz", + "integrity": "sha512-L9beiJKWzjHxBJEZB21I8YjFgOHYROsrfFMvIqP+kjc/u/MecHY1mXzR9VySLr+Qvj55t+vkKKuJ0ZPKvQSaPA==", + "dependencies": { + "core-js": "^3.0" + }, + "peerDependencies": { + "quill": "^1.3.6" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6114,6 +6150,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8288,11 +8332,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -8512,9 +8566,9 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -12777,9 +12831,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", @@ -13256,6 +13310,11 @@ "tslib": "^2.0.3" } }, + "node_modules/parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -13548,10 +13607,15 @@ "node": ">=4" } }, + "node_modules/positioning": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/positioning/-/positioning-2.0.1.tgz", + "integrity": "sha512-DsAgM42kV/ObuwlRpAzDTjH9E8fGKkMDJHWFX+kfNXSxh7UCCQxEmdjv/Ws5Ft1XDnt3JT8fIDYeKNSE2TbttA==" + }, "node_modules/postcss": { - "version": "8.4.30", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz", - "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -13567,7 +13631,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -14907,6 +14971,91 @@ } ] }, + "node_modules/quill": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "dependencies": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "node_modules/quill-better-table": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/quill-better-table/-/quill-better-table-1.2.10.tgz", + "integrity": "sha512-CFwxAQzt4EPCQuynQ65R/FU7Yu//kcDBb/rmBBOsFfO758+q50zvG/PDt4Lenv9DcrSgwnyNkfo4yeA5fzzVYQ==" + }, + "node_modules/quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "dependencies": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/quill-delta/node_modules/deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "dependencies": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quill-table-ui": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/quill-table-ui/-/quill-table-ui-1.0.7.tgz", + "integrity": "sha512-Zr/KWiLmCkaaS1eybwkQX17FUGJEBvpHAOSP7A8J+E2P4R56S+Uvs+U2i+fIxaydfnPksDV/sDJ8EWsFg37dsQ==", + "dependencies": { + "positioning": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/quill/node_modules/deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "dependencies": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quill/node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" + }, "node_modules/raf": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", @@ -15726,6 +15875,20 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-quill": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0.tgz", + "integrity": "sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==", + "dependencies": { + "@types/quill": "^1.3.10", + "lodash": "^4.17.4", + "quill": "^1.3.7" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", diff --git a/package.json b/package.json index 1babb98..ce00f57 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,17 @@ "@types/node": "^16.18.48", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", + "@xeger/quill-image-actions": "^0.7.2", + "@xeger/quill-image-formats": "^0.7.2", "antd": "^5.8.6", "html2canvas": "^1.4.1", "pdf-lib": "^1.17.1", "pdfjs-dist": "^3.10.174", + "quill-better-table": "^1.2.10", + "quill-table-ui": "^1.0.7", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-quill": "^2.0.0", "react-scripts": "5.0.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4" diff --git a/public/index.html b/public/index.html index aa069f2..bfee389 100644 --- a/public/index.html +++ b/public/index.html @@ -25,6 +25,10 @@ Learn how to configure a non-root public URL by running `npm run build`. --> React App + + + + diff --git a/src/CronMaker/CronMaker.tsx b/src/CronMaker/CronMaker.tsx index 1208faf..051dd89 100644 --- a/src/CronMaker/CronMaker.tsx +++ b/src/CronMaker/CronMaker.tsx @@ -1,3 +1,5 @@ + + import useCreateCronExpression, {CronDayTimeProps, CronDefinDayProps} from "./Hook/useCreateCronExpression"; import React, {useState} from "react"; import {Button, Checkbox, Select} from "antd"; diff --git a/src/test/Test.css b/src/test/Test.css new file mode 100644 index 0000000..903442d --- /dev/null +++ b/src/test/Test.css @@ -0,0 +1,130 @@ +/* Set default font-family */ +.app .ql-editor { + font-family: "Ubuntu"; +} + +/* Set dropdown font-families */ + + + +.ql-picker.ql-font .ql-picker-label[data-value="맑은고딕"]::before, +.ql-picker.ql-font .ql-picker-item[data-value="맑은고딕"]::before +{ + font-family: "Malgun Gothic", cursive; + content: "맑은고딕"; +} +.ql-font-맑은고딕 { + font-family: "Malgun Gothic"; +} + +.ql-picker.ql-font .ql-picker-label[data-value="돋움"]::before, +.ql-picker.ql-font .ql-picker-item[data-value="돋움"]::before +{ + font-family: "Dotum", cursive; + content: "돋움"; +} +.ql-font-돋움 { + font-family: "Dotum"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="8px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="8px"]::before +{ + font-family: "Arial", cursive; + content: "8px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="9px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="9px"]::before +{ + font-family: "Arial", cursive; + content: "9px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="10px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="10px"]::before +{ + font-family: "Arial", cursive; + content: "10px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="12px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="12px"]::before +{ + font-family: "Arial", cursive; + content: "12px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="14px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="14px"]::before +{ + font-family: "Arial", cursive; + content: "14px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="16px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="16px"]::before +{ + font-family: "Arial", cursive; + content: "16px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="20px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="20px"]::before +{ + font-family: "Arial", cursive; + content: "20px"; +} + + +.ql-picker.ql-size .ql-picker-label[data-value="24px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="24px"]::before +{ + font-family: "Arial", cursive; + content: "24px"; +} + + +.ql-picker.ql-size .ql-picker-label[data-value="32px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="32px"]::before +{ + font-family: "Arial", cursive; + content: "32px"; +} + + +.ql-picker.ql-size .ql-picker-label[data-value="42px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="42px"]::before +{ + font-family: "Arial", cursive; + content: "42px"; +} + + +.ql-picker.ql-size .ql-picker-label[data-value="54px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="54px"]::before +{ + font-family: "Arial", cursive; + content: "54px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="68px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="68px"]::before +{ + font-family: "Arial", cursive; + content: "68px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="84px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="84px"]::before +{ + font-family: "Arial", cursive; + content: "84px"; +} + +.ql-picker.ql-size .ql-picker-label[data-value="98px"]::before, +.ql-picker.ql-size .ql-picker-item[data-value="98px"]::before +{ + font-family: "Arial", cursive; + content: "98px"; +} \ No newline at end of file diff --git a/src/test/Test.tsx b/src/test/Test.tsx index 2fdceb7..a60de74 100644 --- a/src/test/Test.tsx +++ b/src/test/Test.tsx @@ -1,31 +1,189 @@ -import { Input } from 'antd'; import React, { useState } from 'react'; -import {EditOutlined} from "@ant-design/icons"; +import ReactQuill from 'react-quill'; +import 'react-quill/dist/quill.snow.css'; -const MyComponent = () => { - const [inputValue, setInputValue] = useState(''); +import { ImageActions } from '@xeger/quill-image-actions'; +import { ImageFormats } from '@xeger/quill-image-formats'; + +import * as QuillTableUI from 'quill-table-ui' + + +import {Button} from "antd"; +import "./Test.css" + + + +function MyQuillEditor() { + + ReactQuill.Quill.register('modules/imageActions', ImageActions); + ReactQuill.Quill.register('modules/imageFormats', ImageFormats); + + ReactQuill.Quill.register('modules/tableUI', QuillTableUI.default); + + function setTable() + { + + } + + + + const fontSizeArr = ['8px','9px','10px','12px','14px','16px','20px','24px','32px','42px','54px','68px','84px','98px']; + var Size = ReactQuill.Quill.import('attributors/style/size'); + Size.whitelist = fontSizeArr; + ReactQuill.Quill.register(Size, true); + + const fontListArr = ['맑은고딕', "돋움"] + const Font = ReactQuill.Quill.import('formats/font'); // <<<< ReactQuill exports it + Font.whitelist = fontListArr; // allow ONLY these fonts and the default + ReactQuill.Quill.register(Font, true); + + + const [text, setText] = useState(''); + + const handleChange = async (value: string) => { + // const parsedValue = await parseHTML(value); + parseHTML(value); - const handleChange = (e:any) => { - // Input 값이 변경될 때 상태 업데이트 - setInputValue(e.target.value); }; - const setNewValue = () => { - // 상태를 직접 변경 - setInputValue('New Value'); + const formats = [ + "header", + "font", + "size", + "bold", + "italic", + "underline", + "align", + "strike", + "script", + "blockquote", + "background", + "list", + "bullet", + "indent", + "link", + "image", + "color", + "code-block", + 'float', + 'height', + 'width', + + ]; + + const modules = { + imageActions: {}, + imageFormats: {}, + tableUI: true, + toolbar: { + container: [ + [{ 'font': fontListArr}, { 'size': fontSizeArr }], + + //[{ 'header': [1, 2, 3, 4, 5, 6, false] }], + [{ 'header': [1, 2, 3, 4, 5, 6, false] }], + ['bold', 'italic', 'underline', 'strike', { 'color': [] }, { 'background': [] }], // toggled buttons + + [{ 'align': ""}, { 'align':"center" }, { 'align':"right" }], + + [{ 'list': 'ordered'}, { 'list': 'bullet' }], + [{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript + + ['blockquote', 'code-block'], + ["link", "image"] + + + //[{ 'header': 1 }, { 'header': 2 }], // custom button values + //[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent + //[{ 'direction': 'rtl' }], // text direction + + //[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown + + + + + + //['clean'] // remove formatting button + ], + }, + + history: { + delay: 500, + maxStack: 100, + userOnly: true + }, }; + const parseHTML = (htmlString:string)=> { + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlString, 'text/html'); + const imgTags = doc.querySelectorAll('img'); + + + imgTags.forEach((imgTag) => { + + const src = imgTag.getAttribute('src'); + + if (src && !isBase64(src)) { + convertUrlToBase64(src).then((base64) => { + // 여기에서 base64로 변환된 값을 활용하거나 상태에 저장할 수 있습니다. + imgTag.src = base64; + // Get the updated HTML string after modifications + const updatedHtmlString = doc.documentElement.outerHTML; + + // Update the state with the modified HTML string + setText(updatedHtmlString); + }); + } + }); + + setText(htmlString); + + + }; + + const isBase64 = (str: string): boolean => { + return /^data:image\/[a-z]+;base64,/.test(str); + }; + + const convertUrlToBase64 = async (url: string): Promise => { + const response = await fetch(url); + const blob = await response.blob(); + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => { + resolve(reader.result as string); + }; + reader.readAsDataURL(blob); + }); + }; + + function send() + { + alert(text); + } + return ( -
- } - placeholder="서비스코드" - value={inputValue} - onChange={handleChange} - /> - -
+ <> +
+ + +
+ + + + + ); -}; -export default MyComponent; \ No newline at end of file +} + +export default MyQuillEditor;