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;