Merge branch '20260828_1350_settings_page' into 20260721_0845_Venessa_addingWidgets
This commit is contained in:
Generated
+390
@@ -11,6 +11,7 @@
|
|||||||
"@chakra-ui/react": "^3.22.0",
|
"@chakra-ui/react": "^3.22.0",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.1",
|
"@emotion/styled": "^11.14.1",
|
||||||
|
"@svar-ui/react-gantt": "^2.7.3",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"framer-motion": "^12.23.0",
|
"framer-motion": "^12.23.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
@@ -3106,6 +3107,385 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@svar-ui/comments-locales": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/comments-locales/-/comments-locales-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-jouLSwt0rPp2818bHftsb37aU8ERsyBney8XVUHhnWrsIaGJy/0TSOCw6YqN3cae6SQBd6KBO+P1+hBcDEsmUg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/core-locales": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/core-locales/-/core-locales-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-18xu7qn8Bxwi2EHguVV3Xya5kS+A+6Gnuo2wl55dofp9y948iZ5z7HIRh1+Mj1BgzbdVt6+B04JOCDMLJXyjtg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/editor-locales": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/editor-locales/-/editor-locales-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-HFEB43W+AEUjoBh3ZsrlLFFTVh8WYPVpZeOiCfptS5hS0qC8pEnqaXtreM6TM1g3W5VHHOR+sXsWkIxAoeKVvg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/filter-locales": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/filter-locales/-/filter-locales-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-m963r4TnZxiZ6XzfJYvSmiYcmgSgKhkzpOVcUP25AviWle1oPulyv4Qe28Rak3JaAOFAHQAf0EucoaSMJzvK6A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/filter-store": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/filter-store/-/filter-store-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-2UHeXuNYN56MokBhB48EJ7KvKDVAJbRP2nIbE6t7lbsnWhRsBGxPc4jjUQn/9K+MTGkxrzPrOfeoH8L4p3Hy5g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/filter-store/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/gantt-data-provider": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/gantt-data-provider/-/gantt-data-provider-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-4j+fWq0y7+qfBcu0R5YS13M1u9fKJiH9YQt/81fRRFcRu12Rvpi/HDXeOVpE/APvsM8NoHJdd5kKK6f59qmE+w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-data-provider": "1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/gantt-locales": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/gantt-locales/-/gantt-locales-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-yEihUiPx9dgr0FLfAoNpgS6QcVjYLqdW2TbyilZ0UaA3YLORly9lbmCI0PPnAALa73ws0qUy2AYaL1nTq0T4/w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/gantt-store": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/gantt-store/-/gantt-store-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-krax1GzUWBOTcMVTaaqYlMuJ5lNBkzA6VIhNCnHq+0kFnHg52Hx+D0MQnMkSOUyFA2w0SoiYvUYuAGiQx4eA9A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"date-fns": "3.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-data-provider": {
|
||||||
|
"version": "2.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/grid-data-provider/-/grid-data-provider-2.7.3.tgz",
|
||||||
|
"integrity": "sha512-MFobgoczW6wBPjKq8fTORlJEEn2f6jHKWH1h3pC6qmcKr8GRA+TaRaFPVcI2iD5pOc+h/JZxuKE6L+x99S2Uwg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-data-provider": "1.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-data-provider/node_modules/@svar-ui/lib-data-provider": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-data-provider/-/lib-data-provider-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-Od93Iiy0vBwVzgJm25WdizH3d4Xlli/HAA2kqoUj1pzeZ2SWBeFzvE59iihQz8NuIlfAtQJ6MMe168458T+2lQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-data-provider/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-locales": {
|
||||||
|
"version": "2.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/grid-locales/-/grid-locales-2.7.3.tgz",
|
||||||
|
"integrity": "sha512-bgB2TfSKjY7mYeTzJjCyOoPco7boz+SQ0xFFsnRp849QN5sJoJEtOl/xnzbR58bLdxq57ne5Z708ozxXDT36lQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-store": {
|
||||||
|
"version": "2.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/grid-store/-/grid-store-2.7.3.tgz",
|
||||||
|
"integrity": "sha512-YVmLnFLq7P3ACAos0EiMYHLQbnmjaukmUaMoraTG8vhFsI5BwVaeSFdeC9MQIjbIMlxn/uMA0eEXmZuSxHk2hA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-dom": "0.12.1",
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-store/node_modules/@svar-ui/lib-dom": {
|
||||||
|
"version": "0.12.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-dom/-/lib-dom-0.12.1.tgz",
|
||||||
|
"integrity": "sha512-srvDleQqR6stBBDijCgzDHMFTTffI6sv3XCpNPKmurrnE83L1MDNqezqg6j3+0dUVPd4AAEGOez2DvK6byblTQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/grid-store/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-data-provider": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-data-provider/-/lib-data-provider-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-5Bi9ywngcMTKpGtan0s7q8ivd84Bp0ZnRP+5bLZg6oiRB7YMyN5D5X+apc3CWDAnG4zZn3en4YwS2qc/aHIIuQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-data-provider/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-dom": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-dom/-/lib-dom-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-9uao5ebcQmuW0RoMu1LCesPsZ7i6G3xIvYAQzX/aeg662Yy/ETsNVy1pXoSa2q5v6ccAMjVxFrFCYReK7fzaJQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-react": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-react/-/lib-react-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-jVcREYAMAXOhZB/lbMmLteGKIZoUW3rzmoXCMcFLGcHIGUH7AjFrKOAG/SJvgV0grcG9XyuRTG3jp++6NIGtuw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-dom": "^0.12.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-react/node_modules/@svar-ui/lib-dom": {
|
||||||
|
"version": "0.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-dom/-/lib-dom-0.12.2.tgz",
|
||||||
|
"integrity": "sha512-tV9sJ7Xpedxf1dttTc8I190eqlP0UsassUw48uW3JuEQR0G3IRfmH53/X+mYEooc7bcpZDkzYukWEqJeEq9UlQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.7.tgz",
|
||||||
|
"integrity": "sha512-nxRdk+54m1RJjGT2yDH7NjxAM5KECxA39kdTZezEIj1ixykyefssB9BrgxKy2jIseYxJMtd6lPZvQ3SZXuvn2g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-comments": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-comments/-/react-comments-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-bdO8DHIZ/qpQNXeZzNuU2cbUsiyen+bc2/sS9h7PLzCSeeGmKwAyHeTyO06WvsVxUgQSBAfp2Eom+xFNDaQcXw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/comments-locales": "2.6.1",
|
||||||
|
"@svar-ui/core-locales": "2.6.1",
|
||||||
|
"@svar-ui/lib-data-provider": "1.7.3",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/react-menu": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-comments/node_modules/@svar-ui/lib-data-provider": {
|
||||||
|
"version": "1.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-data-provider/-/lib-data-provider-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-+UAM1VybQco5N52iv6rVcDwOJ5G1qE+V+nvaoBHx41H05w4TZTFJL+UnRy99NDLrVbLoCWhoH3L8vyNmZVjTvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-comments/node_modules/@svar-ui/lib-data-provider/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-core": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-core/-/react-core-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-1b0R+n4r/XLM2FC4mAxhyRYCI79HdrDbfe0nsOr/uJ0Ty+wxEfWglamCf6yJSM2tvmpGJQ388flDIXPbzep4Fg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/core-locales": "2.6.1",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-react": "1.2.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-core/node_modules/@svar-ui/lib-react": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-react/-/lib-react-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-bB+Vou2NM0JhMuFW03MsjjoV5Y3xcFfuuK48+7uzUC9Ui1oSWpCK+txOZ+dnUFJISSVjSsXuF34AzMw/2CA63w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-dom": "^0.11.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-core/node_modules/@svar-ui/lib-react/node_modules/@svar-ui/lib-dom": {
|
||||||
|
"version": "0.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-dom/-/lib-dom-0.11.1.tgz",
|
||||||
|
"integrity": "sha512-4wgerhDVttvrQ9t6OjHur34Of+VVr2VygA16HHGcWHytgdnOuGgfZb5PeBEhCJw/pO3RKfJvBHbaMIzL4IR//g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-editor": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-editor/-/react-editor-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-r/POft5rvYx43DGHHuC3yKJKani0i+jqKbWFH+j5IWUhWjnkEqdpcToehGzoXob7gyl7VuzGMQQFu8DzUcyNrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/editor-locales": "2.6.1",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-comments": "2.6.1",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/react-tasklist": "2.6.1",
|
||||||
|
"@svar-ui/react-toolbar": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-filter": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-filter/-/react-filter-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-GBwReaJUa7Qb7EZTJroxjzm7NIGsAEFuDoTrmJqwkcmwFB+WBukQa/2Z0mf5Ya4t4/ldt1sfOzNWlbFhMo8FTA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/filter-locales": "2.6.1",
|
||||||
|
"@svar-ui/filter-store": "2.6.1",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-react": "1.3.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/react-menu": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-gantt": {
|
||||||
|
"version": "2.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-gantt/-/react-gantt-2.7.3.tgz",
|
||||||
|
"integrity": "sha512-1kLEXrfJ3fkXp5NCvMHIpsjdEphy0EC5ce2nphs8GOFlsiSp6nRau+GY0Go6ivGDPdcchPkZ8a0Q1iKk3HtyRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/core-locales": "2.6.1",
|
||||||
|
"@svar-ui/gantt-data-provider": "2.7.2",
|
||||||
|
"@svar-ui/gantt-locales": "2.7.2",
|
||||||
|
"@svar-ui/gantt-store": "2.7.2",
|
||||||
|
"@svar-ui/grid-store": "2.7.3",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-react": "1.3.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-comments": "2.6.1",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/react-editor": "2.6.1",
|
||||||
|
"@svar-ui/react-filter": "2.6.1",
|
||||||
|
"@svar-ui/react-grid": "2.7.4",
|
||||||
|
"@svar-ui/react-menu": "2.6.1",
|
||||||
|
"@svar-ui/react-tasklist": "2.6.1",
|
||||||
|
"@svar-ui/react-toolbar": "2.6.1",
|
||||||
|
"date-fns": "3.6.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-grid": {
|
||||||
|
"version": "2.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-grid/-/react-grid-2.7.4.tgz",
|
||||||
|
"integrity": "sha512-m3AbGuQNeEnniDcyBesEOg+IirwW5NasJQCfJd7jIFhUyfQ79w+crSnLbinEVS59/OKGrqkmxnLDcDwEKbu4rg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/grid-data-provider": "2.7.3",
|
||||||
|
"@svar-ui/grid-locales": "2.7.3",
|
||||||
|
"@svar-ui/grid-store": "2.7.3",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-react": "1.3.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/react-editor": "2.6.1",
|
||||||
|
"@svar-ui/react-filter": "2.6.1",
|
||||||
|
"@svar-ui/react-menu": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-menu": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-menu/-/react-menu-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-/wu6vaLVPN2AJp8r+axIkjaSpoZOAgE46CRsdM2d0yc+hbJdeMo997LXZTGQzBziwLZttW1DDwOvL+uLIeTOug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/core-locales": "2.6.1",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/react-core": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-tasklist": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-tasklist/-/react-tasklist-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-U06UHYwL1J6XXMLsHrTvs/wWUXEm3ZC+Ca1hC5Ns0vvnscdE6cSRPqC1Xl2JGKu/cem0sHimEVi7SW4Q2NWczw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-data-provider": "1.7.3",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/lib-state": "1.9.7",
|
||||||
|
"@svar-ui/react-core": "2.6.1",
|
||||||
|
"@svar-ui/tasklist-locales": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-tasklist/node_modules/@svar-ui/lib-data-provider": {
|
||||||
|
"version": "1.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-data-provider/-/lib-data-provider-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-+UAM1VybQco5N52iv6rVcDwOJ5G1qE+V+nvaoBHx41H05w4TZTFJL+UnRy99NDLrVbLoCWhoH3L8vyNmZVjTvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/lib-state": "1.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-tasklist/node_modules/@svar-ui/lib-data-provider/node_modules/@svar-ui/lib-state": {
|
||||||
|
"version": "1.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/lib-state/-/lib-state-1.9.6.tgz",
|
||||||
|
"integrity": "sha512-twoHa8wZvzdxtES68s6Wnp4Xi1WivScNaFFK6sJ6WDgqVYOzJw0ZhVVrdwHQgieLITTKl/DYh/U3nuqtMetKYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/react-toolbar": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/react-toolbar/-/react-toolbar-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-jSxcTW8WNgpSgkxicGyu76cKjVuwwxOvdDXJqQpLnxIIdN/RNeWuY8ak4sD0IqhCOp7AicgfPg2t+K4YUp+LMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svar-ui/core-locales": "2.6.1",
|
||||||
|
"@svar-ui/lib-dom": "0.14.0",
|
||||||
|
"@svar-ui/react-core": "2.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svar-ui/tasklist-locales": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svar-ui/tasklist-locales/-/tasklist-locales-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-ewGvdmALpEJR3CpzlNX8aDL2JPmeyF1EweRBoI0jQmp7bIpYDIlpTWStmGwDEwQ5SgvUTJylFyIj6baPf2RBlw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@swc/core": {
|
"node_modules/@swc/core": {
|
||||||
"version": "1.12.7",
|
"version": "1.12.7",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.12.7.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.12.7.tgz",
|
||||||
@@ -5926,6 +6306,16 @@
|
|||||||
"integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==",
|
"integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/date-fns": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/kossnocorp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@chakra-ui/react": "^3.22.0",
|
"@chakra-ui/react": "^3.22.0",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.1",
|
"@emotion/styled": "^11.14.1",
|
||||||
|
"@svar-ui/react-gantt": "^2.7.3",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"framer-motion": "^12.23.0",
|
"framer-motion": "^12.23.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import Volcano from "@/pages/volcano/Volcano.jsx";
|
|||||||
import GlobalMap from "./pages/maps/GlobalMap.jsx";
|
import GlobalMap from "./pages/maps/GlobalMap.jsx";
|
||||||
import Admin from "./pages/admin/Admin.jsx";
|
import Admin from "./pages/admin/Admin.jsx";
|
||||||
import MyDashboard from "./pages/home/tabs/MyDashboard.jsx";
|
import MyDashboard from "./pages/home/tabs/MyDashboard.jsx";
|
||||||
|
import Settings from "./pages/auth/Settings.jsx";
|
||||||
|
import WebAdmin from "./pages/auth/WebAdmin.jsx";
|
||||||
|
|
||||||
function AppFoundation() {
|
function AppFoundation() {
|
||||||
const recipe = useRecipe({ key: "dashboard" });
|
const recipe = useRecipe({ key: "dashboard" });
|
||||||
@@ -81,6 +83,9 @@ function App() {
|
|||||||
<Route path="daily" element={<Placeholder name="Daily Activity" />} />
|
<Route path="daily" element={<Placeholder name="Daily Activity" />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
<Route path="/settings" element={<Settings />} />
|
||||||
|
<Route path="/web-admin" element={<WebAdmin />} />
|
||||||
|
|
||||||
<Route path="/global-map" element={<GlobalMap />} />
|
<Route path="/global-map" element={<GlobalMap />} />
|
||||||
<Route path="/regional-map" element={<RegionalMap />} />
|
<Route path="/regional-map" element={<RegionalMap />} />
|
||||||
<Route path="/volcano" element={<Volcano />} />
|
<Route path="/volcano" element={<Volcano />} />
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { Gantt, Willow } from "@svar-ui/react-gantt";
|
||||||
|
import "@svar-ui/react-gantt/all.css";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import {Avatar, Flex, Text} from "@chakra-ui/react";
|
||||||
|
|
||||||
|
export default function TravelGanttChart() {
|
||||||
|
|
||||||
|
const upcoming_travel = useMemo(() => [
|
||||||
|
{
|
||||||
|
id: 20,
|
||||||
|
text: "Guatemala",
|
||||||
|
start: new Date(2026, 9, 21),
|
||||||
|
end: new Date(2026, 9, 29),
|
||||||
|
duration: 8,
|
||||||
|
participants: ["Chris Hight", "Angie Diefenbach"],
|
||||||
|
type: "travel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 47,
|
||||||
|
text: "Venuatu",
|
||||||
|
start: new Date(2026, 10, 12),
|
||||||
|
end: new Date(2026, 10, 15),
|
||||||
|
duration: 3,
|
||||||
|
participants: ["Chris Hight"],
|
||||||
|
type: "travel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 22,
|
||||||
|
text: "Costa Rica",
|
||||||
|
start: new Date(2027, 1, 1),
|
||||||
|
end: new Date(2027, 1, 10),
|
||||||
|
duration: 9,
|
||||||
|
participants: ["Chris Hight"],
|
||||||
|
type: "travel",
|
||||||
|
},
|
||||||
|
], []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: "start", header: "Start Date", width: 100, height: 200, align: "left" },
|
||||||
|
{ id: "duration", header: "Duration", width: 100, height: 200, align: "left" },
|
||||||
|
{ id: "participants", header: "Participants", width: 150, height: 200, align: "center", cell: AvatarCell, flexgrow: 1 },
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ height: "100%", width: "100%" }}>
|
||||||
|
<Willow>
|
||||||
|
<Gantt tasks={upcoming_travel} cellWidth={20} columns={columns} />
|
||||||
|
</Willow>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume each user has access to the full list of VDAP users
|
||||||
|
|
||||||
|
const users = [
|
||||||
|
{
|
||||||
|
fullname: "Chris Hight",
|
||||||
|
firstname: "Chris",
|
||||||
|
lastname: "Hight",
|
||||||
|
avatar: undefined
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullname: "Angie Diefenbach",
|
||||||
|
firstname: "Chris",
|
||||||
|
lastname: "Hight",
|
||||||
|
avatar: undefined
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fullname: "Venessa Kuchenik",
|
||||||
|
firstname: "Venessa",
|
||||||
|
lastname: "Kuchenik",
|
||||||
|
avatar: undefined
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
function AvatarCell({ row }) {
|
||||||
|
const travelers = row.participants.map((r) => {
|
||||||
|
return users.find((u) => u.fullname === r);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex direction="column" alignItems="left" justifyContent="space-between">
|
||||||
|
{travelers.map((traveler) => (
|
||||||
|
<Avatar.Root shape="full">
|
||||||
|
<Avatar.Image src={traveler.avatar} />
|
||||||
|
<Avatar.Fallback name={traveler.fullname} />
|
||||||
|
<Text>{traveler.fullname}</Text>
|
||||||
|
</Avatar.Root>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -203,6 +203,16 @@ export const WIDGET_REGISTRY = {
|
|||||||
allowedSizes: {
|
allowedSizes: {
|
||||||
medium: { w: 6, h: 12 }
|
medium: { w: 6, h: 12 }
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"travel_gantt_chart": {
|
||||||
|
name: "Travel Gantt Chart",
|
||||||
|
category: "Communications",
|
||||||
|
description: "View upcoming travels in a gantt chart",
|
||||||
|
component: lazy(() => import('../components/Widgets/TravelGanttChart.jsx')),
|
||||||
|
allowedSizes: {
|
||||||
|
medium: { w: 6, h: 12 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
:root {
|
:root {
|
||||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wx-theme {
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import { Flex, Text, Input, Field, Button, Separator, NativeSelect, Image } from '@chakra-ui/react';
|
||||||
|
import useAuthStore from "../../store/authStore.js";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function Settings() {
|
||||||
|
const { user } = useAuthStore();
|
||||||
|
const { register, handleSubmit, errors } = useForm();
|
||||||
|
const [value, setValue] = useState(undefined);
|
||||||
|
const updateProfile = useAuthStore((state) => state.updateProfile);
|
||||||
|
|
||||||
|
const onSubmit = (data, event) => {
|
||||||
|
// TODO: check for identical usernames
|
||||||
|
event.preventDefault();
|
||||||
|
console.log(data);
|
||||||
|
if (data.username && data.username.length !== "") updateProfile(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ivansRequest = () => {
|
||||||
|
console.log(user.username, "requested ivans permissions");
|
||||||
|
// TODO: log users request in database here which will then display request in web-admin page
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Flex direction="column" w="100%" h="100%" p="15rem" pt="3rem" gap="5rem">
|
||||||
|
|
||||||
|
{/* CONTENT */}
|
||||||
|
<Flex direction="column" w="100%" h="100%" gap={4}>
|
||||||
|
{/* header */}
|
||||||
|
<Text fontWeight="semibold" fontSize="xl">Settings</Text>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300"/>
|
||||||
|
|
||||||
|
{/* personal info */}
|
||||||
|
<Flex direction="column" w="100%" gap={4}>
|
||||||
|
<Text fontWeight="semibold" fontSize="lg">Personal Information</Text>
|
||||||
|
{/* profile picture & name */}
|
||||||
|
<Flex direction="row" w="100%" align="center" justify="space-between" gap={5}>
|
||||||
|
<Flex direction="row" w="100%" align="center" gap={5}>
|
||||||
|
<Image borderRadius="full" boxSize="100px" src="https://i.pravatar.cc/300?img=10" />
|
||||||
|
<Flex direction="column">
|
||||||
|
<Text fontWeight="semibold">Name</Text>
|
||||||
|
<Text pl={2}>{user.firstName || "first name"}, {user.lastName || "last name"}</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Button variant="subtle" size="sm">Update photo</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex direction="row" w="100%" gap={5}>
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label fontWeight="semibold">Username</Field.Label>
|
||||||
|
<Input {...register("username")} placeholder={user.username} variant="subtle" />
|
||||||
|
</Field.Root>
|
||||||
|
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label fontWeight="semibold">Email</Field.Label>
|
||||||
|
<Input {...register("email")} type="email" placeholder={user.email || "example@usgs.gov"} variant="subtle" />
|
||||||
|
</Field.Root>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex direction="row" w="100%" gap={5}>
|
||||||
|
<Field.Root pb={8}>
|
||||||
|
<Field.Label fontWeight="semibold">Descipline</Field.Label>
|
||||||
|
<NativeSelect.Root size="sm" variant="subtle">
|
||||||
|
<NativeSelect.Field
|
||||||
|
w="100%"
|
||||||
|
h="2.5rem"
|
||||||
|
placeholder="Select option"
|
||||||
|
{...register("discipline")}
|
||||||
|
>
|
||||||
|
<option value="RS">Remote Sensing</option>
|
||||||
|
<option value="CS">Computer Science</option>
|
||||||
|
<option value="Engineering">Engineering</option>
|
||||||
|
<option value="HR">Human Resources (HR)</option>
|
||||||
|
</NativeSelect.Field>
|
||||||
|
<NativeSelect.Indicator />
|
||||||
|
</NativeSelect.Root>
|
||||||
|
<Field.ErrorText></Field.ErrorText>
|
||||||
|
</Field.Root>
|
||||||
|
<Flex w="100%"></Flex> {/* filler so that discipline dropdown sizes correctly */}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300"/>
|
||||||
|
|
||||||
|
{/* permission requests */}
|
||||||
|
<Flex direction="column" gap={2}>
|
||||||
|
<Text fontWeight="semibold" fontSize="lg">Permissions</Text>
|
||||||
|
<Flex direction="row" w="100%" align="center" justify="space-between" pl={2}>
|
||||||
|
<Text>Request access to IVANS</Text>
|
||||||
|
<Button variant="subtle" size="sm" onClick={ivansRequest}>IVANS Request</Button>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction="row" w="100%" align="center" justify="space-between" pl={2}>
|
||||||
|
<Text>Request access to Remote Sensing</Text>
|
||||||
|
<Button variant="subtle" size="sm" onClick={ivansRequest}>Remote Sensing Request</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300" />
|
||||||
|
|
||||||
|
{/* themes */}
|
||||||
|
<Flex direction="column">
|
||||||
|
<Text fontWeight="semibold" fontSize="lg">Theme</Text>
|
||||||
|
<Flex direction="row" align="center" justify="space-between" pl={2}>
|
||||||
|
<Text fontSize="md">Appearance</Text>
|
||||||
|
<NativeSelect.Root size="sm" w="10rem" variant="subtle">
|
||||||
|
<NativeSelect.Field
|
||||||
|
placeholder="Select option"
|
||||||
|
{...register("theme")}
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => setValue(e.currentTarget.value)}
|
||||||
|
>
|
||||||
|
<option value="Light">Light</option>
|
||||||
|
<option value="Dark">Dark</option>
|
||||||
|
</NativeSelect.Field>
|
||||||
|
<NativeSelect.Indicator />
|
||||||
|
</NativeSelect.Root>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* SAVE-ALL PREFERENCES BUTTON */}
|
||||||
|
{/* TODO: grey out button until changes are detected */}
|
||||||
|
<Button type="submit" w="150px" variant="subtle" borderRadius="lg" alignSelf="center">
|
||||||
|
Save Changes
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
import {Flex, Separator, Text, Table, IconButton, NativeSelect, Button} from "@chakra-ui/react";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { useForm, useFieldArray } from "react-hook-form";
|
||||||
|
import { Check, X, PenLine } from 'lucide-react';
|
||||||
|
import VdapApi from "../../hooks/useVdapApi.js";
|
||||||
|
import useBuildUrl from "../../hooks/useBuildUrl.js";
|
||||||
|
|
||||||
|
export default function WebAdmin() {
|
||||||
|
// TODO: add below api endpoint
|
||||||
|
// const {data: users, isLoading, error} = VdapApi('/api/v2/vdap_web_users');
|
||||||
|
|
||||||
|
const users = useMemo(() => [
|
||||||
|
{
|
||||||
|
"username": "vkuchenik",
|
||||||
|
"firstName": "Venessa",
|
||||||
|
"lastName": "Kuchenik",
|
||||||
|
"permissions": {
|
||||||
|
"ivans": 2, // 2 => requested permission
|
||||||
|
"rs": 0, // 0 => no permissions and not requested
|
||||||
|
},
|
||||||
|
"team": "Computer Science",
|
||||||
|
"group": "Super User",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "amack",
|
||||||
|
"firstName": "Adeiline",
|
||||||
|
"lastName": "Mack",
|
||||||
|
"permissions": {
|
||||||
|
"ivans": 2, // 0 => no permissions and not requested
|
||||||
|
"rs": 2, // 1 => has permission
|
||||||
|
},
|
||||||
|
"team": "Remote Sensing",
|
||||||
|
"group": "Member",
|
||||||
|
}
|
||||||
|
], []);
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
control,
|
||||||
|
errors,
|
||||||
|
formState: { isDirty }
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: {users: users}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { fields, append, remove } = useFieldArray({
|
||||||
|
control,
|
||||||
|
name: "users" // Matches the key in defaultValues
|
||||||
|
})
|
||||||
|
|
||||||
|
const grant = (user, category) => {
|
||||||
|
// 1. post data via api
|
||||||
|
// 2. fetch the new data via api again to force re-render
|
||||||
|
console.log(user.username, "was granted", category, "permission");
|
||||||
|
}
|
||||||
|
|
||||||
|
const deny = (user, category) => {
|
||||||
|
console.log(user.username, "was denied", category, "permission");
|
||||||
|
}
|
||||||
|
|
||||||
|
const users_req_ivans = useMemo(() => {
|
||||||
|
return users.filter(user => user.permissions.ivans === 2);
|
||||||
|
}, [users]);
|
||||||
|
|
||||||
|
const users_req_rs = useMemo(() => {
|
||||||
|
return users.filter(user => user.permissions.rs === 2);
|
||||||
|
}, [users]);
|
||||||
|
|
||||||
|
const onSubmit = (data, event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Flex direction="column" w="100%" h="100%" p="15rem" pt="3rem" gap="3rem">
|
||||||
|
|
||||||
|
{/* CONTENT */}
|
||||||
|
<Flex direction="column" w="100%" gap={4}>
|
||||||
|
{/* Header */}
|
||||||
|
<Text fontSize="xl" fontWeight="bold">Web Admin Panel</Text>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300"/>
|
||||||
|
|
||||||
|
{/* Permission Requests */}
|
||||||
|
<Flex direction="column" w="100%" gap={2} pb={4}>
|
||||||
|
<Text fontSize="lg" fontWeight="bold">Incoming Permission Requests</Text>
|
||||||
|
<Flex direction="row" w="100%" gap={5}>
|
||||||
|
{/* ivans requests table */}
|
||||||
|
<Flex direction="column" w="100%" gap={2}>
|
||||||
|
<Text fontSize="sm" fontWeight="bold">IVANS</Text>
|
||||||
|
<Table.Root w="100%" size="sm" variant="outline" borderRadius="lg">
|
||||||
|
<Table.Header>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.ColumnHeader w="100%" fontWeight="bold">User</Table.ColumnHeader>
|
||||||
|
<Table.ColumnHeader fontWeight="bold" textAlign="left">Permission</Table.ColumnHeader>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Header>
|
||||||
|
<Table.Body>
|
||||||
|
{users_req_ivans.map((user) => (
|
||||||
|
<Table.Row key={user.username}>
|
||||||
|
<Table.Cell w="100%">{user.lastName}, {user.firstName}</Table.Cell>
|
||||||
|
<Table.Cell >
|
||||||
|
<Flex w="100%" gap={1} justify="left">
|
||||||
|
<IconButton borderRadius="xl" size="xs" variant="subtle" onClick={() => grant(user, "ivans")}>
|
||||||
|
<Check />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton borderRadius="xl" size="xs" variant="subtle" onClick={() => deny(user, "ivans")}>
|
||||||
|
<X />
|
||||||
|
</IconButton>
|
||||||
|
</Flex>
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
))}
|
||||||
|
</Table.Body>
|
||||||
|
</Table.Root>
|
||||||
|
</Flex>
|
||||||
|
{/* rs requests table */}
|
||||||
|
<Flex direction="column" w="100%" gap={2}>
|
||||||
|
<Text fontSize="sm" fontWeight="bold">Remote Sensing</Text>
|
||||||
|
<Table.Root w="100%" size="sm" variant="outline" borderRadius="lg">
|
||||||
|
<Table.Header>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.ColumnHeader w="100%" fontWeight="bold">User</Table.ColumnHeader>
|
||||||
|
<Table.ColumnHeader fontWeight="bold" textAlign="left">Permission</Table.ColumnHeader>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Header>
|
||||||
|
<Table.Body>
|
||||||
|
{users_req_rs.map((user) => (
|
||||||
|
<Table.Row key={user.username}>
|
||||||
|
<Table.Cell>{user.lastName}, {user.firstName}</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
<Flex w="100%" gap={1} justify="left">
|
||||||
|
<IconButton borderRadius="xl" size="xs" variant="subtle" onClick={() => grant(user, "rs")}>
|
||||||
|
<Check />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton borderRadius="xl" size="xs" variant="subtle" onClick={() => deny(user, "rs")}>
|
||||||
|
<X />
|
||||||
|
</IconButton>
|
||||||
|
</Flex>
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
))}
|
||||||
|
</Table.Body>
|
||||||
|
</Table.Root>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300"/>
|
||||||
|
|
||||||
|
{/* Group Assignment */}
|
||||||
|
<Flex direction="column" w="100%" gap={2} pb={4}>
|
||||||
|
<Text fontWeight="bold" fontSize="lg">Groups</Text>
|
||||||
|
<Table.Root w="50%" size="sm" variant="outline" borderRadius="lg">
|
||||||
|
<Table.Header>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.ColumnHeader fontWeight="bold">User</Table.ColumnHeader>
|
||||||
|
<Table.ColumnHeader fontWeight="bold" textAlign="left">Group</Table.ColumnHeader>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Header>
|
||||||
|
<Table.Body>
|
||||||
|
{users.map((user, index) => (
|
||||||
|
<Table.Row key={user.username}>
|
||||||
|
<Table.Cell w="100%">{user.lastName}, {user.firstName}</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
<Flex w="100%" justify="left">
|
||||||
|
<NativeSelect.Root size="sm" w="175px" variant="subtle">
|
||||||
|
<NativeSelect.Field
|
||||||
|
defaultValue={user.group}
|
||||||
|
{...register(`users.${index}.group`)}
|
||||||
|
>
|
||||||
|
<option value="Super User">Super User</option>
|
||||||
|
<option value="Member">Member</option>
|
||||||
|
</NativeSelect.Field>
|
||||||
|
<NativeSelect.Indicator />
|
||||||
|
</NativeSelect.Root>
|
||||||
|
</Flex>
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
))}
|
||||||
|
</Table.Body>
|
||||||
|
</Table.Root>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Separator borderColor="gray.300"/>
|
||||||
|
|
||||||
|
{/* Team Assignment */}
|
||||||
|
<Flex direction="column" w="100%" gap={2} pb={4}>
|
||||||
|
<Text fontWeight="bold" fontSize="lg">Teams</Text>
|
||||||
|
<Table.Root w="50%" size="sm" variant="outline" borderRadius="lg">
|
||||||
|
<Table.Header>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.ColumnHeader fontWeight="bold" w="100%">User</Table.ColumnHeader>
|
||||||
|
<Table.ColumnHeader fontWeight="bold" textAlign="left">Team</Table.ColumnHeader>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Header>
|
||||||
|
<Table.Body>
|
||||||
|
{users.map((user, index) => {
|
||||||
|
console.log("user in team: ", user.team);
|
||||||
|
return(
|
||||||
|
<Table.Row key={user.username}>
|
||||||
|
<Table.Cell>
|
||||||
|
{user.lastName}, {user.firstName}
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
<Flex w="100%" justify="right">
|
||||||
|
<NativeSelect.Root size="sm" w="175px" variant="subtle">
|
||||||
|
<NativeSelect.Field
|
||||||
|
defaultValue={user.team}
|
||||||
|
{...register(`users.${index}.team`)}
|
||||||
|
>
|
||||||
|
<option value="Computer Science">Computer Science</option>
|
||||||
|
<option value="Remote Sensing">Remote Sensing</option>
|
||||||
|
</NativeSelect.Field>
|
||||||
|
<NativeSelect.Indicator />
|
||||||
|
</NativeSelect.Root>
|
||||||
|
</Flex>
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
)})}
|
||||||
|
</Table.Body>
|
||||||
|
</Table.Root>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Button type="submit" w="100px" variant="subtle" alignSelf="center">
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -86,7 +86,22 @@ const useAuthStore = create((set) => ({
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to save layout to database", error);
|
console.error("Failed to save layout to database", error);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// updateProfile: async (newProfile) => {
|
||||||
|
// try {
|
||||||
|
// set((state) => ({
|
||||||
|
// user: {
|
||||||
|
// ...state.user,
|
||||||
|
// username: newProfile.username,
|
||||||
|
// }
|
||||||
|
// }));
|
||||||
|
//
|
||||||
|
// await api.post('profile/update/', { profile: newProfile });
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Failed to update profile", error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useAuthStore;
|
export default useAuthStore;
|
||||||
Reference in New Issue
Block a user