feat: EditSettings view
This commit is contained in:
parent
9ab297a471
commit
a50e3ca50e
8 changed files with 406 additions and 150 deletions
|
@ -238,9 +238,11 @@ collection:
|
|||
'@freesewing/snapseries': *freesewing
|
||||
react:
|
||||
_:
|
||||
"@codemirror/lang-yaml": "^6.1.2"
|
||||
"@uiw/react-codemirror": "^4.23.8"
|
||||
d3-drag: "3.0.0"
|
||||
d3-selection: "3.0.0"
|
||||
diff: "^7.0.0"
|
||||
file-saver: "^2.0.5"
|
||||
"highlight.js": "^11.11.1"
|
||||
html-react-parser: "^5.2.2"
|
||||
|
@ -248,11 +250,13 @@ react:
|
|||
jotai-location: "^0.5.5"
|
||||
luxon: "^3.5.0"
|
||||
pdfkit: "^0.16.0"
|
||||
react-diff-viewer-continued: "^4.0.5"
|
||||
react-dropzone: "^14.3.5"
|
||||
react-zoom-pan-pinch: "^3.7.0"
|
||||
svg-to-pdfkit: "^0.1.8"
|
||||
use-local-storage-state: "^19.5.0"
|
||||
web-worker: "^1.5.0"
|
||||
yaml: "^2.7.0"
|
||||
peer:
|
||||
react: &react "^19.0.0"
|
||||
utils:
|
||||
|
|
|
@ -81,6 +81,7 @@ packageJson:
|
|||
"./components/Control": "./components/Control/index.mjs"
|
||||
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs"
|
||||
"./components/Design": "./components/Design/index.mjs"
|
||||
"./components/DiffViewer": "./components/DiffViewer/index.mjs"
|
||||
"./components/Docusaurus": "./components/Docusaurus/index.mjs"
|
||||
"./components/Editor": "./components/Editor/index.mjs"
|
||||
"./components/Heading": "./components/Heading/index.mjs"
|
||||
|
@ -120,6 +121,7 @@ packageJson:
|
|||
"./hooks/useDesign": "./hooks/useDesign/index.mjs"
|
||||
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs"
|
||||
"./hooks/useSelection": "./hooks/useSelection/index.mjs"
|
||||
"./hooks/useStateObject": "./hooks/useStateObject/index.mjs"
|
||||
# Lib
|
||||
"./lib/RestClient": "./lib/RestClient/index.mjs"
|
||||
"./lib/logoPath": "./components/Logo/path.mjs"
|
||||
|
|
268
package-lock.json
generated
268
package-lock.json
generated
|
@ -23951,6 +23951,21 @@
|
|||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-yaml": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.2.tgz",
|
||||
"integrity": "sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.2.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"@lezer/yaml": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "6.10.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.8.tgz",
|
||||
|
@ -26309,6 +26324,188 @@
|
|||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
||||
"integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.16.7",
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/hash": "^0.9.2",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/serialize": "^1.3.3",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"convert-source-map": "^1.5.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"find-root": "^1.1.0",
|
||||
"source-map": "^0.5.7",
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/babel-plugin-macros": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
|
||||
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"cosmiconfig": "^7.0.0",
|
||||
"resolve": "^1.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/cosmiconfig": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
||||
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0",
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/yaml": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
|
||||
"integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/sheet": "^1.4.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"@emotion/weak-memoize": "^0.4.0",
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/css": {
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.13.5.tgz",
|
||||
"integrity": "sha512-wQdD0Xhkn3Qy2VNcIzbLP9MR8TafI0MJb7BEAXKp+w4+XqErksWR4OXomuDzPsN4InLdGhVe6EYcn2ZIUCpB8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
"@emotion/cache": "^11.13.5",
|
||||
"@emotion/serialize": "^1.3.3",
|
||||
"@emotion/sheet": "^1.4.0",
|
||||
"@emotion/utils": "^1.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/hash": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
|
||||
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/memoize": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
|
||||
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/react": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
|
||||
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
"@emotion/cache": "^11.14.0",
|
||||
"@emotion/serialize": "^1.3.3",
|
||||
"@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"@emotion/weak-memoize": "^0.4.0",
|
||||
"hoist-non-react-statics": "^3.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/serialize": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
|
||||
"integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/hash": "^0.9.2",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/unitless": "^0.10.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/sheet": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
|
||||
"integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/unitless": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
|
||||
"integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
|
||||
"integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/utils": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
|
||||
"integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/weak-memoize": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
|
||||
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
|
||||
|
@ -27721,6 +27918,17 @@
|
|||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/yaml": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.3.tgz",
|
||||
"integrity": "sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@marijn/find-cluster-break": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||
|
@ -34097,6 +34305,12 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
||||
|
@ -37368,7 +37582,6 @@
|
|||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
|
||||
"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
|
@ -39868,6 +40081,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/find-root": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
|
||||
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/find-up": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
|
||||
|
@ -48070,6 +48289,12 @@
|
|||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/meow": {
|
||||
"version": "12.1.1",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
|
||||
|
@ -54643,6 +54868,26 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/react-diff-viewer-continued": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-diff-viewer-continued/-/react-diff-viewer-continued-4.0.5.tgz",
|
||||
"integrity": "sha512-L43gIPdhHgu1MYdip4vNqAt5s2JLICKe2/RyGUr2ohAxfhYaH1+QZ6vBO0qgo4xGBhE3jmvbOA/swq4/gdS/0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/css": "^11.13.5",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"classnames": "^2.5.1",
|
||||
"diff": "^5.2.0",
|
||||
"memoize-one": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
||||
|
@ -57881,6 +58126,12 @@
|
|||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/stylis": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sucrase": {
|
||||
"version": "3.35.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
|
||||
|
@ -61968,9 +62219,11 @@
|
|||
"version": "3.3.0-rc.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-yaml": "^6.1.2",
|
||||
"@uiw/react-codemirror": "^4.23.8",
|
||||
"d3-drag": "3.0.0",
|
||||
"d3-selection": "3.0.0",
|
||||
"diff": "^7.0.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"highlight.js": "^11.11.1",
|
||||
"html-react-parser": "^5.2.2",
|
||||
|
@ -61978,11 +62231,13 @@
|
|||
"jotai-location": "^0.5.5",
|
||||
"luxon": "^3.5.0",
|
||||
"pdfkit": "^0.16.0",
|
||||
"react-diff-viewer-continued": "^4.0.5",
|
||||
"react-dropzone": "^14.3.5",
|
||||
"react-zoom-pan-pinch": "^3.7.0",
|
||||
"svg-to-pdfkit": "^0.1.8",
|
||||
"use-local-storage-state": "^19.5.0",
|
||||
"web-worker": "^1.5.0"
|
||||
"web-worker": "^1.5.0",
|
||||
"yaml": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
|
@ -61996,6 +62251,15 @@
|
|||
"react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"packages/react/node_modules/diff": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
|
||||
"integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"packages/rehype-highlight-lines": {
|
||||
"version": "3.3.0-rc.1",
|
||||
"extraneous": true,
|
||||
|
|
8
packages/react/components/DiffViewer/index.mjs
Normal file
8
packages/react/components/DiffViewer/index.mjs
Normal file
|
@ -0,0 +1,8 @@
|
|||
import React from 'react'
|
||||
import { diffWords, diffJson } from 'diff'
|
||||
import ReactDiffViewer from 'react-diff-viewer-continued'
|
||||
|
||||
export const diffJSON = (from, to) => diffJson(from, to)
|
||||
export const diffCheck = (from, to) => diffWords(from, to)
|
||||
|
||||
export const DiffViewer = (props) => <ReactDiffViewer {...props} />
|
|
@ -1,14 +1,26 @@
|
|||
// Dependencies
|
||||
import { linkClasses, horFlexClasses, patternUrlFromState } from '@freesewing/utils'
|
||||
import { linkClasses, horFlexClasses, patternUrlFromState, clone } from '@freesewing/utils'
|
||||
import { exportTypes, handleExport } from '../../lib/export/index.mjs'
|
||||
import yaml from 'yaml'
|
||||
// Hooks
|
||||
import React, { useState } from 'react'
|
||||
import { useStateObject } from '@freesewing/react/hooks/useStateObject'
|
||||
// Components
|
||||
import { H1, H2, H3, H5 } from '@freesewing/react/components/Heading'
|
||||
import { H1, H2, H3, H4, H5 } from '@freesewing/react/components/Heading'
|
||||
import { Popout } from '@freesewing/react/components/Popout'
|
||||
import { DiffViewer, diffCheck } from '@freesewing/react/components/DiffViewer'
|
||||
import { HeaderMenu } from '../HeaderMenu.mjs'
|
||||
import { EditIcon, CodeIcon, TipIcon, PrintIcon } from '@freesewing/react/components/Icon'
|
||||
import {
|
||||
ResetIcon,
|
||||
OkIcon,
|
||||
EditIcon,
|
||||
ExpandIcon,
|
||||
CodeIcon,
|
||||
TipIcon,
|
||||
PrintIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
import CodeMirror from '@uiw/react-codemirror'
|
||||
import { yaml as yamlLang } from '@codemirror/lang-yaml'
|
||||
|
||||
/**
|
||||
* This is the editSettings view
|
||||
|
@ -20,13 +32,20 @@ import CodeMirror from '@uiw/react-codemirror'
|
|||
*/
|
||||
export const EditSettingsView = (props) => {
|
||||
const [settings, setSettings] = useState(props.state.settings)
|
||||
const { state, config, update } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeaderMenu state={state} {...{ config, update }} />
|
||||
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
|
||||
<H1>Documenation</H1>
|
||||
<PrimedSettingsEditor {...props} {...{ runningSettings, dconf }} />
|
||||
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
|
||||
<H1>Edit settings by hand</H1>
|
||||
<p className="tw-mb-4">
|
||||
You can hand-edit your pattern settings below.
|
||||
<br />
|
||||
The changes will not take effect until you click the <b>Apply changes</b> button at the
|
||||
bottom.
|
||||
</p>
|
||||
<PrimedSettingsEditor {...props} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
@ -39,70 +58,38 @@ export const PrimedSettingsEditor = (props) => {
|
|||
/*
|
||||
* Destructure props
|
||||
*/
|
||||
const { runningSettings } = props
|
||||
const { state } = props
|
||||
|
||||
/*
|
||||
* React state
|
||||
*/
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const [mSettings, update, setMSettings] = useStateObject(runningSettings) // Holds the settings
|
||||
const [validationReport, setValidationReport] = useState(false) // Holds the validatino report
|
||||
const [settings, update, setSettings] = useStateObject(state.settings) // Holds the settings
|
||||
const [showDelta, setShowDelta] = useState(false)
|
||||
const [deployOngoing, setDeployOngoing] = useState(false)
|
||||
const [doValidate, setDoValidate] = useState(false)
|
||||
const [kiosk, setKiosk] = useState(false)
|
||||
const [localJson, setLocalJson] = useState(JSON.stringify(runningSettings, null, 2)) // Holds the settings as JSON
|
||||
const [localYaml, setLocalYaml] = useState(yaml.stringify(runningSettings)) // Holds the settings as YAML
|
||||
const [localYaml, setLocalYaml] = useState(yaml.stringify(state.settings)) // Holds the settings as YAML
|
||||
|
||||
/*
|
||||
* Method to revert to running settings
|
||||
* Method to revert to the settings in the editor state
|
||||
*/
|
||||
const revert = () => setMSettings(cloneAsPojo(runningSettings))
|
||||
|
||||
/*
|
||||
* API client
|
||||
*/
|
||||
const { api } = useApi()
|
||||
|
||||
/*
|
||||
* Loading context
|
||||
*/
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
/*
|
||||
* Helper method to deploy the settings
|
||||
*/
|
||||
const deploy = async () => {
|
||||
setLoadingStatus([true, 'Uploading settings'])
|
||||
setDeployOngoing(true)
|
||||
const result = await api.deploy(mSettings)
|
||||
return result[1] === 204
|
||||
? setLoadingStatus([true, 'Settings updated', true, true])
|
||||
: setLoadingStatus([true, `Unable to deploy the settings`, true, false])
|
||||
const revert = () => {
|
||||
setSettings(clone(state.settings))
|
||||
setLocalYaml(yaml.stringify(state.settings))
|
||||
}
|
||||
|
||||
if (!mSettings.cluster) return null
|
||||
/*
|
||||
* Method to save to the settings into the editor state
|
||||
*/
|
||||
const save = () => {
|
||||
props.update.state('settings', yaml.parse(localYaml))
|
||||
}
|
||||
|
||||
if (!settings) return null
|
||||
|
||||
/*
|
||||
* Handle settings delta
|
||||
*/
|
||||
const delta =
|
||||
diffCheck(yaml.stringify(runningSettings), yaml.stringify(mSettings)).length > 1 ? true : false
|
||||
|
||||
if (deployOngoing)
|
||||
return (
|
||||
<>
|
||||
<Box color="success">
|
||||
<div className="flex flex-row items-center gap-2 text-success-content">
|
||||
<div className="w-6 h-6">
|
||||
<OkIcon className="w-6 h-6 text-success-content" stroke={4} />
|
||||
</div>
|
||||
Settings are being deployed
|
||||
</div>
|
||||
</Box>
|
||||
<p>Please wait as Morio applies the new settings.</p>
|
||||
</>
|
||||
)
|
||||
diffCheck(yaml.stringify(state.settings), yaml.stringify(settings)).length > 1 ? true : false
|
||||
|
||||
const onChangeYaml = (input) => {
|
||||
let newSettings
|
||||
|
@ -110,122 +97,59 @@ export const PrimedSettingsEditor = (props) => {
|
|||
newSettings = yaml.parse(input)
|
||||
if (newSettings) {
|
||||
setLocalYaml(input)
|
||||
setMSettings(newSettings)
|
||||
setSettings(newSettings)
|
||||
}
|
||||
} catch (err) {
|
||||
// This is fine
|
||||
}
|
||||
}
|
||||
const onChangeJson = (input) => {
|
||||
let newSettings
|
||||
try {
|
||||
newSettings = JSON.parse(input)
|
||||
if (newSettings) {
|
||||
setLocalJson(input)
|
||||
setMSettings(newSettings)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
// This is fine
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{mSettings.preseed?.base ? (
|
||||
<Popout warning>
|
||||
<h5>These settings are preseeded</h5>
|
||||
<p>
|
||||
This Morio deployment uses preseeded settings. This means the settings are loaded from a
|
||||
remote system, typically a version control system like GitLab or GitHub.
|
||||
</p>
|
||||
<p>
|
||||
While you <b>can</b> update the settings here, those settings will be lost next time
|
||||
Morio is reseeded.
|
||||
<br />
|
||||
You probably should <b>update the preseeded setting instead</b>.
|
||||
</p>
|
||||
</Popout>
|
||||
) : null}
|
||||
{doValidate ? (
|
||||
<CodeMirror
|
||||
value={localYaml}
|
||||
height="50vh"
|
||||
onChange={onChangeYaml}
|
||||
extensions={[yamlLang()]}
|
||||
/>
|
||||
{delta ? (
|
||||
<>
|
||||
<ShowSettingsValidation
|
||||
{...{
|
||||
api,
|
||||
deploy,
|
||||
mSettings,
|
||||
setLoadingStatus,
|
||||
setValidationReport,
|
||||
validationReport,
|
||||
}}
|
||||
/>
|
||||
<p className="text-right w-full">
|
||||
<H4>You have made changes</H4>
|
||||
<p>Your settings have been edited, and are now different from the editor settings.</p>
|
||||
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-3 tw-gap-2 tw-w-full">
|
||||
<button
|
||||
className="btn btn-primary btn-outline btn-s btn-sm"
|
||||
onClick={() => setDoValidate(false)}
|
||||
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
|
||||
onClick={() => setShowDelta(!showDelta)}
|
||||
>
|
||||
<NoteIcon /> Back to editor
|
||||
{showDelta ? 'Hide' : 'Show'} Changes
|
||||
</button>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<div className={kiosk ? 'absolute top-12 left-0 w-screen h-screen z-50 bg-base-100' : ''}>
|
||||
<Tabs tabs="YAML, JSON">
|
||||
<Tab id="json" name="test" label="As YAML">
|
||||
<CodeMirror
|
||||
value={localYaml}
|
||||
height={kiosk ? '90vh' : '70vh'}
|
||||
onChange={onChangeYaml}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab id="yaml" label="As JSON">
|
||||
<CodeMirror
|
||||
value={localJson}
|
||||
height={kiosk ? '90vh' : '70vh'}
|
||||
extensions={[jsonLang()]}
|
||||
onChange={onChangeJson}
|
||||
/>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
<div className="my-2 w-full flex flex-row flex-wrap items-center gap-2 justify-center">
|
||||
<button
|
||||
className="btn btn-primary btn-outline flex flex-row items-center gap-2"
|
||||
onClick={() => setKiosk(!kiosk)}
|
||||
className="tw-daisy-btn tw-daisy-btn-primary tw-flex tw-flex-row tw-items-center tw-justify-between"
|
||||
onClick={save}
|
||||
>
|
||||
<ExpandIcon /> {kiosk ? 'Collapse' : 'Expand'}
|
||||
<OkIcon stroke={3} />
|
||||
Save Settings
|
||||
</button>
|
||||
<button className="btn btn-primary" onClick={() => setDoValidate(true)}>
|
||||
Validate Settings
|
||||
<button
|
||||
className="tw-daisy-btn tw-daisy-btn-error tw-daisy-btn-outline tw-flex tw-flex-row tw-items-center tw-justify-between"
|
||||
onClick={revert}
|
||||
>
|
||||
<ResetIcon />
|
||||
Revert Settings
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!doValidate && delta ? (
|
||||
<Popout note>
|
||||
<h4>You have made changes that are yet to be deployed</h4>
|
||||
<p>The settings have been edited, and are now different from the deployed settings.</p>
|
||||
{showDelta ? (
|
||||
<div className="my-4 w-full overflow-scroll">
|
||||
<div className="tw-my-4 tw-w-full tw-overflow-scroll">
|
||||
<DiffViewer
|
||||
from={yaml.stringify(runningSettings)}
|
||||
to={yaml.stringify(mSettings)}
|
||||
oldValue={yaml.stringify(state.settings)}
|
||||
newValue={yaml.stringify(settings)}
|
||||
extraLinesSurroundingDiff="1"
|
||||
fromTitle="Currently deployed settings"
|
||||
toTitle="Your edits"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex flex-row flex-wrap gap-2 justify-end w-full">
|
||||
<button className="btn btn-warning btn-ghost" onClick={revert}>
|
||||
Revert to Running Settings
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary btn-outline"
|
||||
onClick={() => setShowDelta(!showDelta)}
|
||||
>
|
||||
{showDelta ? 'Hide' : 'Show'} Settings Delta
|
||||
</button>
|
||||
</div>
|
||||
</Popout>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -105,7 +105,7 @@ export const viewLabels = {
|
|||
t: 'Export Pattern',
|
||||
d: 'Export this pattern into a variety of formats',
|
||||
},
|
||||
edit: {
|
||||
editSettings: {
|
||||
t: 'Edit settings by hand',
|
||||
d: "Throw caution to the wind, and hand-edit the pattern's settings",
|
||||
},
|
||||
|
|
48
packages/react/hooks/useStateObject/index.mjs
Normal file
48
packages/react/hooks/useStateObject/index.mjs
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React, { useState } from 'react'
|
||||
import set from 'lodash/set.js'
|
||||
import unset from 'lodash/unset.js'
|
||||
|
||||
/*
|
||||
* Helper method to handle object updates
|
||||
*
|
||||
* This is a wrapper around lodash.set() with extra support for unsetting data.
|
||||
*
|
||||
* @param {object} obj - The object to update
|
||||
* @param {array|string} path - The path to the property to update either as an array or string in dot notation
|
||||
* @param {mixed} val - The value to set. If the value holds the string 'unset' the property will be removed
|
||||
*
|
||||
* @return {object} obj - The mutated object
|
||||
*/
|
||||
export const objUpdate = (obj = {}, path, val = undefined) => {
|
||||
if (val === undefined) {
|
||||
if (Array.isArray(path) && Array.isArray(path[0])) {
|
||||
for (const [ipath, ival = undefined] of path) {
|
||||
if (ival === undefined) unset(obj, ipath)
|
||||
else set(obj, ipath, ival)
|
||||
}
|
||||
} else unset(obj, path)
|
||||
} else set(obj, path, val)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
/*
|
||||
* This hooks provides an React state update with an
|
||||
* update method that allows us to set deeply nested
|
||||
* properties.
|
||||
*/
|
||||
export const useStateObject = (dflt = {}) => {
|
||||
const [obj, setObj] = useState(dflt)
|
||||
|
||||
const replace = (val) => setObj(val)
|
||||
|
||||
const update = (path, val, altObj = false) => {
|
||||
const newObj = altObj ? { ...altObj } : { ...obj }
|
||||
objUpdate(newObj, path, val)
|
||||
setObj(newObj)
|
||||
|
||||
return newObj
|
||||
}
|
||||
|
||||
return [obj, update, replace]
|
||||
}
|
|
@ -34,6 +34,7 @@
|
|||
"./components/Control": "./components/Control/index.mjs",
|
||||
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs",
|
||||
"./components/Design": "./components/Design/index.mjs",
|
||||
"./components/DiffViewer": "./components/DiffViewer/index.mjs",
|
||||
"./components/Docusaurus": "./components/Docusaurus/index.mjs",
|
||||
"./components/Editor": "./components/Editor/index.mjs",
|
||||
"./components/Heading": "./components/Heading/index.mjs",
|
||||
|
@ -71,6 +72,7 @@
|
|||
"./hooks/useDesign": "./hooks/useDesign/index.mjs",
|
||||
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs",
|
||||
"./hooks/useSelection": "./hooks/useSelection/index.mjs",
|
||||
"./hooks/useStateObject": "./hooks/useStateObject/index.mjs",
|
||||
"./lib/RestClient": "./lib/RestClient/index.mjs",
|
||||
"./lib/logoPath": "./components/Logo/path.mjs"
|
||||
},
|
||||
|
@ -82,9 +84,11 @@
|
|||
"react": "^19.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-yaml": "^6.1.2",
|
||||
"@uiw/react-codemirror": "^4.23.8",
|
||||
"d3-drag": "3.0.0",
|
||||
"d3-selection": "3.0.0",
|
||||
"diff": "^7.0.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"highlight.js": "^11.11.1",
|
||||
"html-react-parser": "^5.2.2",
|
||||
|
@ -92,11 +96,13 @@
|
|||
"jotai-location": "^0.5.5",
|
||||
"luxon": "^3.5.0",
|
||||
"pdfkit": "^0.16.0",
|
||||
"react-diff-viewer-continued": "^4.0.5",
|
||||
"react-dropzone": "^14.3.5",
|
||||
"react-zoom-pan-pinch": "^3.7.0",
|
||||
"svg-to-pdfkit": "^0.1.8",
|
||||
"use-local-storage-state": "^19.5.0",
|
||||
"web-worker": "^1.5.0"
|
||||
"web-worker": "^1.5.0",
|
||||
"yaml": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"files": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue