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
|
'@freesewing/snapseries': *freesewing
|
||||||
react:
|
react:
|
||||||
_:
|
_:
|
||||||
|
"@codemirror/lang-yaml": "^6.1.2"
|
||||||
"@uiw/react-codemirror": "^4.23.8"
|
"@uiw/react-codemirror": "^4.23.8"
|
||||||
d3-drag: "3.0.0"
|
d3-drag: "3.0.0"
|
||||||
d3-selection: "3.0.0"
|
d3-selection: "3.0.0"
|
||||||
|
diff: "^7.0.0"
|
||||||
file-saver: "^2.0.5"
|
file-saver: "^2.0.5"
|
||||||
"highlight.js": "^11.11.1"
|
"highlight.js": "^11.11.1"
|
||||||
html-react-parser: "^5.2.2"
|
html-react-parser: "^5.2.2"
|
||||||
|
@ -248,11 +250,13 @@ react:
|
||||||
jotai-location: "^0.5.5"
|
jotai-location: "^0.5.5"
|
||||||
luxon: "^3.5.0"
|
luxon: "^3.5.0"
|
||||||
pdfkit: "^0.16.0"
|
pdfkit: "^0.16.0"
|
||||||
|
react-diff-viewer-continued: "^4.0.5"
|
||||||
react-dropzone: "^14.3.5"
|
react-dropzone: "^14.3.5"
|
||||||
react-zoom-pan-pinch: "^3.7.0"
|
react-zoom-pan-pinch: "^3.7.0"
|
||||||
svg-to-pdfkit: "^0.1.8"
|
svg-to-pdfkit: "^0.1.8"
|
||||||
use-local-storage-state: "^19.5.0"
|
use-local-storage-state: "^19.5.0"
|
||||||
web-worker: "^1.5.0"
|
web-worker: "^1.5.0"
|
||||||
|
yaml: "^2.7.0"
|
||||||
peer:
|
peer:
|
||||||
react: &react "^19.0.0"
|
react: &react "^19.0.0"
|
||||||
utils:
|
utils:
|
||||||
|
|
|
@ -81,6 +81,7 @@ packageJson:
|
||||||
"./components/Control": "./components/Control/index.mjs"
|
"./components/Control": "./components/Control/index.mjs"
|
||||||
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs"
|
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs"
|
||||||
"./components/Design": "./components/Design/index.mjs"
|
"./components/Design": "./components/Design/index.mjs"
|
||||||
|
"./components/DiffViewer": "./components/DiffViewer/index.mjs"
|
||||||
"./components/Docusaurus": "./components/Docusaurus/index.mjs"
|
"./components/Docusaurus": "./components/Docusaurus/index.mjs"
|
||||||
"./components/Editor": "./components/Editor/index.mjs"
|
"./components/Editor": "./components/Editor/index.mjs"
|
||||||
"./components/Heading": "./components/Heading/index.mjs"
|
"./components/Heading": "./components/Heading/index.mjs"
|
||||||
|
@ -120,6 +121,7 @@ packageJson:
|
||||||
"./hooks/useDesign": "./hooks/useDesign/index.mjs"
|
"./hooks/useDesign": "./hooks/useDesign/index.mjs"
|
||||||
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs"
|
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs"
|
||||||
"./hooks/useSelection": "./hooks/useSelection/index.mjs"
|
"./hooks/useSelection": "./hooks/useSelection/index.mjs"
|
||||||
|
"./hooks/useStateObject": "./hooks/useStateObject/index.mjs"
|
||||||
# Lib
|
# Lib
|
||||||
"./lib/RestClient": "./lib/RestClient/index.mjs"
|
"./lib/RestClient": "./lib/RestClient/index.mjs"
|
||||||
"./lib/logoPath": "./components/Logo/path.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"
|
"@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": {
|
"node_modules/@codemirror/language": {
|
||||||
"version": "6.10.8",
|
"version": "6.10.8",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.8.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.8.tgz",
|
||||||
|
@ -26309,6 +26324,188 @@
|
||||||
"tslib": "^2.4.0"
|
"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": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
|
||||||
|
@ -27721,6 +27918,17 @@
|
||||||
"@lezer/common": "^1.0.0"
|
"@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": {
|
"node_modules/@marijn/find-cluster-break": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||||
|
@ -34097,6 +34305,12 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/clean-css": {
|
||||||
"version": "5.3.3",
|
"version": "5.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
||||||
|
@ -37368,7 +37582,6 @@
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
|
||||||
"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
|
"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
|
@ -39868,6 +40081,12 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/find-up": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
|
||||||
|
@ -48070,6 +48289,12 @@
|
||||||
"node": ">= 4.0.0"
|
"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": {
|
"node_modules/meow": {
|
||||||
"version": "12.1.1",
|
"version": "12.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
|
||||||
|
@ -54643,6 +54868,26 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/react-dom": {
|
||||||
"version": "19.0.0",
|
"version": "19.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
||||||
|
@ -57881,6 +58126,12 @@
|
||||||
"postcss": "^8.4.31"
|
"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": {
|
"node_modules/sucrase": {
|
||||||
"version": "3.35.0",
|
"version": "3.35.0",
|
||||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
|
||||||
|
@ -61968,9 +62219,11 @@
|
||||||
"version": "3.3.0-rc.1",
|
"version": "3.3.0-rc.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@codemirror/lang-yaml": "^6.1.2",
|
||||||
"@uiw/react-codemirror": "^4.23.8",
|
"@uiw/react-codemirror": "^4.23.8",
|
||||||
"d3-drag": "3.0.0",
|
"d3-drag": "3.0.0",
|
||||||
"d3-selection": "3.0.0",
|
"d3-selection": "3.0.0",
|
||||||
|
"diff": "^7.0.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"html-react-parser": "^5.2.2",
|
"html-react-parser": "^5.2.2",
|
||||||
|
@ -61978,11 +62231,13 @@
|
||||||
"jotai-location": "^0.5.5",
|
"jotai-location": "^0.5.5",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"pdfkit": "^0.16.0",
|
"pdfkit": "^0.16.0",
|
||||||
|
"react-diff-viewer-continued": "^4.0.5",
|
||||||
"react-dropzone": "^14.3.5",
|
"react-dropzone": "^14.3.5",
|
||||||
"react-zoom-pan-pinch": "^3.7.0",
|
"react-zoom-pan-pinch": "^3.7.0",
|
||||||
"svg-to-pdfkit": "^0.1.8",
|
"svg-to-pdfkit": "^0.1.8",
|
||||||
"use-local-storage-state": "^19.5.0",
|
"use-local-storage-state": "^19.5.0",
|
||||||
"web-worker": "^1.5.0"
|
"web-worker": "^1.5.0",
|
||||||
|
"yaml": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -61996,6 +62251,15 @@
|
||||||
"react": "^19.0.0"
|
"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": {
|
"packages/rehype-highlight-lines": {
|
||||||
"version": "3.3.0-rc.1",
|
"version": "3.3.0-rc.1",
|
||||||
"extraneous": true,
|
"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
|
// 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 { exportTypes, handleExport } from '../../lib/export/index.mjs'
|
||||||
|
import yaml from 'yaml'
|
||||||
// Hooks
|
// Hooks
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import { useStateObject } from '@freesewing/react/hooks/useStateObject'
|
||||||
// Components
|
// 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 { Popout } from '@freesewing/react/components/Popout'
|
||||||
|
import { DiffViewer, diffCheck } from '@freesewing/react/components/DiffViewer'
|
||||||
import { HeaderMenu } from '../HeaderMenu.mjs'
|
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 CodeMirror from '@uiw/react-codemirror'
|
||||||
|
import { yaml as yamlLang } from '@codemirror/lang-yaml'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the editSettings view
|
* This is the editSettings view
|
||||||
|
@ -20,13 +32,20 @@ import CodeMirror from '@uiw/react-codemirror'
|
||||||
*/
|
*/
|
||||||
export const EditSettingsView = (props) => {
|
export const EditSettingsView = (props) => {
|
||||||
const [settings, setSettings] = useState(props.state.settings)
|
const [settings, setSettings] = useState(props.state.settings)
|
||||||
|
const { state, config, update } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeaderMenu state={state} {...{ config, update }} />
|
<HeaderMenu state={state} {...{ config, update }} />
|
||||||
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
|
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
|
||||||
<H1>Documenation</H1>
|
<H1>Edit settings by hand</H1>
|
||||||
<PrimedSettingsEditor {...props} {...{ runningSettings, dconf }} />
|
<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>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -39,70 +58,38 @@ export const PrimedSettingsEditor = (props) => {
|
||||||
/*
|
/*
|
||||||
* Destructure props
|
* Destructure props
|
||||||
*/
|
*/
|
||||||
const { runningSettings } = props
|
const { state } = props
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* React state
|
* React state
|
||||||
*/
|
*/
|
||||||
/* eslint-disable-next-line no-unused-vars */
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
const [mSettings, update, setMSettings] = useStateObject(runningSettings) // Holds the settings
|
const [settings, update, setSettings] = useStateObject(state.settings) // Holds the settings
|
||||||
const [validationReport, setValidationReport] = useState(false) // Holds the validatino report
|
|
||||||
const [showDelta, setShowDelta] = useState(false)
|
const [showDelta, setShowDelta] = useState(false)
|
||||||
const [deployOngoing, setDeployOngoing] = useState(false)
|
const [localYaml, setLocalYaml] = useState(yaml.stringify(state.settings)) // Holds the settings as YAML
|
||||||
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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Method to revert to running settings
|
* Method to revert to the settings in the editor state
|
||||||
*/
|
*/
|
||||||
const revert = () => setMSettings(cloneAsPojo(runningSettings))
|
const revert = () => {
|
||||||
|
setSettings(clone(state.settings))
|
||||||
/*
|
setLocalYaml(yaml.stringify(state.settings))
|
||||||
* 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])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* Handle settings delta
|
||||||
*/
|
*/
|
||||||
const delta =
|
const delta =
|
||||||
diffCheck(yaml.stringify(runningSettings), yaml.stringify(mSettings)).length > 1 ? true : false
|
diffCheck(yaml.stringify(state.settings), yaml.stringify(settings)).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>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
|
|
||||||
const onChangeYaml = (input) => {
|
const onChangeYaml = (input) => {
|
||||||
let newSettings
|
let newSettings
|
||||||
|
@ -110,122 +97,59 @@ export const PrimedSettingsEditor = (props) => {
|
||||||
newSettings = yaml.parse(input)
|
newSettings = yaml.parse(input)
|
||||||
if (newSettings) {
|
if (newSettings) {
|
||||||
setLocalYaml(input)
|
setLocalYaml(input)
|
||||||
setMSettings(newSettings)
|
setSettings(newSettings)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// This is fine
|
// 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 (
|
return (
|
||||||
<>
|
<>
|
||||||
{mSettings.preseed?.base ? (
|
<CodeMirror
|
||||||
<Popout warning>
|
value={localYaml}
|
||||||
<h5>These settings are preseeded</h5>
|
height="50vh"
|
||||||
<p>
|
onChange={onChangeYaml}
|
||||||
This Morio deployment uses preseeded settings. This means the settings are loaded from a
|
extensions={[yamlLang()]}
|
||||||
remote system, typically a version control system like GitLab or GitHub.
|
/>
|
||||||
</p>
|
{delta ? (
|
||||||
<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 ? (
|
|
||||||
<>
|
<>
|
||||||
<ShowSettingsValidation
|
<H4>You have made changes</H4>
|
||||||
{...{
|
<p>Your settings have been edited, and are now different from the editor settings.</p>
|
||||||
api,
|
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-3 tw-gap-2 tw-w-full">
|
||||||
deploy,
|
|
||||||
mSettings,
|
|
||||||
setLoadingStatus,
|
|
||||||
setValidationReport,
|
|
||||||
validationReport,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p className="text-right w-full">
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary btn-outline btn-s btn-sm"
|
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
|
||||||
onClick={() => setDoValidate(false)}
|
onClick={() => setShowDelta(!showDelta)}
|
||||||
>
|
>
|
||||||
<NoteIcon /> Back to editor
|
{showDelta ? 'Hide' : 'Show'} Changes
|
||||||
</button>
|
</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
|
<button
|
||||||
className="btn btn-primary btn-outline flex flex-row items-center gap-2"
|
className="tw-daisy-btn tw-daisy-btn-primary tw-flex tw-flex-row tw-items-center tw-justify-between"
|
||||||
onClick={() => setKiosk(!kiosk)}
|
onClick={save}
|
||||||
>
|
>
|
||||||
<ExpandIcon /> {kiosk ? 'Collapse' : 'Expand'}
|
<OkIcon stroke={3} />
|
||||||
|
Save Settings
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-primary" onClick={() => setDoValidate(true)}>
|
<button
|
||||||
Validate Settings
|
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>
|
</button>
|
||||||
</div>
|
</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 ? (
|
{showDelta ? (
|
||||||
<div className="my-4 w-full overflow-scroll">
|
<div className="tw-my-4 tw-w-full tw-overflow-scroll">
|
||||||
<DiffViewer
|
<DiffViewer
|
||||||
from={yaml.stringify(runningSettings)}
|
oldValue={yaml.stringify(state.settings)}
|
||||||
to={yaml.stringify(mSettings)}
|
newValue={yaml.stringify(settings)}
|
||||||
|
extraLinesSurroundingDiff="1"
|
||||||
fromTitle="Currently deployed settings"
|
fromTitle="Currently deployed settings"
|
||||||
toTitle="Your edits"
|
toTitle="Your edits"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : 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}
|
) : null}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -105,7 +105,7 @@ export const viewLabels = {
|
||||||
t: 'Export Pattern',
|
t: 'Export Pattern',
|
||||||
d: 'Export this pattern into a variety of formats',
|
d: 'Export this pattern into a variety of formats',
|
||||||
},
|
},
|
||||||
edit: {
|
editSettings: {
|
||||||
t: 'Edit settings by hand',
|
t: 'Edit settings by hand',
|
||||||
d: "Throw caution to the wind, and hand-edit the pattern's settings",
|
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/Control": "./components/Control/index.mjs",
|
||||||
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs",
|
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs",
|
||||||
"./components/Design": "./components/Design/index.mjs",
|
"./components/Design": "./components/Design/index.mjs",
|
||||||
|
"./components/DiffViewer": "./components/DiffViewer/index.mjs",
|
||||||
"./components/Docusaurus": "./components/Docusaurus/index.mjs",
|
"./components/Docusaurus": "./components/Docusaurus/index.mjs",
|
||||||
"./components/Editor": "./components/Editor/index.mjs",
|
"./components/Editor": "./components/Editor/index.mjs",
|
||||||
"./components/Heading": "./components/Heading/index.mjs",
|
"./components/Heading": "./components/Heading/index.mjs",
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
"./hooks/useDesign": "./hooks/useDesign/index.mjs",
|
"./hooks/useDesign": "./hooks/useDesign/index.mjs",
|
||||||
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs",
|
"./hooks/useDesignTranslation": "./hooks/useDesignTranslation/index.mjs",
|
||||||
"./hooks/useSelection": "./hooks/useSelection/index.mjs",
|
"./hooks/useSelection": "./hooks/useSelection/index.mjs",
|
||||||
|
"./hooks/useStateObject": "./hooks/useStateObject/index.mjs",
|
||||||
"./lib/RestClient": "./lib/RestClient/index.mjs",
|
"./lib/RestClient": "./lib/RestClient/index.mjs",
|
||||||
"./lib/logoPath": "./components/Logo/path.mjs"
|
"./lib/logoPath": "./components/Logo/path.mjs"
|
||||||
},
|
},
|
||||||
|
@ -82,9 +84,11 @@
|
||||||
"react": "^19.0.0"
|
"react": "^19.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@codemirror/lang-yaml": "^6.1.2",
|
||||||
"@uiw/react-codemirror": "^4.23.8",
|
"@uiw/react-codemirror": "^4.23.8",
|
||||||
"d3-drag": "3.0.0",
|
"d3-drag": "3.0.0",
|
||||||
"d3-selection": "3.0.0",
|
"d3-selection": "3.0.0",
|
||||||
|
"diff": "^7.0.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"html-react-parser": "^5.2.2",
|
"html-react-parser": "^5.2.2",
|
||||||
|
@ -92,11 +96,13 @@
|
||||||
"jotai-location": "^0.5.5",
|
"jotai-location": "^0.5.5",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"pdfkit": "^0.16.0",
|
"pdfkit": "^0.16.0",
|
||||||
|
"react-diff-viewer-continued": "^4.0.5",
|
||||||
"react-dropzone": "^14.3.5",
|
"react-dropzone": "^14.3.5",
|
||||||
"react-zoom-pan-pinch": "^3.7.0",
|
"react-zoom-pan-pinch": "^3.7.0",
|
||||||
"svg-to-pdfkit": "^0.1.8",
|
"svg-to-pdfkit": "^0.1.8",
|
||||||
"use-local-storage-state": "^19.5.0",
|
"use-local-storage-state": "^19.5.0",
|
||||||
"web-worker": "^1.5.0"
|
"web-worker": "^1.5.0",
|
||||||
|
"yaml": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"files": [
|
"files": [
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue