From a4355967d0f97a3b65f1a2cbeac52b58c17c398f Mon Sep 17 00:00:00 2001 From: Donkie Date: Tue, 19 Nov 2024 21:49:29 +0100 Subject: [PATCH 01/16] Added basic locations page to easily move spools between locations --- client/package-lock.json | 75 ++++++++++- client/package.json | 4 +- client/src/App.tsx | 10 ++ client/src/pages/locations/functions.ts | 18 +++ client/src/pages/locations/index.tsx | 151 +++++++++++++++++++++++ client/src/pages/locations/locations.css | 40 ++++++ 6 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 client/src/pages/locations/functions.ts create mode 100644 client/src/pages/locations/index.tsx create mode 100644 client/src/pages/locations/locations.css diff --git a/client/package-lock.json b/client/package-lock.json index b31659d3..57b07f7b 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -30,6 +30,8 @@ "i18next-http-backend": "^2.5.2", "lodash": "^4.17.21", "react": "^18.3.1", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", "react-i18next": "^15.0.0", "react-router-dom": "^6.26.0", @@ -1939,6 +1941,21 @@ "resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz", "integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==" }, + "node_modules/@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" + }, + "node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" + }, "node_modules/@refinedev/antd": { "version": "5.42.0", "resolved": "https://registry.npmjs.org/@refinedev/antd/-/antd-5.42.0.tgz", @@ -4236,6 +4253,16 @@ "node": ">=8" } }, + "node_modules/dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "dependencies": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -4847,8 +4874,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-equals": { "version": "2.0.4", @@ -8128,6 +8154,43 @@ "node": ">=0.10.0" } }, + "node_modules/react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "dependencies": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "@types/hoist-non-react-statics": ">= 3.3.1", + "@types/node": ">= 12", + "@types/react": ">= 16", + "react": ">= 16.14" + }, + "peerDependenciesMeta": { + "@types/hoist-non-react-statics": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "dependencies": { + "dnd-core": "^16.0.1" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -8300,6 +8363,14 @@ "esprima": "~4.0.0" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", diff --git a/client/package.json b/client/package.json index f71ddabd..38f8c3ab 100644 --- a/client/package.json +++ b/client/package.json @@ -29,6 +29,8 @@ "i18next-http-backend": "^2.5.2", "lodash": "^4.17.21", "react": "^18.3.1", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", "react-i18next": "^15.0.0", "react-router-dom": "^6.26.0", @@ -70,4 +72,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/client/src/App.tsx b/client/src/App.tsx index 788e1846..0e6422a9 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -10,6 +10,7 @@ import { HighlightOutlined, HomeOutlined, QuestionOutlined, + TableOutlined, ToolOutlined, UserOutlined, } from "@ant-design/icons"; @@ -148,6 +149,14 @@ function App() { icon: , }, }, + { + name: "locations", + list: "/locations", + meta: { + canDelete: false, + icon: , + }, + }, { name: "settings", list: "/settings", @@ -222,6 +231,7 @@ function App() { } /> } /> + } /> } /> diff --git a/client/src/pages/locations/functions.ts b/client/src/pages/locations/functions.ts new file mode 100644 index 00000000..4bb91af3 --- /dev/null +++ b/client/src/pages/locations/functions.ts @@ -0,0 +1,18 @@ +import { getAPIURL } from "../../utils/url"; +import { ISpool } from "../spools/model"; + +export async function setSpoolLocation(spool_id: number, location: string | null): Promise { + const response = await fetch(getAPIURL() + "/spool/" + spool_id, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + location: location, + }), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + return response.json(); +} diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx new file mode 100644 index 00000000..c628df7a --- /dev/null +++ b/client/src/pages/locations/index.tsx @@ -0,0 +1,151 @@ +import { IResourceComponentsProps, useInvalidate, useList, useTranslate } from "@refinedev/core"; +import { theme } from "antd"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import React from "react"; +import { DndProvider, useDrag, useDrop } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; + +import SpoolIcon from "../../components/spoolIcon"; +import { ISpool } from "../spools/model"; +import { setSpoolLocation } from "./functions"; +import "./locations.css"; + +dayjs.extend(utc); + +const { useToken } = theme; + +function SpoolCard({ spool }: { spool: ISpool }) { + const { token } = useToken(); + const [{ opacity }, dragRef] = useDrag( + () => ({ + type: "spool", + item: spool, + collect: (monitor) => ({ + opacity: monitor.isDragging() ? 0.5 : 1, + }), + }), + [] + ); + + const colorObj = spool.filament.multi_color_hexes + ? { + colors: spool.filament.multi_color_hexes.split(","), + vertical: spool.filament.multi_color_direction === "longitudinal", + } + : spool.filament.color_hex || "#000000"; + + let filament_name: string; + if (spool.filament.vendor && "name" in spool.filament.vendor) { + filament_name = `${spool.filament.vendor.name} - ${spool.filament.name}`; + } else { + filament_name = spool.filament.name ?? spool.filament.id.toString(); + } + + const style = { + opacity, + backgroundColor: token.colorBgContainerDisabled, + }; + + return ( +
+ +
+
+ #{spool.id} {filament_name} +
+
+ {spool.remaining_weight} / {spool.filament.weight} g +
+
+
+ ); +} + +function LocationContainer({ title, spools }: { title: string; spools: ISpool[] }) { + const { token } = useToken(); + const invalidate = useInvalidate(); + + const [, drop] = useDrop(() => ({ + accept: "spool", + drop: (item: ISpool) => { + setSpoolLocation(item.id, title).then(() => { + invalidate({ + resource: "spool", + id: item.id, + invalidates: ["list", "detail"], + }); + }); + }, + })); + + const style = { + backgroundColor: token.colorBgContainer, + borderRadius: token.borderRadiusLG, + }; + + return ( +
+

{title}

+
+ {spools.map((spool) => ( + + ))} +
+
+ ); +} + +export const Locations: React.FC = () => { + const t = useTranslate(); + + const { data, isLoading, isError } = useList({ + resource: "spool", + meta: { + queryParams: { + ["allow_archived"]: false, + }, + }, + pagination: { + mode: "off", + }, + }); + + if (isLoading) { + return
Loading...
; + } + + if (isError) { + return
Failed to load spools
; + } + + const spools = data?.data ?? []; + spools.sort((a, b) => a.id - b.id); + + // Locations is all the unique locations of the spools + const spoolLocations: Record = {}; + spools.forEach((spool) => { + const loc = spool.location ?? t("spool.no_location"); + if (!spoolLocations[loc]) { + spoolLocations[loc] = []; + } + spoolLocations[loc].push(spool); + }); + + const locationsList = Object.keys(spoolLocations); + locationsList.sort((a, b) => { + return a.localeCompare(b); + }); + + const containers = locationsList.map((loc) => { + return ; + }); + + return ( + +
{containers}
+
+ ); +}; + +export default Locations; diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css new file mode 100644 index 00000000..76abccc9 --- /dev/null +++ b/client/src/pages/locations/locations.css @@ -0,0 +1,40 @@ +.loc-metacontainer { + display: flex; + flex-wrap: wrap; +} + +.loc-container { + padding: 1em; + width: 20em; +} + +.loc-container .loc-spools { + padding: 0.2em; + display: flex; + flex-direction: column; + gap: 0.5em; + max-height: 100em; + overflow-y: scroll; +} + +.loc-container .spool { + padding: 0.5em 0.5em 0.5em 0; + display: flex; + align-items: center; + cursor: pointer; + border-radius: 0.5em; +} + +.loc-container .spool .info { + display: flex; + flex-direction: column; + gap: 0.5em; +} + +.loc-container .spool .info .title { + font-size: 1em; +} + +.loc-container .spool .info .subtitle { + font-size: 0.8em; +} From b5681478843d87f8fb4922befd1c1f2305e3bd7a Mon Sep 17 00:00:00 2001 From: Donkie Date: Tue, 19 Nov 2024 21:56:22 +0100 Subject: [PATCH 02/16] Updated some dependencies --- client/package-lock.json | 2101 +++++++++++++++++++++++--------------- client/package.json | 44 +- 2 files changed, 1310 insertions(+), 835 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 57b07f7b..273f4671 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -8,51 +8,51 @@ "name": "spoolman-ui", "version": "0.20.0", "dependencies": { - "@ant-design/icons": "^5.4.0", + "@ant-design/icons": "^5.5.1", "@loadable/component": "^5.16.4", - "@refinedev/antd": "^5.42.0", - "@refinedev/core": "^4.53.0", + "@refinedev/antd": "^5.44.0", + "@refinedev/core": "^4.56.0", "@refinedev/kbar": "^1.3.12", - "@refinedev/react-router-v6": "^4.5.11", + "@refinedev/react-router-v6": "^4.6.0", "@refinedev/simple-rest": "^5.0.8", "@tanstack/react-query": "^4.36.1", "@tanstack/react-query-devtools": "^4.36.1", "@types/loadable__component": "^5.13.9", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.13", "@types/uuid": "^10.0.0", "@yudiel/react-qr-scanner": "^1.2.10", - "antd": "^5.20.0", + "antd": "^5.22.1", "axios": "^1.7.7", "flag-icons": "^7.2.3", "html-to-image": "^1.11.11", - "i18next": "^23.12.2", + "i18next": "^23.16.6", "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.5.2", + "i18next-http-backend": "^2.6.2", "lodash": "^4.17.21", "react": "^18.3.1", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", - "react-i18next": "^15.0.0", - "react-router-dom": "^6.26.0", + "react-i18next": "^15.1.1", + "react-router-dom": "^6.28.0", "react-to-print": "^2.15.1", - "uuid": "^10.0.0", - "vite-plugin-svgr": "^4.2.0" + "uuid": "^11.0.3", + "vite-plugin-svgr": "^4.3.0" }, "devDependencies": { - "@refinedev/cli": "^2.16.36", - "@types/node": "^20.14.6", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "@vitejs/plugin-react": "^4.3.1", + "@refinedev/cli": "^2.16.39", + "@types/node": "^22.9.1", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@typescript-eslint/eslint-plugin": "^8.15.0", + "@typescript-eslint/parser": "^8.15.0", + "@vitejs/plugin-react": "^4.3.3", "eslint": "^9.8.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", - "typescript": "^5.5.4", - "vite": "^5.4.6", - "vite-plugin-mkcert": "^1.17.5" + "typescript": "^5.6.3", + "vite": "^5.4.11", + "vite-plugin-mkcert": "^1.17.6" }, "engines": { "node": "20.x" @@ -88,9 +88,9 @@ } }, "node_modules/@ant-design/cssinjs": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz", - "integrity": "sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.22.0.tgz", + "integrity": "sha512-W9XSFeRPR0mAN3OuxfuS/xhENCYKf+8s+QyNNER0FSWoK9OpISTag6CCweg6lq0hASQ/2Vcza0Z8/kGivCP0Ng==", "dependencies": { "@babel/runtime": "^7.11.1", "@emotion/hash": "^0.8.0", @@ -98,7 +98,7 @@ "classnames": "^2.3.1", "csstype": "^3.1.3", "rc-util": "^5.35.0", - "stylis": "^4.0.13" + "stylis": "^4.3.4" }, "peerDependencies": { "react": ">=16.0.0", @@ -106,9 +106,9 @@ } }, "node_modules/@ant-design/cssinjs-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs-utils/-/cssinjs-utils-1.0.3.tgz", - "integrity": "sha512-BrztZZKuoYcJK8uEH40ylBemf/Mu/QPiDos56g2bv6eUoniQkgQHOCOvA3+pncoFO1TaS8xcUCIqGzDA0I+ZVQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.1.tgz", + "integrity": "sha512-2HAiyGGGnM0es40SxdszeQAU5iWp41wBIInq+ONTCKjlSKOrzQfnw4JDtB8IBmqE6tQaEKwmzTP2LGdt5DSwYQ==", "dependencies": { "@ant-design/cssinjs": "^1.21.0", "@babel/runtime": "^7.23.2", @@ -120,9 +120,9 @@ } }, "node_modules/@ant-design/fast-color": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.5.tgz", - "integrity": "sha512-kzUEdptM2vbHFn+fGkgKgbfsko5TR9GlGvAj+Xa7pKSXipbsvbqPtxcUGv7vdoPHFCr6JUBZa8Rfs+QJtFZEAw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz", + "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==", "dependencies": { "@babel/runtime": "^7.24.7" }, @@ -131,9 +131,9 @@ } }, "node_modules/@ant-design/icons": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.4.0.tgz", - "integrity": "sha512-QZbWC5xQYexCI5q4/fehSEkchJr5UGtvAJweT743qKUQQGs9IH2DehNLP49DJ3Ii9m9CijD2HN6fNy3WKhIFdA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.5.1.tgz", + "integrity": "sha512-0UrM02MA2iDIgvLatWrj6YTCYe0F/cwXvVE0E2SqGrL7PZireQwgEKTKBisWpZyal5eXZLvuM98kju6YtYne8w==", "dependencies": { "@ant-design/colors": "^7.0.0", "@ant-design/icons-svg": "^4.4.0", @@ -155,65 +155,69 @@ "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" }, "node_modules/@ant-design/pro-layout": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@ant-design/pro-layout/-/pro-layout-7.17.12.tgz", - "integrity": "sha512-iqA1Iks7pqHJUhWp13jKy3ORvCMho3lLIBheru0nIlO3S10/BF+UbJABch+PJLZPLrXesJomqT1mq7VnFUFElQ==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@ant-design/pro-layout/-/pro-layout-7.21.2.tgz", + "integrity": "sha512-dtqap5YNDrxUWxhi43QJQSv1JLHYPCV4/h4cFM10HNiX/86Cxw37DiCOMdIM/ZwWk619BiwN7CJNgL5Q8obrAQ==", "dependencies": { + "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.13.3", - "@ant-design/pro-utils": "2.14.12", + "@ant-design/pro-provider": "2.15.2", + "@ant-design/pro-utils": "2.16.2", "@babel/runtime": "^7.18.0", "@umijs/route-utils": "^4.0.0", "@umijs/use-params": "^1.0.9", "classnames": "^2.3.2", - "lodash.merge": "^4.6.2", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "omit.js": "^2.0.2", - "path-to-regexp": "2.4.0", + "path-to-regexp": "8.0.0", "rc-resize-observer": "^1.1.0", "rc-util": "^5.0.6", "swr": "^2.0.0", "warning": "^4.0.3" }, "peerDependencies": { - "antd": ">=4.23.0 || >=5.0.0", + "antd": "^4.24.15 || ^5.11.2", "react": ">=17.0.0", "react-dom": ">=17.0.0" } }, "node_modules/@ant-design/pro-provider": { - "version": "2.13.3", - "resolved": "https://registry.npmjs.org/@ant-design/pro-provider/-/pro-provider-2.13.3.tgz", - "integrity": "sha512-qkD/qA5NsLRxQTDdkgfviTZbsC0BeHahNTbJiZdwVwYMMLBzg0C1ptnHm4ofKdXt0EzARg/WG5EjaVOtvs/sFw==", + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/@ant-design/pro-provider/-/pro-provider-2.15.2.tgz", + "integrity": "sha512-7WSJcjYIuLwco1YiiSgEEJnrqvg7x/YZap8pxOChRnyNh9S3HuV1D5HTc18kfHTpWqZWTAUcS66b0kMP96uKrw==", "dependencies": { - "@ant-design/cssinjs": "^1.11.1", + "@ant-design/cssinjs": "^1.21.1", "@babel/runtime": "^7.18.0", "@ctrl/tinycolor": "^3.4.0", + "dayjs": "^1.11.10", "rc-util": "^5.0.1", "swr": "^2.0.0" }, "peerDependencies": { - "antd": ">=4.23.0 || >=5.0.0", + "antd": "^4.24.15 || ^5.11.2", "react": ">=17.0.0", "react-dom": ">=17.0.0" } }, "node_modules/@ant-design/pro-utils": { - "version": "2.14.12", - "resolved": "https://registry.npmjs.org/@ant-design/pro-utils/-/pro-utils-2.14.12.tgz", - "integrity": "sha512-hPNO/PFOeWCWl2p/VxM6JIeKvqAPJCheqh8kw0HuPfGpAmr6k8Wf4G9/6er5rmfYryObW11OOmBSyXTxM9sWUg==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@ant-design/pro-utils/-/pro-utils-2.16.2.tgz", + "integrity": "sha512-ama73ZSzz9O6Qz6DvHd6cnyUA3vI7N+AAl5BV5plijujtnXpNC8KJMXl9jOI1K7QuUVJgJIKbZ2DVm8LnBcTAQ==", "dependencies": { "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.13.3", + "@ant-design/pro-provider": "2.15.2", "@babel/runtime": "^7.18.0", "classnames": "^2.3.2", "dayjs": "^1.11.10", - "lodash.merge": "^4.6.2", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "rc-util": "^5.0.6", "safe-stable-stringify": "^2.4.3", "swr": "^2.0.0" }, "peerDependencies": { - "antd": ">=4.23.0 || >=5.0.0", + "antd": "^4.24.15 || ^5.11.2", "react": ">=17.0.0", "react-dom": ">=17.0.0" } @@ -234,11 +238,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -246,28 +251,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -291,39 +296,40 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dependencies": { - "@babel/types": "^7.25.0", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -340,17 +346,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", - "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.0", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -370,39 +376,38 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -412,35 +417,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -450,150 +455,73 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.26.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -603,12 +531,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", - "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", + "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -618,12 +546,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -632,37 +560,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -672,13 +576,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -688,13 +592,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.2.tgz", - "integrity": "sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.9.tgz", + "integrity": "sha512-/VVukELzPDdci7UUsWQaSkhgnjIWXnIyRpM02ldxaVoFK96c41So8JcKT3m0gYjyv7j5FNPGS5vfELrWalkbDA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/plugin-syntax-flow": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-flow": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -704,14 +608,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -721,13 +625,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -737,14 +640,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", - "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -754,13 +656,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -800,16 +702,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", - "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz", + "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -819,14 +721,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.7.tgz", - "integrity": "sha512-NL3Lo0NorCU607zU3NwRyJbpaB6E3t0xtd3LfAQKDfkeX4/ggcDXvkmkW42QWT5owUeW/jAe4hn+2qvkV1IbfQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.25.9.tgz", + "integrity": "sha512-EASHsAhE+SSlEzJ4bzfusnXSHiU+JfAYzj+jbw2vgQKgq5HrUr8qs+vgtiEL5dOH6sEweI+PNt2D7AqrDSHyqQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-flow-strip-types": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-flow-strip-types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -836,16 +738,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -855,9 +757,9 @@ } }, "node_modules/@babel/register": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.24.6.tgz", - "integrity": "sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.25.9.tgz", + "integrity": "sha512-8D43jXtGsYmEeDvm4MWHYUpWf8iiXgWYx3fW7E7Wb7Oe6FWqJPl5K6TuFW0dOwNZzEE5rjlaSJYH9JjrUKJszA==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -874,9 +776,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -885,28 +787,28 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -915,13 +817,12 @@ } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1462,6 +1363,102 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -1560,6 +1557,163 @@ "node": ">= 8" } }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", + "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/@octokit/auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", @@ -1570,16 +1724,16 @@ } }, "node_modules/@octokit/core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", - "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", "dev": true, "dependencies": { "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" }, @@ -1588,12 +1742,12 @@ } }, "node_modules/@octokit/endpoint": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", - "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", "dev": true, "dependencies": { - "@octokit/types": "^12.0.0", + "@octokit/types": "^13.1.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -1601,13 +1755,13 @@ } }, "node_modules/@octokit/graphql": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", "dev": true, "dependencies": { - "@octokit/request": "^8.0.1", - "@octokit/types": "^12.0.0", + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -1615,62 +1769,62 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", - "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==", + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", - "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz", + "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==", "dev": true, "dependencies": { - "@octokit/types": "^12.4.0" + "@octokit/types": "^13.5.0" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": "5" } }, "node_modules/@octokit/plugin-request-log": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", - "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", "dev": true, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": "5" } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", - "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz", + "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==", "dev": true, "dependencies": { - "@octokit/types": "^12.3.0" + "@octokit/types": "^13.5.0" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": "^5" } }, "node_modules/@octokit/request": { - "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", "dev": true, "dependencies": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -1678,12 +1832,12 @@ } }, "node_modules/@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", "dev": true, "dependencies": { - "@octokit/types": "^12.0.0", + "@octokit/types": "^13.1.0", "deprecation": "^2.0.0", "once": "^1.4.0" }, @@ -1692,27 +1846,37 @@ } }, "node_modules/@octokit/rest": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", - "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "version": "20.1.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz", + "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==", "dev": true, "dependencies": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.3.1", "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + "@octokit/plugin-rest-endpoint-methods": "13.2.2" }, "engines": { "node": ">= 18" } }, "node_modules/@octokit/types": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", - "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", "dev": true, "dependencies": { - "@octokit/openapi-types": "^19.1.0" + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" } }, "node_modules/@radix-ui/react-compose-refs": { @@ -1808,11 +1972,11 @@ } }, "node_modules/@rc-component/color-picker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-2.0.0.tgz", - "integrity": "sha512-52z3XqUwUr0+Br3B8RjN2GfuR1Pk3MZPAVd34WptWFEOyTz7OQmmn8nqgXUBOYwZem8jXp6G3iv+6Dm1+1epJA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-2.0.1.tgz", + "integrity": "sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==", "dependencies": { - "@ant-design/fast-color": "^2.0.1", + "@ant-design/fast-color": "^2.0.6", "@babel/runtime": "^7.23.6", "classnames": "^2.2.6", "rc-util": "^5.38.1" @@ -1898,9 +2062,9 @@ } }, "node_modules/@rc-component/tour": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz", - "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.1.tgz", + "integrity": "sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==", "dependencies": { "@babel/runtime": "^7.18.0", "@rc-component/portal": "^1.0.0-9", @@ -1917,9 +2081,9 @@ } }, "node_modules/@rc-component/trigger": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz", - "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.5.tgz", + "integrity": "sha512-F1EJ4KjFpGAHAjuKvOyZB/6IZDkVx0bHl0M4fQM5wXcmm7lgTgVSSnR3bXwdmS6jOJGHOqfDxIJW3WUvwMIXhQ==", "dependencies": { "@babel/runtime": "^7.23.2", "@rc-component/portal": "^1.1.0", @@ -1957,12 +2121,12 @@ "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" }, "node_modules/@refinedev/antd": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@refinedev/antd/-/antd-5.42.0.tgz", - "integrity": "sha512-aKHg5V4widJgW740+4MHp+ngOHfB7KHooAkzOcNN6ngB87qH1Nk2LjyGd5Iza+ooGIKEDlD1rijWFGO/s+Xz2A==", + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/@refinedev/antd/-/antd-5.44.0.tgz", + "integrity": "sha512-uztVPS8vqm//+cjjR+KQLR2ZnEZCFoGfOyIO/ZdGxcyYnwDR09wPgSseHu1spI/oyPayRIkXa5PhFQGylNT6Wg==", "dependencies": { - "@ant-design/icons": "5.0.1", - "@ant-design/pro-layout": "7.17.12", + "@ant-design/icons": "^5.5.1", + "@ant-design/pro-layout": "^7.21.1", "@refinedev/ui-types": "^1.22.9", "@tanstack/react-query": "^4.10.1", "antd": "^5.17.0", @@ -1982,33 +2146,16 @@ "react-dom": "^17.0.0 || ^18.0.0" } }, - "node_modules/@refinedev/antd/node_modules/@ant-design/icons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.0.1.tgz", - "integrity": "sha512-ZyF4ksXCcdtwA/1PLlnFLcF/q8/MhwxXhKHh4oCHDA4Ip+ZzAHoICtyp4wZWfiCVDP0yuz3HsjyvuldHFb3wjA==", - "dependencies": { - "@ant-design/colors": "^7.0.0", - "@ant-design/icons-svg": "^4.2.1", - "@babel/runtime": "^7.11.2", - "classnames": "^2.2.6", - "rc-util": "^5.9.4" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, "node_modules/@refinedev/cli": { - "version": "2.16.36", - "resolved": "https://registry.npmjs.org/@refinedev/cli/-/cli-2.16.36.tgz", - "integrity": "sha512-iky2zLHnXYErN4DbFe5QwyuGla1Dt1jxi/FZg0bAipMOw1WVixUIVl/KphpgbayLRTVQERE1Jz6xmCEvARzRkQ==", + "version": "2.16.39", + "resolved": "https://registry.npmjs.org/@refinedev/cli/-/cli-2.16.39.tgz", + "integrity": "sha512-0XwTeN1iQWTgOPqv9xc8nyNIIlVnbbgLkriBHhQBV4NyaXQdyuL/dRH3eChcKJ0g4QhCC5WoLmQX7HMwaJa6vw==", "dev": true, "dependencies": { - "@refinedev/devtools-server": "1.1.34", + "@npmcli/package-json": "^5.2.0", + "@refinedev/devtools-server": "1.1.37", "boxen": "^5.1.2", + "camelcase": "^6.2.0", "cardinal": "^2.1.1", "center-align": "1.0.1", "chalk": "^4.1.2", @@ -2020,7 +2167,6 @@ "dotenv": "^16.0.3", "envinfo": "^7.8.1", "execa": "^5.1.1", - "express": "^4.18.2", "figlet": "^1.5.2", "fs-extra": "^10.1.0", "globby": "^11.1.0", @@ -2081,11 +2227,11 @@ "dev": true }, "node_modules/@refinedev/core": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@refinedev/core/-/core-4.53.0.tgz", - "integrity": "sha512-Q6qtXWIxNmDCtmbBmyKGEI5S4srR7zlCsR0grYikwnjzUOa/1u9d7kJdmxqCuukmKkDeYkOmVEsanMoGVNPoZA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@refinedev/core/-/core-4.56.0.tgz", + "integrity": "sha512-u5wniUzHyembX803VAmAFLt0Mbd8SMjkKna7noz2hh3d7iZh6C9uzpmWO0Y4ZEdgwoYCJKIYSLeOSV/LdPbIkw==", "dependencies": { - "@refinedev/devtools-internal": "1.1.13", + "@refinedev/devtools-internal": "1.1.14", "@tanstack/react-query": "^4.10.1", "lodash": "^4.17.21", "lodash-es": "^4.17.21", @@ -2104,11 +2250,11 @@ } }, "node_modules/@refinedev/devtools-internal": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@refinedev/devtools-internal/-/devtools-internal-1.1.13.tgz", - "integrity": "sha512-abTS5Qfndvy57DGmf25Igog1yeLhkNlQiDTRiMw70H2iMZaZqTk+x7BaBNO1659Q+cpHrKRbsjRP/yc9mSA6RQ==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@refinedev/devtools-internal/-/devtools-internal-1.1.14.tgz", + "integrity": "sha512-uIIAVA7sLoy0gm49nDGvIFRrJnAW1z8NOSKgYc1HoOBNvOLlnZ8TwPmHF2aJji/iQrwyOH9Z0gLKEvD/qIOPSg==", "dependencies": { - "@refinedev/devtools-shared": "1.1.11", + "@refinedev/devtools-shared": "1.1.12", "@tanstack/react-query": "^4.10.1", "error-stack-parser": "^2.1.4" }, @@ -2123,19 +2269,20 @@ } }, "node_modules/@refinedev/devtools-server": { - "version": "1.1.34", - "resolved": "https://registry.npmjs.org/@refinedev/devtools-server/-/devtools-server-1.1.34.tgz", - "integrity": "sha512-2T0gU1JEGqNmg1S2l5UgSLT316iMGUl7LFj9nJmgHHd20czU5RrG1vLjPDmITPVYwl+p8QEzTBqR9IVxHxEtmg==", + "version": "1.1.37", + "resolved": "https://registry.npmjs.org/@refinedev/devtools-server/-/devtools-server-1.1.37.tgz", + "integrity": "sha512-a61orLFGoGDJ/0Zr12hx2PeDVO4PBKs7kTq/Dp90CLUu1OBXMUHKfLas3QnzKveenYKZHEI+HRMXn7O4UZKIhw==", "dev": true, "dependencies": { - "@refinedev/devtools-shared": "1.1.11", + "@refinedev/devtools-shared": "1.1.12", "body-parser": "^1.20.2", "boxen": "^5.1.2", "chalk": "^4.1.2", "dedent": "^0.7.0", + "dotenv": "^16.0.3", "error-stack-parser": "^2.1.4", "execa": "^5.1.1", - "express": "^4.18.2", + "express": "^4.21.0", "fs-extra": "^10.1.0", "globby": "^11.1.0", "gray-matter": "^4.0.3", @@ -2145,7 +2292,7 @@ "lodash-es": "^4.17.21", "marked": "^4.3.0", "node-fetch": "^2.6.7", - "preferred-pm": "^3.1.3", + "package-manager-detector": "^0.1.1", "react": "^18.0.0", "react-dom": "^18.0.0", "sanitize-html": "^2.11.0", @@ -2165,9 +2312,9 @@ } }, "node_modules/@refinedev/devtools-shared": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@refinedev/devtools-shared/-/devtools-shared-1.1.11.tgz", - "integrity": "sha512-C3v3hnJT5J0d4Uex8DapdpWaVYdUuOovEL/oeQLd4kW2N6ImQCFBYGMfwvi4mDCdorQzGyWSJHmFcfV8EEF+Hg==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@refinedev/devtools-shared/-/devtools-shared-1.1.12.tgz", + "integrity": "sha512-F4fn6KTfETSFqQdP1Zvp4NHfoOUDYxdsx5BQUi0uFRQLm+gE3FfDBl4avyMCeE0xcuChF1qmmEXXrUBCLyj43w==", "dependencies": { "@tanstack/react-query": "^4.10.1", "error-stack-parser": "^2.1.4" @@ -2199,9 +2346,9 @@ } }, "node_modules/@refinedev/react-router-v6": { - "version": "4.5.11", - "resolved": "https://registry.npmjs.org/@refinedev/react-router-v6/-/react-router-v6-4.5.11.tgz", - "integrity": "sha512-VxvRqqwAlrXPTTDWb3KBkriGsG03IUxuZy2bGct9N1P+RmQRvpW8Fk6xn6iaEORE1glY/xa8D4cE05tlkevzvw==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@refinedev/react-router-v6/-/react-router-v6-4.6.0.tgz", + "integrity": "sha512-mybaCanCxclkSPiSeXPeXr6zLNW0LsjxMQG8+/C44h0ud0kZXrHntmV2wQ/louMK3EI5OVDr90oVkkxcprYASA==", "dependencies": { "qs": "^6.10.1", "react-router-dom": "^6.8.1" @@ -2249,21 +2396,21 @@ } }, "node_modules/@remix-run/router": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz", - "integrity": "sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", "engines": { "node": ">=14.0.0" } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -2277,6 +2424,17 @@ } } }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", @@ -2822,9 +2980,9 @@ } }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -2839,9 +2997,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==" + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==" }, "node_modules/@types/mdast": { "version": "3.0.15", @@ -2852,12 +3010,12 @@ } }, "node_modules/@types/node": { - "version": "20.14.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.6.tgz", - "integrity": "sha512-JbA0XIJPL1IiNnU7PFxDXyfAwcwVVrOoqyzzyQTyMeVhBzkJVMSkC1LlVsRQ2lpqiY4n6Bb9oCS6lzDKVQxbZw==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", + "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.8" } }, "node_modules/@types/prop-types": { @@ -2866,18 +3024,18 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "dependencies": { "@types/react": "*" @@ -2894,16 +3052,16 @@ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0.tgz", - "integrity": "sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", + "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/type-utils": "8.0.0", - "@typescript-eslint/utils": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/type-utils": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2927,15 +3085,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.0.tgz", - "integrity": "sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", + "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/typescript-estree": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "debug": "^4.3.4" }, "engines": { @@ -2955,13 +3113,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz", - "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", + "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0" + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2972,13 +3130,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.0.tgz", - "integrity": "sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", + "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.0.0", - "@typescript-eslint/utils": "8.0.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/utils": "8.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2989,6 +3147,9 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -2996,9 +3157,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz", - "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", + "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3009,15 +3170,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz", - "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", + "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", @@ -3061,15 +3222,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz", - "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", + "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/typescript-estree": "8.0.0" + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3080,16 +3241,21 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz", - "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", + "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.0.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.15.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3099,6 +3265,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@umijs/route-utils": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@umijs/route-utils/-/route-utils-4.0.1.tgz", @@ -3113,14 +3291,14 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", - "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", "dev": true, "dependencies": { - "@babel/core": "^7.24.5", - "@babel/plugin-transform-react-jsx-self": "^7.24.5", - "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, @@ -3311,56 +3489,56 @@ "dev": true }, "node_modules/antd": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.20.0.tgz", - "integrity": "sha512-wWCFzbry3hov7k8gqhPR+FzD6EkWlhBbGD9mYOSIDoYRGMRqueTh2+2jfU1voHucmwcxDwzU7iwZDU2+PCXZdA==", + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.22.1.tgz", + "integrity": "sha512-itq8AZwe3IfawZH6SMM5XdbTz1xXGTTqA7sNN0qpEdxcoTpD5nRsCBAMIy+PhwcWFobgFc6ZlF8d7f8eicn0SQ==", "dependencies": { "@ant-design/colors": "^7.1.0", - "@ant-design/cssinjs": "^1.21.0", - "@ant-design/cssinjs-utils": "^1.0.3", - "@ant-design/icons": "^5.4.0", + "@ant-design/cssinjs": "^1.21.1", + "@ant-design/cssinjs-utils": "^1.1.1", + "@ant-design/icons": "^5.5.1", "@ant-design/react-slick": "~1.1.2", - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.7", "@ctrl/tinycolor": "^3.6.1", - "@rc-component/color-picker": "~2.0.0", + "@rc-component/color-picker": "~2.0.1", "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", - "@rc-component/tour": "~1.15.0", - "@rc-component/trigger": "^2.2.0", + "@rc-component/tour": "~1.15.1", + "@rc-component/trigger": "^2.2.5", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", - "rc-cascader": "~3.27.0", + "rc-cascader": "~3.30.0", "rc-checkbox": "~3.3.0", - "rc-collapse": "~3.7.3", - "rc-dialog": "~9.5.2", + "rc-collapse": "~3.9.0", + "rc-dialog": "~9.6.0", "rc-drawer": "~7.2.0", "rc-dropdown": "~4.2.0", - "rc-field-form": "~2.2.1", - "rc-image": "~7.9.0", - "rc-input": "~1.6.2", - "rc-input-number": "~9.2.0", - "rc-mentions": "~2.15.0", - "rc-menu": "~9.14.1", - "rc-motion": "^2.9.2", - "rc-notification": "~5.6.0", - "rc-pagination": "~4.2.0", - "rc-picker": "~4.6.11", + "rc-field-form": "~2.5.0", + "rc-image": "~7.11.0", + "rc-input": "~1.6.3", + "rc-input-number": "~9.3.0", + "rc-mentions": "~2.17.0", + "rc-menu": "~9.16.0", + "rc-motion": "^2.9.3", + "rc-notification": "~5.6.2", + "rc-pagination": "~4.3.0", + "rc-picker": "~4.8.0", "rc-progress": "~4.0.0", "rc-rate": "~2.13.0", "rc-resize-observer": "^1.4.0", - "rc-segmented": "~2.3.0", - "rc-select": "~14.15.1", - "rc-slider": "~11.1.3", + "rc-segmented": "~2.5.0", + "rc-select": "~14.16.3", + "rc-slider": "~11.1.7", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.45.7", - "rc-tabs": "~15.1.1", - "rc-textarea": "~1.8.1", - "rc-tooltip": "~6.2.0", - "rc-tree": "~5.8.8", - "rc-tree-select": "~5.22.1", - "rc-upload": "~4.6.0", + "rc-table": "~7.48.1", + "rc-tabs": "~15.4.0", + "rc-textarea": "~1.8.2", + "rc-tooltip": "~6.2.1", + "rc-tree": "~5.10.1", + "rc-tree-select": "~5.24.4", + "rc-upload": "~4.8.1", "rc-util": "^5.43.0", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.2" @@ -3385,11 +3563,6 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "node_modules/array-tree-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", - "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -3580,9 +3753,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -3598,10 +3771,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -3687,9 +3860,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "funding": [ { "type": "opencollective", @@ -3891,6 +4064,18 @@ "node": ">=6" } }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/clone-deep/node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -4124,11 +4309,11 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4354,6 +4539,12 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4361,9 +4552,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.806", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.806.tgz", - "integrity": "sha512-nkoEX2QIB8kwCOtvtgwhXWy2IHVcOLQZu9Qo36uaGB835mdX/h8uLRlosL6QIhLVUnAiicXRW00PwaPZC74Nrg==" + "version": "1.5.63", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz", + "integrity": "sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -4418,6 +4609,12 @@ "node": ">=4" } }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4492,9 +4689,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -5160,9 +5357,9 @@ "dev": true }, "node_modules/flow-parser": { - "version": "0.242.1", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.242.1.tgz", - "integrity": "sha512-E3ml21Q1S5cMAyPbtYslkvI6yZO5oCS/S2EoteeFH8Kx9iKOv/YOJ+dGd/yMf+H3YKfhMKjnOpyNwrO7NdddWA==", + "version": "0.253.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.253.0.tgz", + "integrity": "sha512-EbxtzRIzp8dDSzTloPhsc6uOvrEFIyu08cqQzXBWLAgxK+i2d/5qOos9ryQHRmk+RyDDXfnz/7qteh3jnAlc4w==", "dev": true, "engines": { "node": ">=0.4.0" @@ -5181,10 +5378,38 @@ "engines": { "node": ">=4.0" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { @@ -5517,6 +5742,24 @@ "react-is": "^16.7.0" } }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/html-parse-stringify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", @@ -5580,17 +5823,17 @@ } }, "node_modules/http-proxy-middleware": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz", - "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", "dev": true, "dependencies": { - "@types/http-proxy": "^1.17.10", - "debug": "^4.3.4", + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.5" + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5606,9 +5849,9 @@ } }, "node_modules/i18next": { - "version": "23.12.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", - "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", + "version": "23.16.6", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.6.tgz", + "integrity": "sha512-wGdE5rUfkZtrL5k6MCptxbpjmgwku4rBRVU/YOJ7Xfd841fgaZjlxHpVJ5NIz8sfSvAJhEhJrvJ8qE7AWXE4Xg==", "funding": [ { "type": "individual", @@ -5636,9 +5879,9 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz", - "integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.6.2.tgz", + "integrity": "sha512-Hp/kd8/VuoxIHmxsknJXjkTYYHzivAyAF15pzliKzk2TiXC25rZCEerb1pUFoxz4IVrG3fCvQSY51/Lu4ECV4A==", "dependencies": { "cross-fetch": "4.0.0" } @@ -5724,6 +5967,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -5917,26 +6169,11 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, "engines": { "node": ">=0.10.0" } @@ -5991,6 +6228,21 @@ "node": ">=0.10.0" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6059,14 +6311,14 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -6246,7 +6498,8 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", @@ -6709,12 +6962,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6782,6 +7035,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -6795,9 +7057,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/mute-stream": { "version": "0.0.8", @@ -6909,9 +7171,74 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, "node_modules/npm-run-path": { "version": "4.0.1", @@ -7082,6 +7409,18 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/package-manager-detector": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.1.2.tgz", + "integrity": "sha512-iePyefLTOm2gEzbaZKSW+eBMjg+UYsQvUKxmvGXAQ987K16efBg10MxIjZs08iyX+DY2/owKY9DIdu193kX33w==", + "dev": true + }, "node_modules/papaparse": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", @@ -7174,10 +7513,35 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/path-to-regexp": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz", - "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==" + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.0.0.tgz", + "integrity": "sha512-GAWaqWlTjYK/7SVpIUA6CTxmcg65SP30sbjdCvyYReosRkk7Z/LyHWwkK3Vu0FcIi0FNTADUs4eh1AsU5s10cg==", + "engines": { + "node": ">=16" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -7196,6 +7560,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -7442,6 +7807,34 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7567,16 +7960,15 @@ } }, "node_modules/rc-cascader": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.27.0.tgz", - "integrity": "sha512-z5uq8VvQadFUBiuZJ7YF5UAUGNkZtdEtcEYiIA94N/Kc2MIKr6lEbN5HyVddvYSgwWlKqnL6pH5bFXFuIK3MNg==", + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.30.0.tgz", + "integrity": "sha512-rrzSbk1Bdqbu+pDwiLCLHu72+lwX9BZ28+JKzoi0DWZ4N29QYFeip8Gctl33QVd2Xg3Rf14D3yAOG76ElJw16w==", "dependencies": { - "@babel/runtime": "^7.12.5", - "array-tree-filter": "^2.1.0", + "@babel/runtime": "^7.25.7", "classnames": "^2.3.1", - "rc-select": "~14.15.0", - "rc-tree": "~5.8.1", - "rc-util": "^5.37.0" + "rc-select": "~14.16.2", + "rc-tree": "~5.10.1", + "rc-util": "^5.43.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -7598,9 +7990,9 @@ } }, "node_modules/rc-collapse": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.3.tgz", - "integrity": "sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.9.0.tgz", + "integrity": "sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -7613,9 +8005,9 @@ } }, "node_modules/rc-dialog": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.5.2.tgz", - "integrity": "sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.6.0.tgz", + "integrity": "sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/portal": "^1.0.0-8", @@ -7660,9 +8052,9 @@ } }, "node_modules/rc-field-form": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz", - "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.5.1.tgz", + "integrity": "sha512-33hunXwynQJyeae7LS3hMGTXNeRBjiPyPYgB0824EbmLHiXC1EBGyUwRh6xjLRy9c+en5WARYN0gJz5+JAqwig==", "dependencies": { "@babel/runtime": "^7.18.0", "@rc-component/async-validator": "^5.0.3", @@ -7677,14 +8069,14 @@ } }, "node_modules/rc-image": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.9.0.tgz", - "integrity": "sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.11.0.tgz", + "integrity": "sha512-aZkTEZXqeqfPZtnSdNUnKQA0N/3MbgR7nUnZ+/4MfSFWPFHZau4p5r5ShaI0KPEMnNjv4kijSCFq/9wtJpwykw==", "dependencies": { "@babel/runtime": "^7.11.2", "@rc-component/portal": "^1.0.2", "classnames": "^2.2.6", - "rc-dialog": "~9.5.2", + "rc-dialog": "~9.6.0", "rc-motion": "^2.6.2", "rc-util": "^5.34.1" }, @@ -7694,9 +8086,9 @@ } }, "node_modules/rc-input": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.6.2.tgz", - "integrity": "sha512-nJqsiIv8K88w8pvbUR5savKqBokdSR0zVGPntLApeOKFp8dp6s92l1CzD60yVActpCZAJwlCfRX5rno+QVYV7g==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.6.3.tgz", + "integrity": "sha512-wI4NzuqBS8vvKr8cljsvnTUqItMfG1QbJoxovCgL+DX4eVUcHIjVwharwevIxyy7H/jbLryh+K7ysnJr23aWIA==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -7708,9 +8100,9 @@ } }, "node_modules/rc-input-number": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.2.0.tgz", - "integrity": "sha512-5XZFhBCV5f9UQ62AZ2hFbEY8iZT/dm23Q1kAg0H8EvOgD3UDbYYJAayoVIkM3lQaCqYAW5gV0yV3vjw1XtzWHg==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.3.0.tgz", + "integrity": "sha512-JQ363ywqRyxwgVxpg2z2kja3CehTpYdqR7emJ/6yJjRdbvo+RvfE83fcpBCIJRq3zLp8SakmEXq60qzWyZ7Usw==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/mini-decimal": "^1.0.1", @@ -7724,15 +8116,15 @@ } }, "node_modules/rc-mentions": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.15.0.tgz", - "integrity": "sha512-f5v5i7VdqvBDXbphoqcQWmXDif2Msd2arritVoWybrVDuHE6nQ7XCYsybHbV//WylooK52BFDouFvyaRDtXZEw==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.17.0.tgz", + "integrity": "sha512-sfHy+qLvc+p8jx8GUsujZWXDOIlIimp6YQz7N5ONQ6bHsa2kyG+BLa5k2wuxgebBbH97is33wxiyq5UkiXRpHA==", "dependencies": { "@babel/runtime": "^7.22.5", "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", "rc-input": "~1.6.0", - "rc-menu": "~9.14.0", + "rc-menu": "~9.16.0", "rc-textarea": "~1.8.0", "rc-util": "^5.34.1" }, @@ -7742,9 +8134,9 @@ } }, "node_modules/rc-menu": { - "version": "9.14.1", - "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.1.tgz", - "integrity": "sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.16.0.tgz", + "integrity": "sha512-vAL0yqPkmXWk3+YKRkmIR8TYj3RVdEt3ptG2jCJXWNAvQbT0VJJdRyHZ7kG/l1JsZlB+VJq/VcYOo69VR4oD+w==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/trigger": "^2.0.0", @@ -7759,9 +8151,9 @@ } }, "node_modules/rc-motion": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.2.tgz", - "integrity": "sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.3.tgz", + "integrity": "sha512-rkW47ABVkic7WEB0EKJqzySpvDqwl60/tdkY7hWP7dYnh5pm0SzJpo54oW3TDUGXV5wfxXFmMkxrzRRbotQ0+w==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -7773,9 +8165,9 @@ } }, "node_modules/rc-notification": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz", - "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.2.tgz", + "integrity": "sha512-Id4IYMoii3zzrG0lB0gD6dPgJx4Iu95Xu0BQrhHIbp7ZnAZbLqdqQ73aIWH0d0UFcElxwaKjnzNovTjo7kXz7g==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -7806,9 +8198,9 @@ } }, "node_modules/rc-pagination": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.2.0.tgz", - "integrity": "sha512-V6qeANJsT6tmOcZ4XiUmj8JXjRLbkusuufpuoBw2GiAn94fIixYjFLmbruD1Sbhn8fPLDnWawPp4CN37zQorvw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.3.0.tgz", + "integrity": "sha512-UubEWA0ShnroQ1tDa291Fzw6kj0iOeF26IsUObxYTpimgj4/qPCWVFl18RLZE+0Up1IZg0IK4pMn6nB3mjvB7g==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.3.2", @@ -7820,9 +8212,9 @@ } }, "node_modules/rc-picker": { - "version": "4.6.11", - "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.6.11.tgz", - "integrity": "sha512-PEVH5MMTUrdvTTxCmPndsXiJL7TFLSu8q0cDdZrhdcjn8en3NbuhOFacWqKTvdnfG53RPPhiBssXCUHYyc3R/Q==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.8.1.tgz", + "integrity": "sha512-lj9hXXMSkbjFUIhfQh8XH698ybxnoBOfq7pdM1FvfSyDwdFhdQa7dvsIYwo6Uz7Zp1wVkfw5rOJO3MpdWzoHsg==", "dependencies": { "@babel/runtime": "^7.24.7", "@rc-component/trigger": "^2.0.0", @@ -7904,9 +8296,9 @@ } }, "node_modules/rc-segmented": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", - "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.5.0.tgz", + "integrity": "sha512-B28Fe3J9iUFOhFJET3RoXAPFJ2u47QvLSYcZWC4tFYNGPEjug5LAxEasZlA/PpAxhdOPqGWsGbSj7ftneukJnw==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -7919,9 +8311,9 @@ } }, "node_modules/rc-select": { - "version": "14.15.1", - "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.15.1.tgz", - "integrity": "sha512-mGvuwW1RMm1NCSI8ZUoRoLRK51R2Nb+QJnmiAvbDRcjh2//ulCkxeV6ZRFTECPpE1t2DPfyqZMPw90SVJzQ7wQ==", + "version": "14.16.3", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.16.3.tgz", + "integrity": "sha512-51+j6s3fJJJXB7E+B6W1hM4Tjzv1B/Decooz9ilgegDBt3ZAth1b/xMwYCTrT5BbG2e53XACQsyDib2+3Ro1fg==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/trigger": "^2.1.1", @@ -7940,9 +8332,9 @@ } }, "node_modules/rc-slider": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-11.1.5.tgz", - "integrity": "sha512-b77H5PbjMKsvkYXAYIkn50QuFX6ICQmCTibDinI9q+BHx65/TV4TeU25+oadhSRzykxs0/vBWeKBwRyySOeWlg==", + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-11.1.7.tgz", + "integrity": "sha512-ytYbZei81TX7otdC0QvoYD72XSlxvTihNth5OeZ6PMXyEDq/vHdWFulQmfDGyXK1NwKwSlKgpvINOa88uT5g2A==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -7988,15 +8380,15 @@ } }, "node_modules/rc-table": { - "version": "7.45.7", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz", - "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==", + "version": "7.48.1", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.48.1.tgz", + "integrity": "sha512-Z4mDKjWg+xz/Ezdw6ivWcbqRpaJ0QfCORRoRrlrw65KSGZLK8OcTdacH22/fyGb8L4It/0/9qcMm8VrVAk/WBw==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", - "rc-util": "^5.37.0", + "rc-util": "^5.41.0", "rc-virtual-list": "^3.14.2" }, "engines": { @@ -8008,14 +8400,14 @@ } }, "node_modules/rc-tabs": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.1.tgz", - "integrity": "sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.4.0.tgz", + "integrity": "sha512-llKuyiAVqmXm2z7OrmhX5cNb2ueZaL8ZyA2P4R+6/72NYYcbEgOXibwHiQCFY2RiN3swXl53SIABi2CumUS02g==", "dependencies": { "@babel/runtime": "^7.11.2", "classnames": "2.x", "rc-dropdown": "~4.2.0", - "rc-menu": "~9.14.0", + "rc-menu": "~9.16.0", "rc-motion": "^2.6.2", "rc-resize-observer": "^1.0.0", "rc-util": "^5.34.1" @@ -8029,9 +8421,9 @@ } }, "node_modules/rc-textarea": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.8.1.tgz", - "integrity": "sha512-bm36N2ZqwZAP60ZQg2OY9mPdqWC+m6UTjHc+CqEZOxb3Ia29BGHazY/s5bI8M4113CkqTzhtFUDNA078ZiOx3Q==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.8.2.tgz", + "integrity": "sha512-UFAezAqltyR00a8Lf0IPAyTd29Jj9ee8wt8DqXyDMal7r/Cg/nDt3e1OOv3Th4W6mKaZijjgwuPXhAfVNTN8sw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.1", @@ -8045,9 +8437,9 @@ } }, "node_modules/rc-tooltip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", - "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.1.tgz", + "integrity": "sha512-rws0duD/3sHHsD905Nex7FvoUGy2UBQRhTkKxeEvr2FB+r21HsOxcDJI0TzyO8NHhnAA8ILr8pfbSBg5Jj5KBg==", "dependencies": { "@babel/runtime": "^7.11.2", "@rc-component/trigger": "^2.0.0", @@ -8059,9 +8451,9 @@ } }, "node_modules/rc-tree": { - "version": "5.8.8", - "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.8.tgz", - "integrity": "sha512-S+mCMWo91m5AJqjz3PdzKilGgbFm7fFJRFiTDOcoRbD7UfMOPnerXwMworiga0O2XIo383UoWuEfeHs1WOltag==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.10.1.tgz", + "integrity": "sha512-FPXb3tT/u39mgjr6JNlHaUTYfHkVGW56XaGDahDpEFLGsnPxGcVLNTjcqoQb/GNbSCycl7tD7EvIymwOTP0+Yw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -8078,15 +8470,15 @@ } }, "node_modules/rc-tree-select": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.22.1.tgz", - "integrity": "sha512-b8mAK52xEpRgS+b2PTapCt29GoIrO5cO8jB7AfHttFsIJfcnynY9FCtnYzURsKXJkGHbFY6UzSEB2I3TETtdWg==", + "version": "5.24.4", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.24.4.tgz", + "integrity": "sha512-MzljkSkk7weKOcE853UtYlXB6uyUEzcEQhhpaCwE6jQPbmBUgGiRURuKWpYUnM/dXrwTTlCK969M6Pgjj35MLA==", "dependencies": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.25.7", "classnames": "2.x", - "rc-select": "~14.15.0", - "rc-tree": "~5.8.1", - "rc-util": "^5.16.1" + "rc-select": "~14.16.2", + "rc-tree": "~5.10.1", + "rc-util": "^5.43.0" }, "peerDependencies": { "react": "*", @@ -8094,9 +8486,9 @@ } }, "node_modules/rc-upload": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.6.0.tgz", - "integrity": "sha512-Zr0DT1NHw/ApxrP7UAoxOtGaVYuzarrrCVr0ld7RiEFsKX07uFhE1EpCBxwL11ruFn89GMcshOKWp+s6FLyAlA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.8.1.tgz", + "integrity": "sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==", "dependencies": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.5", @@ -8126,9 +8518,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/rc-virtual-list": { - "version": "3.14.3", - "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.3.tgz", - "integrity": "sha512-6+6wiEhdqakNBnbRJymgMlh+90qpkgqherTRo1l1cX7mK6F9hWsazPczmP0lA+64yhC9/t+M9Dh5pjvDWimn8A==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.15.0.tgz", + "integrity": "sha512-dF2YQztqrU3ijAeWOqscTshCEr7vpimzSqAVjO1AyAmaqcHulaXpnGR0ptK5PXfxTUy48VkJOiglMIxlkYGs0w==", "dependencies": { "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", @@ -8204,11 +8596,11 @@ } }, "node_modules/react-i18next": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz", - "integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.1.tgz", + "integrity": "sha512-R/Vg9wIli2P3FfeI8o1eNJUJue5LWpFsQePCHdQDmX0Co3zkr6kdT8gAseb/yGeWbNz1Txc4bKDQuZYsC0kQfw==", "dependencies": { - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.0", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { @@ -8272,11 +8664,11 @@ } }, "node_modules/react-router": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.0.tgz", - "integrity": "sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", "dependencies": { - "@remix-run/router": "1.19.0" + "@remix-run/router": "1.21.0" }, "engines": { "node": ">=14.0.0" @@ -8286,12 +8678,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.0.tgz", - "integrity": "sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", "dependencies": { - "@remix-run/router": "1.19.0", - "react-router": "6.26.0" + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" }, "engines": { "node": ">=14.0.0" @@ -8467,6 +8859,15 @@ "node": ">=8" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8586,9 +8987,9 @@ ] }, "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "engines": { "node": ">=10" } @@ -8600,9 +9001,9 @@ "dev": true }, "node_modules/sanitize-html": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.13.0.tgz", - "integrity": "sha512-Xff91Z+4Mz5QiNSLdLWwjgBDm5b1RU6xBT0+12rapjiaR7SwfRdjw8f+6Rir2MXKLrDicRFHdb51hGOAxmsUIA==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.13.1.tgz", + "integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==", "dev": true, "dependencies": { "deepmerge": "^4.2.2", @@ -8613,15 +9014,6 @@ "postcss": "^8.3.11" } }, - "node_modules/sanitize-html/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -8741,12 +9133,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -8916,6 +9302,38 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, "node_modules/split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", @@ -8980,6 +9398,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8992,6 +9425,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -9040,9 +9486,9 @@ } }, "node_modules/stylis": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz", - "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==" + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" }, "node_modules/sunflower-antd": { "version": "1.0.0-beta.3", @@ -9095,9 +9541,9 @@ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, "node_modules/swr": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.4.tgz", - "integrity": "sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", "dependencies": { "client-only": "^0.0.1", "use-sync-external-store": "^1.2.0" @@ -9156,14 +9602,6 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9267,9 +9705,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -9293,9 +9731,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unicode-emoji-modifier-base": { @@ -9454,9 +9892,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -9472,8 +9910,8 @@ } ], "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -9515,15 +9953,34 @@ } }, "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/vary": { @@ -9586,9 +10043,9 @@ } }, "node_modules/vite": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", - "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "dependencies": { "esbuild": "^0.21.3", @@ -9645,15 +10102,15 @@ } }, "node_modules/vite-plugin-mkcert": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.5.tgz", - "integrity": "sha512-KKGY3iHx/9zb7ow8JJ+nLN2HiNIBuPBwj34fJ+jAJT89/8qfk7msO7G7qipR8VDEm9xMCys0xT11QOJbZcg3/Q==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.6.tgz", + "integrity": "sha512-4JR1RN0HEg/w17eRQJ/Ve2pSa6KCVQcQO6yKtIaKQCFDyd63zGfXHWpygBkvvRSpqa0GcqNKf0fjUJ0HiJQXVQ==", "dev": true, "dependencies": { - "@octokit/rest": "^20.0.2", - "axios": "^1.6.8", - "debug": "^4.3.4", - "picocolors": "^1.0.0" + "@octokit/rest": "^20.1.1", + "axios": "^1.7.4", + "debug": "^4.3.6", + "picocolors": "^1.0.1" }, "engines": { "node": ">=v16.7.0" @@ -9663,16 +10120,16 @@ } }, "node_modules/vite-plugin-svgr": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", - "integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz", + "integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==", "dependencies": { - "@rollup/pluginutils": "^5.0.5", + "@rollup/pluginutils": "^5.1.3", "@svgr/core": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0" }, "peerDependencies": { - "vite": "^2.6.0 || 3 || 4 || 5" + "vite": ">=2.6.0" } }, "node_modules/void-elements": { @@ -9782,6 +10239,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/client/package.json b/client/package.json index 38f8c3ab..d333a91e 100644 --- a/client/package.json +++ b/client/package.json @@ -7,51 +7,51 @@ "private": true, "type": "module", "dependencies": { - "@ant-design/icons": "^5.4.0", + "@ant-design/icons": "^5.5.1", "@loadable/component": "^5.16.4", - "@refinedev/antd": "^5.42.0", - "@refinedev/core": "^4.53.0", + "@refinedev/antd": "^5.44.0", + "@refinedev/core": "^4.56.0", "@refinedev/kbar": "^1.3.12", - "@refinedev/react-router-v6": "^4.5.11", + "@refinedev/react-router-v6": "^4.6.0", "@refinedev/simple-rest": "^5.0.8", "@tanstack/react-query": "^4.36.1", "@tanstack/react-query-devtools": "^4.36.1", "@types/loadable__component": "^5.13.9", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.13", "@types/uuid": "^10.0.0", "@yudiel/react-qr-scanner": "^1.2.10", - "antd": "^5.20.0", + "antd": "^5.22.1", "axios": "^1.7.7", "flag-icons": "^7.2.3", "html-to-image": "^1.11.11", - "i18next": "^23.12.2", + "i18next": "^23.16.6", "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.5.2", + "i18next-http-backend": "^2.6.2", "lodash": "^4.17.21", "react": "^18.3.1", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", - "react-i18next": "^15.0.0", - "react-router-dom": "^6.26.0", + "react-i18next": "^15.1.1", + "react-router-dom": "^6.28.0", "react-to-print": "^2.15.1", - "uuid": "^10.0.0", - "vite-plugin-svgr": "^4.2.0" + "uuid": "^11.0.3", + "vite-plugin-svgr": "^4.3.0" }, "devDependencies": { - "@refinedev/cli": "^2.16.36", - "@types/node": "^20.14.6", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "@vitejs/plugin-react": "^4.3.1", + "@refinedev/cli": "^2.16.39", + "@types/node": "^22.9.1", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@typescript-eslint/eslint-plugin": "^8.15.0", + "@typescript-eslint/parser": "^8.15.0", + "@vitejs/plugin-react": "^4.3.3", "eslint": "^9.8.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", - "typescript": "^5.5.4", - "vite": "^5.4.6", - "vite-plugin-mkcert": "^1.17.5" + "typescript": "^5.6.3", + "vite": "^5.4.11", + "vite-plugin-mkcert": "^1.17.6" }, "scripts": { "dev": "refine dev", From 1eca7b2503240b78b9d7930e7b06be5f9894ef2e Mon Sep 17 00:00:00 2001 From: Donkie Date: Tue, 19 Nov 2024 22:04:06 +0100 Subject: [PATCH 03/16] Added buttons to view/edit spools on locations page --- client/src/pages/locations/index.tsx | 27 ++++++++++++++++++++---- client/src/pages/locations/locations.css | 8 +++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index c628df7a..e2cd8624 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -1,11 +1,13 @@ -import { IResourceComponentsProps, useInvalidate, useList, useTranslate } from "@refinedev/core"; -import { theme } from "antd"; +import { IResourceComponentsProps, useInvalidate, useList, useNavigation, useTranslate } from "@refinedev/core"; +import { Button, theme } from "antd"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; import React from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; +import { EditOutlined, EyeOutlined } from "@ant-design/icons"; +import { Link } from "react-router-dom"; import SpoolIcon from "../../components/spoolIcon"; import { ISpool } from "../spools/model"; import { setSpoolLocation } from "./functions"; @@ -17,6 +19,7 @@ const { useToken } = theme; function SpoolCard({ spool }: { spool: ISpool }) { const { token } = useToken(); + const t = useTranslate(); const [{ opacity }, dragRef] = useDrag( () => ({ type: "spool", @@ -27,6 +30,7 @@ function SpoolCard({ spool }: { spool: ISpool }) { }), [] ); + const { editUrl, showUrl } = useNavigation(); const colorObj = spool.filament.multi_color_hexes ? { @@ -52,9 +56,24 @@ function SpoolCard({ spool }: { spool: ISpool }) {
- #{spool.id} {filament_name} + + #{spool.id} {filament_name} + +
+ +
-
+
{spool.remaining_weight} / {spool.filament.weight} g
diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css index 76abccc9..9723a399 100644 --- a/client/src/pages/locations/locations.css +++ b/client/src/pages/locations/locations.css @@ -5,7 +5,7 @@ .loc-container { padding: 1em; - width: 20em; + width: 24em; } .loc-container .loc-spools { @@ -28,11 +28,15 @@ .loc-container .spool .info { display: flex; flex-direction: column; - gap: 0.5em; + width: 100%; } .loc-container .spool .info .title { font-size: 1em; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; } .loc-container .spool .info .subtitle { From e4175e26ec9740b54139eb10b5832d93a9a5e280 Mon Sep 17 00:00:00 2001 From: Donkie Date: Tue, 19 Nov 2024 22:32:05 +0100 Subject: [PATCH 04/16] Added a locations setting so empty locations are still kept around --- client/src/pages/locations/index.tsx | 91 ++++++++++++++++++------ client/src/pages/locations/locations.css | 1 + spoolman/settings.py | 2 + 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index e2cd8624..12149efb 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -2,13 +2,14 @@ import { IResourceComponentsProps, useInvalidate, useList, useNavigation, useTra import { Button, theme } from "antd"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; -import React from "react"; +import React, { useEffect, useMemo } from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { EditOutlined, EyeOutlined } from "@ant-design/icons"; import { Link } from "react-router-dom"; import SpoolIcon from "../../components/spoolIcon"; +import { useGetSetting, useSetSetting } from "../../utils/querySettings"; import { ISpool } from "../spools/model"; import { setSpoolLocation } from "./functions"; import "./locations.css"; @@ -115,9 +116,27 @@ function LocationContainer({ title, spools }: { title: string; spools: ISpool[] ); } +function useLocations(): string[] { + const query = useGetSetting("locations"); + + return useMemo(() => { + if (!query.data) return []; + + try { + return JSON.parse(query.data.value) as string[]; + } catch { + console.warn("Failed to parse locations", query.data.value); + return []; + } + }, [query.data]); +} + export const Locations: React.FC = () => { const t = useTranslate(); + const settingsLocations = useLocations(); + const setLocationsSetting = useSetSetting("locations"); + const { data, isLoading, isError } = useList({ resource: "spool", meta: { @@ -130,36 +149,62 @@ export const Locations: React.FC = () => { }, }); - if (isLoading) { - return
Loading...
; - } - - if (isError) { - return
Failed to load spools
; - } - + // Grab spools and sort by ID const spools = data?.data ?? []; spools.sort((a, b) => a.id - b.id); - // Locations is all the unique locations of the spools - const spoolLocations: Record = {}; - spools.forEach((spool) => { - const loc = spool.location ?? t("spool.no_location"); - if (!spoolLocations[loc]) { - spoolLocations[loc] = []; - } - spoolLocations[loc].push(spool); - }); + // Group spools by location + const spoolLocations = useMemo(() => { + const grouped: Record = {}; + spools.forEach((spool) => { + const loc = spool.location ?? t("spool.no_location"); + if (!grouped[loc]) { + grouped[loc] = []; + } + grouped[loc].push(spool); + }); + return grouped; + }, [spools]); - const locationsList = Object.keys(spoolLocations); - locationsList.sort((a, b) => { - return a.localeCompare(b); - }); + // Create list of locations that's sorted + const locationsList = useMemo(() => { + // Start with the locations from the spools + let allLocs = [...Object.keys(spoolLocations), ...settingsLocations]; + + // Remove duplicates + allLocs = [...new Set(allLocs)]; + + allLocs.sort((a, b) => { + // Sort alphabetically + return a.localeCompare(b); + }); + return allLocs; + }, [spoolLocations, settingsLocations]); + + // Create containers const containers = locationsList.map((loc) => { - return ; + return ; }); + // Update locations settings so it always includes all spool locations + useEffect(() => { + // Check if they're not the same + if (JSON.stringify(locationsList.sort()) !== JSON.stringify(settingsLocations.sort())) { + console.log("Updating locations settings", locationsList, settingsLocations); + // Update settings + setLocationsSetting.mutate(locationsList); + } + }, [spoolLocations]); + + if (isLoading) { + return
Loading...
; + } + + if (isError) { + return
Failed to load spools
; + } + return (
{containers}
diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css index 9723a399..76b1cf2b 100644 --- a/client/src/pages/locations/locations.css +++ b/client/src/pages/locations/locations.css @@ -13,6 +13,7 @@ display: flex; flex-direction: column; gap: 0.5em; + min-height: 3em; max-height: 100em; overflow-y: scroll; } diff --git a/spoolman/settings.py b/spoolman/settings.py index ccd3ad55..bb7217c8 100644 --- a/spoolman/settings.py +++ b/spoolman/settings.py @@ -68,3 +68,5 @@ def parse_setting(key: str) -> SettingDefinition: register_setting("extra_fields_filament", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_spool", SettingType.ARRAY, json.dumps([])) register_setting("base_url", SettingType.STRING, json.dumps("")) + +register_setting("locations", SettingType.ARRAY, json.dumps([])) From 3dc0082f0e6bbe49f7c7215f903d04d4d2c0e1c4 Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 19:37:56 +0100 Subject: [PATCH 05/16] Added ability to add new location --- client/src/pages/locations/index.tsx | 71 ++++++++++++++++++------ client/src/pages/locations/locations.css | 7 +++ 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index 12149efb..818c5400 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -6,7 +6,7 @@ import React, { useEffect, useMemo } from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; -import { EditOutlined, EyeOutlined } from "@ant-design/icons"; +import { DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined } from "@ant-design/icons"; import { Link } from "react-router-dom"; import SpoolIcon from "../../components/spoolIcon"; import { useGetSetting, useSetSetting } from "../../utils/querySettings"; @@ -82,7 +82,17 @@ function SpoolCard({ spool }: { spool: ISpool }) { ); } -function LocationContainer({ title, spools }: { title: string; spools: ISpool[] }) { +function LocationContainer({ + title, + spools, + showDelete, + onDelete, +}: { + title: string; + spools: ISpool[]; + showDelete?: boolean; + onDelete?: () => void; +}) { const { token } = useToken(); const invalidate = useInvalidate(); @@ -106,7 +116,10 @@ function LocationContainer({ title, spools }: { title: string; spools: ISpool[] return (
-

{title}

+

+ {title} + {showDelete &&

{spools.map((spool) => ( @@ -168,31 +181,41 @@ export const Locations: React.FC = () => { // Create list of locations that's sorted const locationsList = useMemo(() => { - // Start with the locations from the spools - let allLocs = [...Object.keys(spoolLocations), ...settingsLocations]; - - // Remove duplicates - allLocs = [...new Set(allLocs)]; - - allLocs.sort((a, b) => { - // Sort alphabetically - return a.localeCompare(b); - }); + // Start with the locations setting + let allLocs = settingsLocations; + console.log("settingsLocations", settingsLocations); + + // Add any missing locations from the spools + for (const loc of Object.keys(spoolLocations)) { + if (!allLocs.includes(loc)) { + allLocs.push(loc); + } + } return allLocs; }, [spoolLocations, settingsLocations]); // Create containers const containers = locationsList.map((loc) => { - return ; + const spools = spoolLocations[loc] ?? []; + return ( + { + setLocationsSetting.mutate(locationsList.filter((l) => l !== loc)); + }} + /> + ); }); // Update locations settings so it always includes all spool locations useEffect(() => { // Check if they're not the same - if (JSON.stringify(locationsList.sort()) !== JSON.stringify(settingsLocations.sort())) { + if (JSON.stringify(locationsList) !== JSON.stringify(settingsLocations)) { console.log("Updating locations settings", locationsList, settingsLocations); - // Update settings setLocationsSetting.mutate(locationsList); } }, [spoolLocations]); @@ -207,7 +230,21 @@ export const Locations: React.FC = () => { return ( -
{containers}
+
+ {containers} +
+
+
); }; diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css index 76b1cf2b..391d09bb 100644 --- a/client/src/pages/locations/locations.css +++ b/client/src/pages/locations/locations.css @@ -8,6 +8,13 @@ width: 24em; } +.loc-container h3 { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; +} + .loc-container .loc-spools { padding: 0.2em; display: flex; From 8d6f2636c5810c40b7cd03d7d748e2478318f53d Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 20:12:08 +0100 Subject: [PATCH 06/16] Locations can now be drag-dropped around --- client/src/pages/locations/functions.ts | 17 ++ client/src/pages/locations/index.tsx | 197 +++++++++++++++++------- 2 files changed, 157 insertions(+), 57 deletions(-) diff --git a/client/src/pages/locations/functions.ts b/client/src/pages/locations/functions.ts index 4bb91af3..a5004006 100644 --- a/client/src/pages/locations/functions.ts +++ b/client/src/pages/locations/functions.ts @@ -1,3 +1,5 @@ +import { useMemo } from "react"; +import { useGetSetting } from "../../utils/querySettings"; import { getAPIURL } from "../../utils/url"; import { ISpool } from "../spools/model"; @@ -16,3 +18,18 @@ export async function setSpoolLocation(spool_id: number, location: string | null } return response.json(); } + +export function useLocations(): string[] { + const query = useGetSetting("locations"); + + return useMemo(() => { + if (!query.data) return []; + + try { + return JSON.parse(query.data.value) as string[]; + } catch { + console.warn("Failed to parse locations", query.data.value); + return []; + } + }, [query.data]); +} diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index 818c5400..7083d7e1 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -2,20 +2,26 @@ import { IResourceComponentsProps, useInvalidate, useList, useNavigation, useTra import { Button, theme } from "antd"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; -import React, { useEffect, useMemo } from "react"; +import type { Identifier, XYCoord } from "dnd-core"; +import React, { useEffect, useMemo, useRef } from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined } from "@ant-design/icons"; import { Link } from "react-router-dom"; import SpoolIcon from "../../components/spoolIcon"; -import { useGetSetting, useSetSetting } from "../../utils/querySettings"; +import { useSetSetting } from "../../utils/querySettings"; import { ISpool } from "../spools/model"; -import { setSpoolLocation } from "./functions"; +import { setSpoolLocation, useLocations } from "./functions"; import "./locations.css"; dayjs.extend(utc); +const ItemTypes = { + SPOOL: "spool", + CONTAINER: "spool-container", +}; + const { useToken } = theme; function SpoolCard({ spool }: { spool: ISpool }) { @@ -23,7 +29,7 @@ function SpoolCard({ spool }: { spool: ISpool }) { const t = useTranslate(); const [{ opacity }, dragRef] = useDrag( () => ({ - type: "spool", + type: ItemTypes.SPOOL, item: spool, collect: (monitor) => ({ opacity: monitor.isDragging() ? 0.5 : 1, @@ -82,24 +88,13 @@ function SpoolCard({ spool }: { spool: ISpool }) { ); } -function LocationContainer({ - title, - spools, - showDelete, - onDelete, -}: { - title: string; - spools: ISpool[]; - showDelete?: boolean; - onDelete?: () => void; -}) { +function SpoolList({ location, spools }: { location: string; spools: ISpool[] }) { const { token } = useToken(); const invalidate = useInvalidate(); - - const [, drop] = useDrop(() => ({ - accept: "spool", + const [, spoolDrop] = useDrop(() => ({ + accept: ItemTypes.SPOOL, drop: (item: ISpool) => { - setSpoolLocation(item.id, title).then(() => { + setSpoolLocation(item.id, location).then(() => { invalidate({ resource: "spool", id: item.id, @@ -115,36 +110,108 @@ function LocationContainer({ }; return ( -
-

- {title} - {showDelete &&

-
- {spools.map((spool) => ( - - ))} -
+
+ {spools.map((spool) => ( + + ))}
); } -function useLocations(): string[] { - const query = useGetSetting("locations"); +interface DragItem { + index: number; + title: string; +} - return useMemo(() => { - if (!query.data) return []; +function LocationContainer({ + index, + title, + spools, + showDelete, + onDelete, + moveLocation, +}: { + index: number; + title: string; + spools: ISpool[]; + showDelete?: boolean; + onDelete?: () => void; + moveLocation: (dragIndex: number, hoverIndex: number) => void; +}) { + const ref = useRef(null); + const [{ handlerId }, drop] = useDrop({ + accept: ItemTypes.CONTAINER, + collect(monitor) { + return { + handlerId: monitor.getHandlerId(), + }; + }, + hover(item, monitor) { + if (!ref.current) { + return null; + } + const dragIndex = item.index; + const hoverIndex = index; - try { - return JSON.parse(query.data.value) as string[]; - } catch { - console.warn("Failed to parse locations", query.data.value); - return []; - } - }, [query.data]); + // Don't replace items with themselves + if (dragIndex === hoverIndex) { + return; + } + + // Determine rectangle on screen + const hoverBoundingRect = ref.current?.getBoundingClientRect(); + + // Get horizontal middle + const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2; + + // Determine mouse position + const clientOffset = monitor.getClientOffset(); + + // Get pixels to the left + const hoverClientX = (clientOffset as XYCoord).x - hoverBoundingRect.left; + + // Dragging downwards + if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) { + return; + } + + // Dragging upwards + if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) { + return; + } + + // Time to actually perform the action + moveLocation(dragIndex, hoverIndex); + + item.index = hoverIndex; + }, + }); + + const [{ isDragging }, drag] = useDrag({ + type: ItemTypes.CONTAINER, + item: () => { + return { title, index }; + }, + collect: (monitor: any) => ({ + isDragging: monitor.isDragging(), + }), + }); + + const opacity = isDragging ? 0 : 1; + drag(drop(ref)); + + return ( +
+

+ {title} + {showDelete &&

+ +
+ ); } -export const Locations: React.FC = () => { +function LocationMetaContainer() { const t = useTranslate(); const settingsLocations = useLocations(); @@ -195,18 +262,28 @@ export const Locations: React.FC = () => { return allLocs; }, [spoolLocations, settingsLocations]); + const moveLocation = (dragIndex: number, hoverIndex: number) => { + const newLocs = [...locationsList]; + newLocs.splice(dragIndex, 1); + newLocs.splice(hoverIndex, 0, locationsList[dragIndex]); + console.log("newLocs", newLocs); + setLocationsSetting.mutate(newLocs); + }; + // Create containers - const containers = locationsList.map((loc) => { + const containers = locationsList.map((loc, idx) => { const spools = spoolLocations[loc] ?? []; return ( { setLocationsSetting.mutate(locationsList.filter((l) => l !== loc)); }} + moveLocation={moveLocation} /> ); }); @@ -229,22 +306,28 @@ export const Locations: React.FC = () => { } return ( - -
- {containers} -
-
+
+ {containers} +
+
+
+ ); +} + +export const Locations: React.FC = () => { + return ( + + ); }; From 58611908218c474e40bdced6ddb9eca51269369d Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 20:15:46 +0100 Subject: [PATCH 07/16] Fixed being able to create multiple locs of same name --- client/src/pages/locations/index.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index 7083d7e1..e8c61ba3 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -305,6 +305,20 @@ function LocationMetaContainer() { return
Failed to load spools
; } + const addNewLocation = () => { + let newLocationName = "New Location"; + + const newLocs = [...locationsList]; + let i = 1; + while (newLocs.includes(newLocationName)) { + newLocationName = "New Location " + i; + i++; + } + newLocs.push(newLocationName); + + setLocationsSetting.mutate(newLocs); + }; + return (
{containers} @@ -317,7 +331,7 @@ function LocationMetaContainer() { style={{ margin: "1em", }} - onClick={() => setLocationsSetting.mutate([...settingsLocations, "New Location"])} + onClick={addNewLocation} />
From 37b6d1fcee7708cf2900ee53135681b8001afc4c Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 21:00:39 +0100 Subject: [PATCH 08/16] Added ability to rename location --- client/src/pages/locations/functions.ts | 16 +++++++ client/src/pages/locations/index.tsx | 55 +++++++++++++++++++++--- client/src/pages/locations/locations.css | 2 + spoolman/api/v1/other.py | 23 ++++++++++ spoolman/database/spool.py | 12 ++++++ 5 files changed, 103 insertions(+), 5 deletions(-) diff --git a/client/src/pages/locations/functions.ts b/client/src/pages/locations/functions.ts index a5004006..0091efc8 100644 --- a/client/src/pages/locations/functions.ts +++ b/client/src/pages/locations/functions.ts @@ -33,3 +33,19 @@ export function useLocations(): string[] { } }, [query.data]); } + +export async function renameSpoolLocation(location: string, newName: string): Promise { + const response = await fetch(getAPIURL() + "/location/" + location, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: newName, + }), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + return await response.text(); +} diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index e8c61ba3..50be7f42 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -1,9 +1,9 @@ import { IResourceComponentsProps, useInvalidate, useList, useNavigation, useTranslate } from "@refinedev/core"; -import { Button, theme } from "antd"; +import { Button, Input, theme } from "antd"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; import type { Identifier, XYCoord } from "dnd-core"; -import React, { useEffect, useMemo, useRef } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; @@ -12,7 +12,7 @@ import { Link } from "react-router-dom"; import SpoolIcon from "../../components/spoolIcon"; import { useSetSetting } from "../../utils/querySettings"; import { ISpool } from "../spools/model"; -import { setSpoolLocation, useLocations } from "./functions"; +import { renameSpoolLocation, setSpoolLocation, useLocations } from "./functions"; import "./locations.css"; dayjs.extend(utc); @@ -130,6 +130,7 @@ function LocationContainer({ showDelete, onDelete, moveLocation, + onEditTitle, }: { index: number; title: string; @@ -137,7 +138,11 @@ function LocationContainer({ showDelete?: boolean; onDelete?: () => void; moveLocation: (dragIndex: number, hoverIndex: number) => void; + onEditTitle: (newTitle: string) => void; }) { + const [editTitle, setEditTitle] = useState(false); + const [newTitle, setNewTitle] = useState(title); + const ref = useRef(null); const [{ handlerId }, drop] = useDrop({ accept: ItemTypes.CONTAINER, @@ -189,6 +194,7 @@ function LocationContainer({ const [{ isDragging }, drag] = useDrag({ type: ItemTypes.CONTAINER, + canDrag: !editTitle, item: () => { return { title, index }; }, @@ -203,7 +209,28 @@ function LocationContainer({ return (

- {title} + {editTitle ? ( + setEditTitle(false)} + onChange={(e) => setNewTitle(e.target.value)} + onPressEnter={() => { + setEditTitle(false); + return onEditTitle(newTitle); + }} + /> + ) : ( + { + setNewTitle(title); + setEditTitle(true); + }} + > + {title} + + )} {showDelete &&

@@ -213,6 +240,7 @@ function LocationContainer({ function LocationMetaContainer() { const t = useTranslate(); + const invalidate = useInvalidate(); const settingsLocations = useLocations(); const setLocationsSetting = useSetSetting("locations"); @@ -266,7 +294,23 @@ function LocationMetaContainer() { const newLocs = [...locationsList]; newLocs.splice(dragIndex, 1); newLocs.splice(hoverIndex, 0, locationsList[dragIndex]); - console.log("newLocs", newLocs); + setLocationsSetting.mutate(newLocs); + }; + + const onEditTitle = async (location: string, newTitle: string) => { + if (newTitle == location) return; + if (newTitle == "") return; + if (locationsList.includes(newTitle)) return; + + // Update all spool locations in the database + if (spoolLocations[location] && spoolLocations[location].length > 0) { + await renameSpoolLocation(location, newTitle); + await invalidate({ resource: "spool", invalidates: ["list", "detail"] }); + } + + // Update the value in the settings + const newLocs = [...locationsList]; + newLocs[locationsList.indexOf(location)] = newTitle; setLocationsSetting.mutate(newLocs); }; @@ -284,6 +328,7 @@ function LocationMetaContainer() { setLocationsSetting.mutate(locationsList.filter((l) => l !== loc)); }} moveLocation={moveLocation} + onEditTitle={(newTitle: string) => onEditTitle(loc, newTitle)} /> ); }); diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css index 391d09bb..90bef7b7 100644 --- a/client/src/pages/locations/locations.css +++ b/client/src/pages/locations/locations.css @@ -6,6 +6,7 @@ .loc-container { padding: 1em; width: 24em; + cursor: pointer; } .loc-container h3 { @@ -13,6 +14,7 @@ align-items: center; justify-content: space-between; width: 100%; + cursor: text; } .loc-container .loc-spools { diff --git a/spoolman/api/v1/other.py b/spoolman/api/v1/other.py index 345ea609..14f7128d 100644 --- a/spoolman/api/v1/other.py +++ b/spoolman/api/v1/other.py @@ -4,6 +4,7 @@ from typing import Annotated from fastapi import APIRouter, Depends +from pydantic import BaseModel, Field, RootModel from sqlalchemy.ext.asyncio import AsyncSession from spoolman.database import filament, spool @@ -123,3 +124,25 @@ async def find_locations( db: Annotated[AsyncSession, Depends(get_db_session)], ) -> list[str]: return await spool.find_locations(db=db) + + +class RenameLocationBody(BaseModel): + name: str = Field(description="The new name of the location.", min_length=1) + + +@router.patch( + "/location/{location}", + name="Rename location", + description="Rename a spool location. All spools in this location will be moved to the new location.", + response_model_exclude_none=True, + response_model=RootModel[str], +) +async def rename_location( + location: str, + *, + db: Annotated[AsyncSession, Depends(get_db_session)], + body: RenameLocationBody, +) -> str: + logger.info("Renaming location %s to %s", location, body.name) + await spool.rename_location(db=db, current_name=location, new_name=body.name) + return body.name diff --git a/spoolman/database/spool.py b/spoolman/database/spool.py index 254a85e3..2f60fdc4 100644 --- a/spoolman/database/spool.py +++ b/spoolman/database/spool.py @@ -462,3 +462,15 @@ async def reset_initial_weight(db: AsyncSession, spool_id: int, weight: float) - await db.commit() await spool_changed(spool, EventType.UPDATED) return spool + + +async def rename_location( + *, + db: AsyncSession, + current_name: str, + new_name: str, +) -> None: + """Rename all spools with the current location name to the new name.""" + await db.execute( + sqlalchemy.update(models.Spool).where(models.Spool.location == current_name).values(location=new_name), + ) From ce42d687ed91d2d50026ddfca2053f038187f7b9 Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 21:08:43 +0100 Subject: [PATCH 09/16] Some file rearranging --- .../pages/locations/components/location.tsx | 129 ++++++ .../components/locationContainer.tsx | 153 +++++++ .../pages/locations/components/spoolCard.tsx | 75 ++++ .../pages/locations/components/spoolList.tsx | 40 ++ client/src/pages/locations/index.tsx | 383 +----------------- client/src/pages/locations/itemTypes.ts | 4 + 6 files changed, 406 insertions(+), 378 deletions(-) create mode 100644 client/src/pages/locations/components/location.tsx create mode 100644 client/src/pages/locations/components/locationContainer.tsx create mode 100644 client/src/pages/locations/components/spoolCard.tsx create mode 100644 client/src/pages/locations/components/spoolList.tsx create mode 100644 client/src/pages/locations/itemTypes.ts diff --git a/client/src/pages/locations/components/location.tsx b/client/src/pages/locations/components/location.tsx new file mode 100644 index 00000000..eaa8dea4 --- /dev/null +++ b/client/src/pages/locations/components/location.tsx @@ -0,0 +1,129 @@ +import { Button, Input } from "antd"; +import type { Identifier, XYCoord } from "dnd-core"; +import { useRef, useState } from "react"; +import { useDrag, useDrop } from "react-dnd"; + +import { DeleteOutlined } from "@ant-design/icons"; +import { ISpool } from "../../spools/model"; +import { ItemTypes } from "../itemTypes"; +import { SpoolList } from "./spoolList"; + +interface DragItem { + index: number; + title: string; +} + +export function Location({ + index, + title, + spools, + showDelete, + onDelete, + moveLocation, + onEditTitle, +}: { + index: number; + title: string; + spools: ISpool[]; + showDelete?: boolean; + onDelete?: () => void; + moveLocation: (dragIndex: number, hoverIndex: number) => void; + onEditTitle: (newTitle: string) => void; +}) { + const [editTitle, setEditTitle] = useState(false); + const [newTitle, setNewTitle] = useState(title); + + const ref = useRef(null); + const [{ handlerId }, drop] = useDrop({ + accept: ItemTypes.CONTAINER, + collect(monitor) { + return { + handlerId: monitor.getHandlerId(), + }; + }, + hover(item, monitor) { + if (!ref.current) { + return null; + } + const dragIndex = item.index; + const hoverIndex = index; + + // Don't replace items with themselves + if (dragIndex === hoverIndex) { + return; + } + + // Determine rectangle on screen + const hoverBoundingRect = ref.current?.getBoundingClientRect(); + + // Get horizontal middle + const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2; + + // Determine mouse position + const clientOffset = monitor.getClientOffset(); + + // Get pixels to the left + const hoverClientX = (clientOffset as XYCoord).x - hoverBoundingRect.left; + + // Dragging downwards + if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) { + return; + } + + // Dragging upwards + if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) { + return; + } + + // Time to actually perform the action + moveLocation(dragIndex, hoverIndex); + + item.index = hoverIndex; + }, + }); + + const [{ isDragging }, drag] = useDrag({ + type: ItemTypes.CONTAINER, + canDrag: !editTitle, + item: () => { + return { title, index }; + }, + collect: (monitor: any) => ({ + isDragging: monitor.isDragging(), + }), + }); + + const opacity = isDragging ? 0 : 1; + drag(drop(ref)); + + return ( +
+

+ {editTitle ? ( + setEditTitle(false)} + onChange={(e) => setNewTitle(e.target.value)} + onPressEnter={() => { + setEditTitle(false); + return onEditTitle(newTitle); + }} + /> + ) : ( + { + setNewTitle(title); + setEditTitle(true); + }} + > + {title} + + )} + {showDelete &&

+ +
+ ); +} diff --git a/client/src/pages/locations/components/locationContainer.tsx b/client/src/pages/locations/components/locationContainer.tsx new file mode 100644 index 00000000..78852eaf --- /dev/null +++ b/client/src/pages/locations/components/locationContainer.tsx @@ -0,0 +1,153 @@ +import { PlusOutlined } from "@ant-design/icons"; +import { useInvalidate, useList, useTranslate } from "@refinedev/core"; +import { Button } from "antd"; +import { useEffect, useMemo } from "react"; +import { useSetSetting } from "../../../utils/querySettings"; +import { ISpool } from "../../spools/model"; +import { renameSpoolLocation, useLocations } from "../functions"; +import { Location } from "./location"; + +export function LocationContainer() { + const t = useTranslate(); + const invalidate = useInvalidate(); + + const settingsLocations = useLocations(); + const setLocationsSetting = useSetSetting("locations"); + + const { data, isLoading, isError } = useList({ + resource: "spool", + meta: { + queryParams: { + ["allow_archived"]: false, + }, + }, + pagination: { + mode: "off", + }, + }); + + // Grab spools and sort by ID + const spools = data?.data ?? []; + spools.sort((a, b) => a.id - b.id); + + // Group spools by location + const spoolLocations = useMemo(() => { + const grouped: Record = {}; + spools.forEach((spool) => { + const loc = spool.location ?? t("spool.no_location"); + if (!grouped[loc]) { + grouped[loc] = []; + } + grouped[loc].push(spool); + }); + return grouped; + }, [spools]); + + // Create list of locations that's sorted + const locationsList = useMemo(() => { + // Start with the locations setting + let allLocs = settingsLocations; + console.log("settingsLocations", settingsLocations); + + // Add any missing locations from the spools + for (const loc of Object.keys(spoolLocations)) { + if (!allLocs.includes(loc)) { + allLocs.push(loc); + } + } + + return allLocs; + }, [spoolLocations, settingsLocations]); + + const moveLocation = (dragIndex: number, hoverIndex: number) => { + const newLocs = [...locationsList]; + newLocs.splice(dragIndex, 1); + newLocs.splice(hoverIndex, 0, locationsList[dragIndex]); + setLocationsSetting.mutate(newLocs); + }; + + const onEditTitle = async (location: string, newTitle: string) => { + if (newTitle == location) return; + if (newTitle == "") return; + if (locationsList.includes(newTitle)) return; + + // Update all spool locations in the database + if (spoolLocations[location] && spoolLocations[location].length > 0) { + await renameSpoolLocation(location, newTitle); + await invalidate({ resource: "spool", invalidates: ["list", "detail"] }); + } + + // Update the value in the settings + const newLocs = [...locationsList]; + newLocs[locationsList.indexOf(location)] = newTitle; + setLocationsSetting.mutate(newLocs); + }; + + // Create containers + const containers = locationsList.map((loc, idx) => { + const spools = spoolLocations[loc] ?? []; + return ( + { + setLocationsSetting.mutate(locationsList.filter((l) => l !== loc)); + }} + moveLocation={moveLocation} + onEditTitle={(newTitle: string) => onEditTitle(loc, newTitle)} + /> + ); + }); + + // Update locations settings so it always includes all spool locations + useEffect(() => { + // Check if they're not the same + if (JSON.stringify(locationsList) !== JSON.stringify(settingsLocations)) { + console.log("Updating locations settings", locationsList, settingsLocations); + setLocationsSetting.mutate(locationsList); + } + }, [spoolLocations]); + + if (isLoading) { + return
Loading...
; + } + + if (isError) { + return
Failed to load spools
; + } + + const addNewLocation = () => { + let newLocationName = "New Location"; + + const newLocs = [...locationsList]; + let i = 1; + while (newLocs.includes(newLocationName)) { + newLocationName = "New Location " + i; + i++; + } + newLocs.push(newLocationName); + + setLocationsSetting.mutate(newLocs); + }; + + return ( +
+ {containers} +
+
+
+ ); +} diff --git a/client/src/pages/locations/components/spoolCard.tsx b/client/src/pages/locations/components/spoolCard.tsx new file mode 100644 index 00000000..5785bcc1 --- /dev/null +++ b/client/src/pages/locations/components/spoolCard.tsx @@ -0,0 +1,75 @@ +import { useNavigation, useTranslate } from "@refinedev/core"; +import { Button, theme } from "antd"; +import { useDrag } from "react-dnd"; + +import { EditOutlined, EyeOutlined } from "@ant-design/icons"; +import { Link } from "react-router-dom"; +import SpoolIcon from "../../../components/spoolIcon"; +import { ISpool } from "../../spools/model"; +import { ItemTypes } from "../itemTypes"; + +const { useToken } = theme; + +export function SpoolCard({ spool }: { spool: ISpool }) { + const { token } = useToken(); + const t = useTranslate(); + const [{ opacity }, dragRef] = useDrag( + () => ({ + type: ItemTypes.SPOOL, + item: spool, + collect: (monitor) => ({ + opacity: monitor.isDragging() ? 0.5 : 1, + }), + }), + [] + ); + const { editUrl, showUrl } = useNavigation(); + + const colorObj = spool.filament.multi_color_hexes + ? { + colors: spool.filament.multi_color_hexes.split(","), + vertical: spool.filament.multi_color_direction === "longitudinal", + } + : spool.filament.color_hex || "#000000"; + + let filament_name: string; + if (spool.filament.vendor && "name" in spool.filament.vendor) { + filament_name = `${spool.filament.vendor.name} - ${spool.filament.name}`; + } else { + filament_name = spool.filament.name ?? spool.filament.id.toString(); + } + + const style = { + opacity, + backgroundColor: token.colorBgContainerDisabled, + }; + + return ( +
+ +
+
+ + #{spool.id} {filament_name} + +
+ +
+
+
+ {spool.remaining_weight} / {spool.filament.weight} g +
+
+
+ ); +} diff --git a/client/src/pages/locations/components/spoolList.tsx b/client/src/pages/locations/components/spoolList.tsx new file mode 100644 index 00000000..0b68fdce --- /dev/null +++ b/client/src/pages/locations/components/spoolList.tsx @@ -0,0 +1,40 @@ +import { useInvalidate } from "@refinedev/core"; +import { useDrop } from "react-dnd"; + +import { theme } from "antd"; +import { ISpool } from "../../spools/model"; +import { ItemTypes } from "../itemTypes"; +import { setSpoolLocation } from "./../functions"; +import { SpoolCard } from "./spoolCard"; + +const { useToken } = theme; + +export function SpoolList({ location, spools }: { location: string; spools: ISpool[] }) { + const { token } = useToken(); + const invalidate = useInvalidate(); + const [, spoolDrop] = useDrop(() => ({ + accept: ItemTypes.SPOOL, + drop: (item: ISpool) => { + setSpoolLocation(item.id, location).then(() => { + invalidate({ + resource: "spool", + id: item.id, + invalidates: ["list", "detail"], + }); + }); + }, + })); + + const style = { + backgroundColor: token.colorBgContainer, + borderRadius: token.borderRadiusLG, + }; + + return ( +
+ {spools.map((spool) => ( + + ))} +
+ ); +} diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index 50be7f42..f9f127e8 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -1,392 +1,19 @@ -import { IResourceComponentsProps, useInvalidate, useList, useNavigation, useTranslate } from "@refinedev/core"; -import { Button, Input, theme } from "antd"; +import { IResourceComponentsProps } from "@refinedev/core"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; -import type { Identifier, XYCoord } from "dnd-core"; -import React, { useEffect, useMemo, useRef, useState } from "react"; -import { DndProvider, useDrag, useDrop } from "react-dnd"; +import React from "react"; +import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; -import { DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined } from "@ant-design/icons"; -import { Link } from "react-router-dom"; -import SpoolIcon from "../../components/spoolIcon"; -import { useSetSetting } from "../../utils/querySettings"; -import { ISpool } from "../spools/model"; -import { renameSpoolLocation, setSpoolLocation, useLocations } from "./functions"; +import { LocationContainer } from "./components/locationContainer"; import "./locations.css"; dayjs.extend(utc); -const ItemTypes = { - SPOOL: "spool", - CONTAINER: "spool-container", -}; - -const { useToken } = theme; - -function SpoolCard({ spool }: { spool: ISpool }) { - const { token } = useToken(); - const t = useTranslate(); - const [{ opacity }, dragRef] = useDrag( - () => ({ - type: ItemTypes.SPOOL, - item: spool, - collect: (monitor) => ({ - opacity: monitor.isDragging() ? 0.5 : 1, - }), - }), - [] - ); - const { editUrl, showUrl } = useNavigation(); - - const colorObj = spool.filament.multi_color_hexes - ? { - colors: spool.filament.multi_color_hexes.split(","), - vertical: spool.filament.multi_color_direction === "longitudinal", - } - : spool.filament.color_hex || "#000000"; - - let filament_name: string; - if (spool.filament.vendor && "name" in spool.filament.vendor) { - filament_name = `${spool.filament.vendor.name} - ${spool.filament.name}`; - } else { - filament_name = spool.filament.name ?? spool.filament.id.toString(); - } - - const style = { - opacity, - backgroundColor: token.colorBgContainerDisabled, - }; - - return ( -
- -
-
- - #{spool.id} {filament_name} - -
- -
-
-
- {spool.remaining_weight} / {spool.filament.weight} g -
-
-
- ); -} - -function SpoolList({ location, spools }: { location: string; spools: ISpool[] }) { - const { token } = useToken(); - const invalidate = useInvalidate(); - const [, spoolDrop] = useDrop(() => ({ - accept: ItemTypes.SPOOL, - drop: (item: ISpool) => { - setSpoolLocation(item.id, location).then(() => { - invalidate({ - resource: "spool", - id: item.id, - invalidates: ["list", "detail"], - }); - }); - }, - })); - - const style = { - backgroundColor: token.colorBgContainer, - borderRadius: token.borderRadiusLG, - }; - - return ( -
- {spools.map((spool) => ( - - ))} -
- ); -} - -interface DragItem { - index: number; - title: string; -} - -function LocationContainer({ - index, - title, - spools, - showDelete, - onDelete, - moveLocation, - onEditTitle, -}: { - index: number; - title: string; - spools: ISpool[]; - showDelete?: boolean; - onDelete?: () => void; - moveLocation: (dragIndex: number, hoverIndex: number) => void; - onEditTitle: (newTitle: string) => void; -}) { - const [editTitle, setEditTitle] = useState(false); - const [newTitle, setNewTitle] = useState(title); - - const ref = useRef(null); - const [{ handlerId }, drop] = useDrop({ - accept: ItemTypes.CONTAINER, - collect(monitor) { - return { - handlerId: monitor.getHandlerId(), - }; - }, - hover(item, monitor) { - if (!ref.current) { - return null; - } - const dragIndex = item.index; - const hoverIndex = index; - - // Don't replace items with themselves - if (dragIndex === hoverIndex) { - return; - } - - // Determine rectangle on screen - const hoverBoundingRect = ref.current?.getBoundingClientRect(); - - // Get horizontal middle - const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2; - - // Determine mouse position - const clientOffset = monitor.getClientOffset(); - - // Get pixels to the left - const hoverClientX = (clientOffset as XYCoord).x - hoverBoundingRect.left; - - // Dragging downwards - if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) { - return; - } - - // Dragging upwards - if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) { - return; - } - - // Time to actually perform the action - moveLocation(dragIndex, hoverIndex); - - item.index = hoverIndex; - }, - }); - - const [{ isDragging }, drag] = useDrag({ - type: ItemTypes.CONTAINER, - canDrag: !editTitle, - item: () => { - return { title, index }; - }, - collect: (monitor: any) => ({ - isDragging: monitor.isDragging(), - }), - }); - - const opacity = isDragging ? 0 : 1; - drag(drop(ref)); - - return ( -
-

- {editTitle ? ( - setEditTitle(false)} - onChange={(e) => setNewTitle(e.target.value)} - onPressEnter={() => { - setEditTitle(false); - return onEditTitle(newTitle); - }} - /> - ) : ( - { - setNewTitle(title); - setEditTitle(true); - }} - > - {title} - - )} - {showDelete &&

- -
- ); -} - -function LocationMetaContainer() { - const t = useTranslate(); - const invalidate = useInvalidate(); - - const settingsLocations = useLocations(); - const setLocationsSetting = useSetSetting("locations"); - - const { data, isLoading, isError } = useList({ - resource: "spool", - meta: { - queryParams: { - ["allow_archived"]: false, - }, - }, - pagination: { - mode: "off", - }, - }); - - // Grab spools and sort by ID - const spools = data?.data ?? []; - spools.sort((a, b) => a.id - b.id); - - // Group spools by location - const spoolLocations = useMemo(() => { - const grouped: Record = {}; - spools.forEach((spool) => { - const loc = spool.location ?? t("spool.no_location"); - if (!grouped[loc]) { - grouped[loc] = []; - } - grouped[loc].push(spool); - }); - return grouped; - }, [spools]); - - // Create list of locations that's sorted - const locationsList = useMemo(() => { - // Start with the locations setting - let allLocs = settingsLocations; - console.log("settingsLocations", settingsLocations); - - // Add any missing locations from the spools - for (const loc of Object.keys(spoolLocations)) { - if (!allLocs.includes(loc)) { - allLocs.push(loc); - } - } - - return allLocs; - }, [spoolLocations, settingsLocations]); - - const moveLocation = (dragIndex: number, hoverIndex: number) => { - const newLocs = [...locationsList]; - newLocs.splice(dragIndex, 1); - newLocs.splice(hoverIndex, 0, locationsList[dragIndex]); - setLocationsSetting.mutate(newLocs); - }; - - const onEditTitle = async (location: string, newTitle: string) => { - if (newTitle == location) return; - if (newTitle == "") return; - if (locationsList.includes(newTitle)) return; - - // Update all spool locations in the database - if (spoolLocations[location] && spoolLocations[location].length > 0) { - await renameSpoolLocation(location, newTitle); - await invalidate({ resource: "spool", invalidates: ["list", "detail"] }); - } - - // Update the value in the settings - const newLocs = [...locationsList]; - newLocs[locationsList.indexOf(location)] = newTitle; - setLocationsSetting.mutate(newLocs); - }; - - // Create containers - const containers = locationsList.map((loc, idx) => { - const spools = spoolLocations[loc] ?? []; - return ( - { - setLocationsSetting.mutate(locationsList.filter((l) => l !== loc)); - }} - moveLocation={moveLocation} - onEditTitle={(newTitle: string) => onEditTitle(loc, newTitle)} - /> - ); - }); - - // Update locations settings so it always includes all spool locations - useEffect(() => { - // Check if they're not the same - if (JSON.stringify(locationsList) !== JSON.stringify(settingsLocations)) { - console.log("Updating locations settings", locationsList, settingsLocations); - setLocationsSetting.mutate(locationsList); - } - }, [spoolLocations]); - - if (isLoading) { - return
Loading...
; - } - - if (isError) { - return
Failed to load spools
; - } - - const addNewLocation = () => { - let newLocationName = "New Location"; - - const newLocs = [...locationsList]; - let i = 1; - while (newLocs.includes(newLocationName)) { - newLocationName = "New Location " + i; - i++; - } - newLocs.push(newLocationName); - - setLocationsSetting.mutate(newLocs); - }; - - return ( -
- {containers} -
-
-
- ); -} - export const Locations: React.FC = () => { return ( - + ); }; diff --git a/client/src/pages/locations/itemTypes.ts b/client/src/pages/locations/itemTypes.ts new file mode 100644 index 00000000..76cc06a4 --- /dev/null +++ b/client/src/pages/locations/itemTypes.ts @@ -0,0 +1,4 @@ +export const ItemTypes = { + SPOOL: "spool", + CONTAINER: "spool-container", +}; From bf0640836801bcdbf5610712c90fc3cba992ef1f Mon Sep 17 00:00:00 2001 From: Donkie Date: Wed, 20 Nov 2024 21:57:01 +0100 Subject: [PATCH 10/16] Added reading and using of spool orders in locations --- .../pages/locations/components/location.tsx | 11 ++++- .../components/locationContainer.tsx | 17 +++++++- .../pages/locations/components/spoolList.tsx | 37 ++++++++++++---- client/src/pages/locations/functions.ts | 43 +++++++++++++------ spoolman/settings.py | 1 + 5 files changed, 84 insertions(+), 25 deletions(-) diff --git a/client/src/pages/locations/components/location.tsx b/client/src/pages/locations/components/location.tsx index eaa8dea4..926a7137 100644 --- a/client/src/pages/locations/components/location.tsx +++ b/client/src/pages/locations/components/location.tsx @@ -21,6 +21,8 @@ export function Location({ onDelete, moveLocation, onEditTitle, + locationSpoolOrder, + setLocationSpoolOrder, }: { index: number; title: string; @@ -29,6 +31,8 @@ export function Location({ onDelete?: () => void; moveLocation: (dragIndex: number, hoverIndex: number) => void; onEditTitle: (newTitle: string) => void; + locationSpoolOrder: number[]; + setLocationSpoolOrder: (spoolOrder: number[]) => void; }) { const [editTitle, setEditTitle] = useState(false); const [newTitle, setNewTitle] = useState(title); @@ -123,7 +127,12 @@ export function Location({ )} {showDelete &&
); } diff --git a/client/src/pages/locations/components/locationContainer.tsx b/client/src/pages/locations/components/locationContainer.tsx index 78852eaf..b4c5caf4 100644 --- a/client/src/pages/locations/components/locationContainer.tsx +++ b/client/src/pages/locations/components/locationContainer.tsx @@ -4,7 +4,7 @@ import { Button } from "antd"; import { useEffect, useMemo } from "react"; import { useSetSetting } from "../../../utils/querySettings"; import { ISpool } from "../../spools/model"; -import { renameSpoolLocation, useLocations } from "../functions"; +import { renameSpoolLocation, useLocations, useLocationsSpoolOrders } from "../functions"; import { Location } from "./location"; export function LocationContainer() { @@ -14,6 +14,10 @@ export function LocationContainer() { const settingsLocations = useLocations(); const setLocationsSetting = useSetSetting("locations"); + const locationsSpoolOrders = useLocationsSpoolOrders(); + console.log("locationsSpoolOrders", locationsSpoolOrders); + const setLocationsSpoolOrders = useSetSetting>("locations_spoolorders"); + const { data, isLoading, isError } = useList({ resource: "spool", meta: { @@ -83,9 +87,18 @@ export function LocationContainer() { setLocationsSetting.mutate(newLocs); }; + const setLocationSpoolOrder = (location: string, spoolOrder: number[]) => { + setLocationsSpoolOrders.mutate({ + ...locationsSpoolOrders, + [location]: spoolOrder, + }); + }; + // Create containers const containers = locationsList.map((loc, idx) => { const spools = spoolLocations[loc] ?? []; + const spoolOrder = locationsSpoolOrders[loc] ?? []; + return ( onEditTitle(loc, newTitle)} + locationSpoolOrder={spoolOrder} + setLocationSpoolOrder={(spoolOrder: number[]) => setLocationSpoolOrder(loc, spoolOrder)} /> ); }); diff --git a/client/src/pages/locations/components/spoolList.tsx b/client/src/pages/locations/components/spoolList.tsx index 0b68fdce..1a9f7b7b 100644 --- a/client/src/pages/locations/components/spoolList.tsx +++ b/client/src/pages/locations/components/spoolList.tsx @@ -9,22 +9,41 @@ import { SpoolCard } from "./spoolCard"; const { useToken } = theme; -export function SpoolList({ location, spools }: { location: string; spools: ISpool[] }) { +export function SpoolList({ + location, + spools, + spoolOrder, + setSpoolOrder, +}: { + location: string; + spools: ISpool[]; + spoolOrder: number[]; + setSpoolOrder: (spoolOrder: number[]) => void; +}) { const { token } = useToken(); const invalidate = useInvalidate(); const [, spoolDrop] = useDrop(() => ({ accept: ItemTypes.SPOOL, - drop: (item: ISpool) => { - setSpoolLocation(item.id, location).then(() => { - invalidate({ - resource: "spool", - id: item.id, - invalidates: ["list", "detail"], - }); + drop: async (item: ISpool) => { + if (item.location === location) return; + await setSpoolLocation(item.id, location); + await invalidate({ + resource: "spool", + id: item.id, + invalidates: ["list", "detail"], }); }, })); + // Make sure all spools are in the spoolOrders array + const finalSpoolOrder = [...spoolOrder].filter((id) => spools.find((spool) => spool.id === id)); // Remove any spools that are not in the spools array + spools.forEach((spool) => { + if (!finalSpoolOrder.includes(spool.id)) finalSpoolOrder.push(spool.id); + }); + + // Reorder the spools based on the spoolOrder array + const reorderedSpools = finalSpoolOrder.map((id) => spools.find((spool) => spool.id === id)!); + const style = { backgroundColor: token.colorBgContainer, borderRadius: token.borderRadiusLG, @@ -32,7 +51,7 @@ export function SpoolList({ location, spools }: { location: string; spools: ISpo return (
- {spools.map((spool) => ( + {reorderedSpools.map((spool) => ( ))}
diff --git a/client/src/pages/locations/functions.ts b/client/src/pages/locations/functions.ts index 0091efc8..6d6e6ee1 100644 --- a/client/src/pages/locations/functions.ts +++ b/client/src/pages/locations/functions.ts @@ -19,6 +19,22 @@ export async function setSpoolLocation(spool_id: number, location: string | null return response.json(); } +export async function renameSpoolLocation(location: string, newName: string): Promise { + const response = await fetch(getAPIURL() + "/location/" + location, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: newName, + }), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + return await response.text(); +} + export function useLocations(): string[] { const query = useGetSetting("locations"); @@ -34,18 +50,17 @@ export function useLocations(): string[] { }, [query.data]); } -export async function renameSpoolLocation(location: string, newName: string): Promise { - const response = await fetch(getAPIURL() + "/location/" + location, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: newName, - }), - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return await response.text(); +export function useLocationsSpoolOrders(): Record { + const query = useGetSetting("locations_spoolorders"); + + return useMemo(() => { + if (!query.data) return {}; + + try { + return JSON.parse(query.data.value) as Record; + } catch { + console.warn("Failed to parse locations spool orders", query.data.value); + return {}; + } + }, [query.data]); } diff --git a/spoolman/settings.py b/spoolman/settings.py index bb7217c8..50510316 100644 --- a/spoolman/settings.py +++ b/spoolman/settings.py @@ -70,3 +70,4 @@ def parse_setting(key: str) -> SettingDefinition: register_setting("base_url", SettingType.STRING, json.dumps("")) register_setting("locations", SettingType.ARRAY, json.dumps([])) +register_setting("locations_spoolorders", SettingType.OBJECT, json.dumps({})) From 67c5b34bf5c90537ea6893e352bf380e540eef64 Mon Sep 17 00:00:00 2001 From: Donkie Date: Sat, 23 Nov 2024 22:42:47 +0100 Subject: [PATCH 11/16] Final touches on locations page --- client/package-lock.json | 41 +++++- client/package.json | 4 +- .../pages/locations/components/location.tsx | 46 +++++-- .../components/locationContainer.tsx | 44 +++++-- .../pages/locations/components/spoolCard.tsx | 120 +++++++++++++++--- .../pages/locations/components/spoolList.tsx | 45 +++---- client/src/pages/locations/dnd.ts | 29 +++++ client/src/pages/locations/functions.ts | 97 ++++++++++---- client/src/pages/locations/itemTypes.ts | 4 - client/src/pages/locations/locations.css | 8 ++ 10 files changed, 339 insertions(+), 99 deletions(-) create mode 100644 client/src/pages/locations/dnd.ts delete mode 100644 client/src/pages/locations/itemTypes.ts diff --git a/client/package-lock.json b/client/package-lock.json index 273f4671..faf8f1e7 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -37,10 +37,12 @@ "react-router-dom": "^6.28.0", "react-to-print": "^2.15.1", "uuid": "^11.0.3", - "vite-plugin-svgr": "^4.3.0" + "vite-plugin-svgr": "^4.3.0", + "zustand": "^5.0.1" }, "devDependencies": { "@refinedev/cli": "^2.16.39", + "@simbathesailor/use-what-changed": "^2.0.0", "@types/node": "^22.9.1", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", @@ -2643,6 +2645,15 @@ "win32" ] }, + "node_modules/@simbathesailor/use-what-changed": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@simbathesailor/use-what-changed/-/use-what-changed-2.0.0.tgz", + "integrity": "sha512-ulBNrPSvfho9UN6zS2fii3AsdEcp2fMaKeqUZZeCNPaZbB6aXyTUhpEN9atjMAbu/eyK3AY8L4SYJUG62Ekocw==", + "dev": true, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -10320,6 +10331,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zustand": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.1.tgz", + "integrity": "sha512-pRET7Lao2z+n5R/HduXMio35TncTlSW68WsYBq2Lg1ASspsNGjpwLAsij3RpouyV6+kHMwwwzP0bZPD70/Jx/w==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, "node_modules/zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", diff --git a/client/package.json b/client/package.json index d333a91e..119fc090 100644 --- a/client/package.json +++ b/client/package.json @@ -36,10 +36,12 @@ "react-router-dom": "^6.28.0", "react-to-print": "^2.15.1", "uuid": "^11.0.3", - "vite-plugin-svgr": "^4.3.0" + "vite-plugin-svgr": "^4.3.0", + "zustand": "^5.0.1" }, "devDependencies": { "@refinedev/cli": "^2.16.39", + "@simbathesailor/use-what-changed": "^2.0.0", "@types/node": "^22.9.1", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", diff --git a/client/src/pages/locations/components/location.tsx b/client/src/pages/locations/components/location.tsx index 926a7137..eebd5261 100644 --- a/client/src/pages/locations/components/location.tsx +++ b/client/src/pages/locations/components/location.tsx @@ -4,15 +4,11 @@ import { useRef, useState } from "react"; import { useDrag, useDrop } from "react-dnd"; import { DeleteOutlined } from "@ant-design/icons"; +import { useUpdate } from "@refinedev/core"; import { ISpool } from "../../spools/model"; -import { ItemTypes } from "../itemTypes"; +import { DragItem, ItemTypes, SpoolDragItem } from "../dnd"; import { SpoolList } from "./spoolList"; -interface DragItem { - index: number; - title: string; -} - export function Location({ index, title, @@ -36,10 +32,24 @@ export function Location({ }) { const [editTitle, setEditTitle] = useState(false); const [newTitle, setNewTitle] = useState(title); + const { mutate: updateSpool } = useUpdate({ + resource: "spool", + mutationMode: "optimistic", + successNotification: false, + }); + + const moveSpoolLocation = (spool_id: number, location: string) => { + updateSpool({ + id: spool_id, + values: { + location: location, + }, + }); + }; const ref = useRef(null); const [{ handlerId }, drop] = useDrop({ - accept: ItemTypes.CONTAINER, + accept: [ItemTypes.CONTAINER, ItemTypes.SPOOL], collect(monitor) { return { handlerId: monitor.getHandlerId(), @@ -49,6 +59,21 @@ export function Location({ if (!ref.current) { return null; } + + if ("spool" in item) { + // Only allow dropping spools on the container if it's empty. + if (spools.length > 0) { + return null; + } + + const spoolitem = item as SpoolDragItem; + if (spoolitem.spool.location !== title) { + moveSpoolLocation(spoolitem.spool.id, title); + spoolitem.spool.location = title; + } + return null; + } + const dragIndex = item.index; const hoverIndex = index; @@ -127,12 +152,7 @@ export function Location({ )} {showDelete &&
); } diff --git a/client/src/pages/locations/components/locationContainer.tsx b/client/src/pages/locations/components/locationContainer.tsx index b4c5caf4..1cac77b8 100644 --- a/client/src/pages/locations/components/locationContainer.tsx +++ b/client/src/pages/locations/components/locationContainer.tsx @@ -4,21 +4,25 @@ import { Button } from "antd"; import { useEffect, useMemo } from "react"; import { useSetSetting } from "../../../utils/querySettings"; import { ISpool } from "../../spools/model"; -import { renameSpoolLocation, useLocations, useLocationsSpoolOrders } from "../functions"; +import { useLocations, useLocationsSpoolOrders, useRenameSpoolLocation } from "../functions"; import { Location } from "./location"; export function LocationContainer() { const t = useTranslate(); const invalidate = useInvalidate(); + const renameSpoolLocation = useRenameSpoolLocation(); const settingsLocations = useLocations(); const setLocationsSetting = useSetSetting("locations"); const locationsSpoolOrders = useLocationsSpoolOrders(); - console.log("locationsSpoolOrders", locationsSpoolOrders); const setLocationsSpoolOrders = useSetSetting>("locations_spoolorders"); - const { data, isLoading, isError } = useList({ + const { + data: spoolData, + isLoading, + isError, + } = useList({ resource: "spool", meta: { queryParams: { @@ -30,12 +34,11 @@ export function LocationContainer() { }, }); - // Grab spools and sort by ID - const spools = data?.data ?? []; - spools.sort((a, b) => a.id - b.id); - // Group spools by location - const spoolLocations = useMemo(() => { + const spoolLocations = (() => { + const spools = spoolData?.data ?? []; + spools.sort((a, b) => a.id - b.id); + const grouped: Record = {}; spools.forEach((spool) => { const loc = spool.location ?? t("spool.no_location"); @@ -44,14 +47,32 @@ export function LocationContainer() { } grouped[loc].push(spool); }); + + // Sort spools in the locations by the spool order + for (const loc of Object.keys(grouped)) { + if (!locationsSpoolOrders[loc]) { + continue; + } + grouped[loc].sort((a, b) => { + let aidx = locationsSpoolOrders[loc].indexOf(a.id); + if (aidx === -1) { + aidx = 999999; + } + let bidx = locationsSpoolOrders[loc].indexOf(b.id); + if (bidx === -1) { + bidx = 999999; + } + return aidx - bidx; + }); + } + return grouped; - }, [spools]); + })(); // Create list of locations that's sorted const locationsList = useMemo(() => { // Start with the locations setting let allLocs = settingsLocations; - console.log("settingsLocations", settingsLocations); // Add any missing locations from the spools for (const loc of Object.keys(spoolLocations)) { @@ -77,8 +98,7 @@ export function LocationContainer() { // Update all spool locations in the database if (spoolLocations[location] && spoolLocations[location].length > 0) { - await renameSpoolLocation(location, newTitle); - await invalidate({ resource: "spool", invalidates: ["list", "detail"] }); + renameSpoolLocation.mutate({ old: location, new: newTitle }); } // Update the value in the settings diff --git a/client/src/pages/locations/components/spoolCard.tsx b/client/src/pages/locations/components/spoolCard.tsx index 5785bcc1..6da9a605 100644 --- a/client/src/pages/locations/components/spoolCard.tsx +++ b/client/src/pages/locations/components/spoolCard.tsx @@ -1,30 +1,118 @@ -import { useNavigation, useTranslate } from "@refinedev/core"; +import { useNavigation, useTranslate, useUpdate } from "@refinedev/core"; import { Button, theme } from "antd"; -import { useDrag } from "react-dnd"; +import type { Identifier, XYCoord } from "dnd-core"; +import { useDrag, useDrop } from "react-dnd"; import { EditOutlined, EyeOutlined } from "@ant-design/icons"; +import { useEffect, useRef } from "react"; import { Link } from "react-router-dom"; import SpoolIcon from "../../../components/spoolIcon"; import { ISpool } from "../../spools/model"; -import { ItemTypes } from "../itemTypes"; +import { ItemTypes, SpoolDragItem, useCurrentDraggedSpool } from "../dnd"; const { useToken } = theme; -export function SpoolCard({ spool }: { spool: ISpool }) { +export function SpoolCard({ + index, + spool, + moveSpoolOrder, +}: { + index: number; + spool: ISpool; + moveSpoolOrder: (dragIndex: number, hoverIndex: number) => void; +}) { const { token } = useToken(); const t = useTranslate(); - const [{ opacity }, dragRef] = useDrag( - () => ({ - type: ItemTypes.SPOOL, - item: spool, - collect: (monitor) => ({ - opacity: monitor.isDragging() ? 0.5 : 1, - }), - }), - [] - ); const { editUrl, showUrl } = useNavigation(); + // Using a global state for this, because the drag handlers are reset when the spool changes location + const { draggedSpoolId, setDraggedSpoolId } = useCurrentDraggedSpool(); + + const { mutate: updateSpool } = useUpdate({ + resource: "spool", + mutationMode: "optimistic", + successNotification: false, + }); + + const moveSpoolLocation = (spool_id: number, location: string) => { + updateSpool({ + id: spool_id, + values: { + location: location, + }, + }); + }; + + const ref = useRef(null); + const [{ handlerId }, drop] = useDrop({ + accept: ItemTypes.SPOOL, + collect(monitor) { + return { + handlerId: monitor.getHandlerId(), + }; + }, + hover(item, monitor) { + if (!ref.current || item.spool.id === spool.id) { + return null; + } + + if (item.spool.location !== spool.location && spool.location) { + moveSpoolLocation(item.spool.id, spool.location); + item.spool.location = spool.location; + return; + } + + const dragIndex = item.index; + const hoverIndex = index; + + // Determine rectangle on screen + const hoverBoundingRect = ref.current?.getBoundingClientRect(); + + // Get horizontal middle + const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; + + // Determine mouse position + const clientOffset = monitor.getClientOffset(); + + // Get pixels to the top + const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top; + + // Dragging downwards + if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { + return; + } + + // Dragging upwards + if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { + return; + } + + // Time to actually perform the action + moveSpoolOrder(item.spool.id, hoverIndex); + + item.index = hoverIndex; + }, + }); + + const [{ isDragging }, drag] = useDrag({ + type: ItemTypes.SPOOL, + item: () => { + return { spool, index }; + }, + collect: (monitor: any) => ({ + isDragging: monitor.isDragging(), + }), + end() { + setDraggedSpoolId(-1); + }, + }); + + useEffect(() => { + if (isDragging) { + setDraggedSpoolId(spool.id); + } + }, [isDragging]); + const colorObj = spool.filament.multi_color_hexes ? { colors: spool.filament.multi_color_hexes.split(","), @@ -39,13 +127,15 @@ export function SpoolCard({ spool }: { spool: ISpool }) { filament_name = spool.filament.name ?? spool.filament.id.toString(); } + const opacity = draggedSpoolId === spool.id ? 0 : 1; const style = { opacity, backgroundColor: token.colorBgContainerDisabled, }; + drag(drop(ref)); return ( -
+
diff --git a/client/src/pages/locations/components/spoolList.tsx b/client/src/pages/locations/components/spoolList.tsx index 1a9f7b7b..46293c40 100644 --- a/client/src/pages/locations/components/spoolList.tsx +++ b/client/src/pages/locations/components/spoolList.tsx @@ -1,39 +1,19 @@ -import { useInvalidate } from "@refinedev/core"; -import { useDrop } from "react-dnd"; - import { theme } from "antd"; import { ISpool } from "../../spools/model"; -import { ItemTypes } from "../itemTypes"; -import { setSpoolLocation } from "./../functions"; import { SpoolCard } from "./spoolCard"; const { useToken } = theme; export function SpoolList({ - location, spools, spoolOrder, setSpoolOrder, }: { - location: string; spools: ISpool[]; spoolOrder: number[]; setSpoolOrder: (spoolOrder: number[]) => void; }) { const { token } = useToken(); - const invalidate = useInvalidate(); - const [, spoolDrop] = useDrop(() => ({ - accept: ItemTypes.SPOOL, - drop: async (item: ISpool) => { - if (item.location === location) return; - await setSpoolLocation(item.id, location); - await invalidate({ - resource: "spool", - id: item.id, - invalidates: ["list", "detail"], - }); - }, - })); // Make sure all spools are in the spoolOrders array const finalSpoolOrder = [...spoolOrder].filter((id) => spools.find((spool) => spool.id === id)); // Remove any spools that are not in the spools array @@ -41,8 +21,23 @@ export function SpoolList({ if (!finalSpoolOrder.includes(spool.id)) finalSpoolOrder.push(spool.id); }); - // Reorder the spools based on the spoolOrder array - const reorderedSpools = finalSpoolOrder.map((id) => spools.find((spool) => spool.id === id)!); + const moveSpoolOrder = (spool_id: number, hoverIndex: number) => { + // Move spool spool_id to position hoverIndex + let curIdx = finalSpoolOrder.indexOf(spool_id); + if (curIdx === -1) { + // Spool is missing from spool order array, add it to the end of the array + finalSpoolOrder.push(spool_id); + curIdx = finalSpoolOrder.length - 1; + } else if (curIdx === hoverIndex) { + // Spool is already in the right position + return; + } + + const newSpoolOrder = [...finalSpoolOrder]; + newSpoolOrder.splice(curIdx, 1); + newSpoolOrder.splice(hoverIndex, 0, finalSpoolOrder[curIdx]); + setSpoolOrder(newSpoolOrder); + }; const style = { backgroundColor: token.colorBgContainer, @@ -50,9 +45,9 @@ export function SpoolList({ }; return ( -
- {reorderedSpools.map((spool) => ( - +
+ {spools.map((spool, idx) => ( + ))}
); diff --git a/client/src/pages/locations/dnd.ts b/client/src/pages/locations/dnd.ts new file mode 100644 index 00000000..6997f5fa --- /dev/null +++ b/client/src/pages/locations/dnd.ts @@ -0,0 +1,29 @@ +import { create } from "zustand"; +import { ISpool } from "../spools/model"; + +export const ItemTypes = { + SPOOL: "spool", + CONTAINER: "spool-container", +}; + +export interface DragItem { + index: number; +} + +export interface SpoolDragItem extends DragItem { + spool: ISpool; +} + +export interface ContainerDragItem extends DragItem { + title: string; +} + +interface CurrentDraggedSpool { + draggedSpoolId: number; + setDraggedSpoolId: (spoolid: number) => void; +} + +export const useCurrentDraggedSpool = create((set) => ({ + draggedSpoolId: -1, + setDraggedSpoolId: (spoolid: number) => set({ draggedSpoolId: spoolid }), +})); diff --git a/client/src/pages/locations/functions.ts b/client/src/pages/locations/functions.ts index 6d6e6ee1..e45e17f3 100644 --- a/client/src/pages/locations/functions.ts +++ b/client/src/pages/locations/functions.ts @@ -1,38 +1,77 @@ +import { GetListResponse } from "@refinedev/core"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useMemo } from "react"; import { useGetSetting } from "../../utils/querySettings"; import { getAPIURL } from "../../utils/url"; import { ISpool } from "../spools/model"; -export async function setSpoolLocation(spool_id: number, location: string | null): Promise { - const response = await fetch(getAPIURL() + "/spool/" + spool_id, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - location: location, - }), - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); +interface LocationRename { + old: string; + new: string; } -export async function renameSpoolLocation(location: string, newName: string): Promise { - const response = await fetch(getAPIURL() + "/location/" + location, { - method: "PATCH", - headers: { - "Content-Type": "application/json", +export function useRenameSpoolLocation() { + const queryClient = useQueryClient(); + const queryKey = ["default", "spool"]; + const queryKeyList = ["default", "spool", "list"]; + + return useMutation({ + mutationFn: async (value) => { + const response = await fetch(getAPIURL() + "/location/" + value.old, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: value.new, + }), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + return await response.text(); + }, + onMutate: async (value) => { + await queryClient.cancelQueries(queryKeyList); + + // Optimistically update all spools with matching location to the new one + queryClient.setQueriesData>({ queryKey: queryKeyList }, (old) => { + if (old) { + return { + data: old.data.map((spool) => { + if (spool.location === value.old) { + return { ...spool, location: value.new }; + } + return spool; + }), + total: old.total, + }; + } + return old; + }); + }, + onError: (_error, value, _context) => { + // Mutation failed, reset spools with matching location to the old one + queryClient.setQueriesData>({ queryKey: queryKeyList }, (old) => { + if (old) { + return { + data: old.data.map((spool) => { + if (spool.location === value.new) { + return { ...spool, location: value.old }; + } + return spool; + }), + total: old.total, + }; + } + return old; + }); + }, + onSuccess: (_data, _value) => { + // Mutation succeeded, refetch + queryClient.invalidateQueries(queryKey); }, - body: JSON.stringify({ - name: newName, - }), }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return await response.text(); } export function useLocations(): string[] { @@ -42,7 +81,9 @@ export function useLocations(): string[] { if (!query.data) return []; try { - return JSON.parse(query.data.value) as string[]; + let data = (JSON.parse(query.data.value) ?? []) as string[]; + data = data.filter((location) => location != null && location.length > 0); + return data; } catch { console.warn("Failed to parse locations", query.data.value); return []; @@ -57,7 +98,7 @@ export function useLocationsSpoolOrders(): Record { if (!query.data) return {}; try { - return JSON.parse(query.data.value) as Record; + return (JSON.parse(query.data.value) ?? {}) as Record; } catch { console.warn("Failed to parse locations spool orders", query.data.value); return {}; diff --git a/client/src/pages/locations/itemTypes.ts b/client/src/pages/locations/itemTypes.ts deleted file mode 100644 index 76cc06a4..00000000 --- a/client/src/pages/locations/itemTypes.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const ItemTypes = { - SPOOL: "spool", - CONTAINER: "spool-container", -}; diff --git a/client/src/pages/locations/locations.css b/client/src/pages/locations/locations.css index 90bef7b7..de427580 100644 --- a/client/src/pages/locations/locations.css +++ b/client/src/pages/locations/locations.css @@ -13,10 +13,18 @@ display: flex; align-items: center; justify-content: space-between; + font-size: 21px; width: 100%; cursor: text; } +.loc-container h3 input { + font-size: 21px; + margin: 0; + padding: 0; + border: 0; +} + .loc-container .loc-spools { padding: 0.2em; display: flex; From 1a55855ce91aa6467421e7457d1b55752416c1ef Mon Sep 17 00:00:00 2001 From: Donkie Date: Sat, 23 Nov 2024 23:16:41 +0100 Subject: [PATCH 12/16] Some i18n stuff --- client/public/locales/en/common.json | 7 +++++ client/public/locales/sv/common.json | 9 ++++++- client/src/i18n.ts | 27 +++++++++++++++++++ .../components/locationContainer.tsx | 7 ++--- .../pages/locations/components/spoolCard.tsx | 23 +++++++++++++++- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/client/public/locales/en/common.json b/client/public/locales/en/common.json index 45df7769..c1459e9c 100644 --- a/client/public/locales/en/common.json +++ b/client/public/locales/en/common.json @@ -208,6 +208,9 @@ }, "messages": { "archive": "Are you sure you want to archive this spool?" + }, + "formats": { + "last_used": "Last used {{date}}" } }, "filament": { @@ -377,5 +380,9 @@ "create": "Create Manufacturer | Spoolman", "clone": "#{{id}} Clone Manufacturer | Spoolman" } + }, + "locations": { + "new_location": "New Location", + "no_location": "No Location" } } diff --git a/client/public/locales/sv/common.json b/client/public/locales/sv/common.json index e36c4083..39977fc0 100644 --- a/client/public/locales/sv/common.json +++ b/client/public/locales/sv/common.json @@ -210,6 +210,9 @@ "measurement_type_label": "Mättyp", "adjust_filament_value": "Mängd att konsumera", "adjust_filament_help": "Här kan du direkt lägga till eller subtrahera filament från spolen. Ett positivt värde kommer att konsumera filament, ett negativt värde kommer att lägga till det." + }, + "formats": { + "last_used": "Senast använd {{date}}" } }, "filament": { @@ -376,5 +379,9 @@ "description": "Hjälp

Här är några tips för att komma igång.

Spoolman innehåller 3 olika typer av data:

För att lägga till en ny spole i databasen måste du först skapa ett Filament-objekt för den. När det är klart kan du sedan skapa ett Spol-objekt för den individuella spolen. Om du sedan köper ytterligare spolar av samma filament kan du bara skapa ytterligare Spol-objekt och återanvända samma Filament-objekt.

Du kan valfritt också skapa ett Tillverkar-objekt för företaget som tillverkar filamentet om du vill spåra den informationen.

Du kan koppla andra 3D-skrivartjänster till Spoolman, som Moonraker, som sedan automatiskt kan spåra filamentanvändning och uppdatera Spol-objekten åt dig. Se Spoolman README för hur du gör det.

", "help": "Hjälp" }, - "kofi": "Dricksa mig på Ko-fi" + "kofi": "Dricksa mig på Ko-fi", + "locations": { + "new_location": "Ny plats", + "no_location": "Ingen plats" + } } diff --git a/client/src/i18n.ts b/client/src/i18n.ts index a83382e5..ac1f79b0 100644 --- a/client/src/i18n.ts +++ b/client/src/i18n.ts @@ -1,3 +1,4 @@ +import dayjs from "dayjs"; import i18n from "i18next"; import detector from "i18next-browser-languagedetector"; import Backend from "i18next-http-backend"; @@ -8,6 +9,7 @@ interface Language { name: string; countryCode: string; fullCode: string; + djs: () => Promise; } /** @@ -16,107 +18,128 @@ interface Language { * name: Name of the language in the list * countryCode: Country code of the country's flag to display for this language * fullCode: Full language code, used for Ant Design's locale + * djs: Function to load the dayjs locale, see https://github.com/iamkun/dayjs/tree/dev/src/locale for list of locales */ export const languages: { [key: string]: Language } = { ["en"]: { name: "English", countryCode: "gb", fullCode: "en-GB", + djs: () => import("dayjs/locale/en"), }, ["sv"]: { name: "Svenska", countryCode: "se", fullCode: "sv-SE", + djs: () => import("dayjs/locale/sv"), }, ["de"]: { name: "Deutsch", countryCode: "de", fullCode: "de-DE", + djs: () => import("dayjs/locale/de"), }, ["es"]: { name: "Español", countryCode: "es", fullCode: "es-ES", + djs: () => import("dayjs/locale/es"), }, ["zh"]: { name: "简体中文", countryCode: "cn", fullCode: "zh-CN", + djs: () => import("dayjs/locale/zh-cn"), }, ["zh-Hant"]: { name: "繁體中文", countryCode: "cn", fullCode: "zh-TW", + djs: () => import("dayjs/locale/zh-hk"), }, ["pl"]: { name: "Polski", countryCode: "pl", fullCode: "pl-PL", + djs: () => import("dayjs/locale/pl"), }, ["ru"]: { name: "Русский", countryCode: "ru", fullCode: "ru-RU", + djs: () => import("dayjs/locale/ru"), }, ["cs"]: { name: "Česky", countryCode: "cz", fullCode: "cs-CZ", + djs: () => import("dayjs/locale/cs"), }, ["nb-NO"]: { name: "Norsk bokmål", countryCode: "no", fullCode: "nb-NO", + djs: () => import("dayjs/locale/nb"), }, ["nl"]: { name: "Nederlands", countryCode: "nl", fullCode: "nl-NL", + djs: () => import("dayjs/locale/nl"), }, ["fr"]: { name: "Français", countryCode: "fr", fullCode: "fr-FR", + djs: () => import("dayjs/locale/fr"), }, ["hu"]: { name: "Magyar", countryCode: "hu", fullCode: "hu-HU", + djs: () => import("dayjs/locale/hu"), }, ["it"]: { name: "Italiano", countryCode: "it", fullCode: "it-IT", + djs: () => import("dayjs/locale/it"), }, ["uk"]: { name: "Українська", countryCode: "ua", fullCode: "uk-UA", + djs: () => import("dayjs/locale/uk"), }, ["el"]: { name: "Ελληνικά", countryCode: "gr", fullCode: "el-GR", + djs: () => import("dayjs/locale/el"), }, ["da"]: { name: "Dansk", countryCode: "dk", fullCode: "da-DK", + djs: () => import("dayjs/locale/da"), }, ["pt"]: { name: "Português", countryCode: "pt", fullCode: "pt-PT", + djs: () => import("dayjs/locale/pt"), }, ["fa"]: { name: "فارسی", countryCode: "ir", fullCode: "fa-IR", + djs: () => import("dayjs/locale/fa"), }, ["ro"]: { name: "Român", countryCode: "ro", fullCode: "ro-RO", + djs: () => import("dayjs/locale/ro"), }, }; @@ -134,4 +157,8 @@ i18n fallbackLng: "en", }); +i18n.on("languageChanged", function (lng) { + languages[lng].djs().then((djs) => dayjs.locale(djs.name)); +}); + export default i18n; diff --git a/client/src/pages/locations/components/locationContainer.tsx b/client/src/pages/locations/components/locationContainer.tsx index 1cac77b8..cecb6071 100644 --- a/client/src/pages/locations/components/locationContainer.tsx +++ b/client/src/pages/locations/components/locationContainer.tsx @@ -41,7 +41,7 @@ export function LocationContainer() { const grouped: Record = {}; spools.forEach((spool) => { - const loc = spool.location ?? t("spool.no_location"); + const loc = spool.location ?? t("locations.no_location"); if (!grouped[loc]) { grouped[loc] = []; } @@ -155,12 +155,13 @@ export function LocationContainer() { } const addNewLocation = () => { - let newLocationName = "New Location"; + const baseLocationName = t("locations.new_location"); + let newLocationName = baseLocationName; const newLocs = [...locationsList]; let i = 1; while (newLocs.includes(newLocationName)) { - newLocationName = "New Location " + i; + newLocationName = baseLocationName + " " + i; i++; } newLocs.push(newLocationName); diff --git a/client/src/pages/locations/components/spoolCard.tsx b/client/src/pages/locations/components/spoolCard.tsx index 6da9a605..0f2c7f1c 100644 --- a/client/src/pages/locations/components/spoolCard.tsx +++ b/client/src/pages/locations/components/spoolCard.tsx @@ -4,12 +4,18 @@ import type { Identifier, XYCoord } from "dnd-core"; import { useDrag, useDrop } from "react-dnd"; import { EditOutlined, EyeOutlined } from "@ant-design/icons"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import utc from "dayjs/plugin/utc"; import { useEffect, useRef } from "react"; import { Link } from "react-router-dom"; import SpoolIcon from "../../../components/spoolIcon"; import { ISpool } from "../../spools/model"; import { ItemTypes, SpoolDragItem, useCurrentDraggedSpool } from "../dnd"; +dayjs.extend(utc); +dayjs.extend(relativeTime); + const { useToken } = theme; export function SpoolCard({ @@ -134,6 +140,21 @@ export function SpoolCard({ }; drag(drop(ref)); + function formatSubtitle(spool: ISpool) { + let str = ""; + if (spool.filament.material) str += spool.filament.material + " - "; + if (spool.filament.weight) { + const remaining_weight = spool.remaining_weight ?? spool.filament.weight; + str += `${remaining_weight} / ${spool.filament.weight} g`; + } + if (spool.last_used) { + // Format like "last used X time ago" + const dt = dayjs(spool.last_used); + str += ` - ${t("spool.formats.last_used", { date: dt.fromNow() })}`; + } + return str; + } + return (
@@ -157,7 +178,7 @@ export function SpoolCard({ color: token.colorTextSecondary, }} > - {spool.remaining_weight} / {spool.filament.weight} g + {formatSubtitle(spool)}
From 755e06c98904877f2b6cf850d32826277bf85bfc Mon Sep 17 00:00:00 2001 From: Donkie Date: Sun, 24 Nov 2024 12:31:38 +0100 Subject: [PATCH 13/16] Now goes back to loc page on edit submit --- client/src/components/dataProvider.ts | 2 - client/src/pages/filaments/edit.tsx | 15 ++++---- .../components/locationContainer.tsx | 1 - .../pages/locations/components/spoolCard.tsx | 2 +- client/src/pages/printing/printing.tsx | 10 ++--- client/src/pages/spools/edit.tsx | 15 +++++++- client/src/pages/spools/show.tsx | 37 ++++++++----------- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/client/src/components/dataProvider.ts b/client/src/components/dataProvider.ts index 46e062d8..c140be1e 100644 --- a/client/src/components/dataProvider.ts +++ b/client/src/components/dataProvider.ts @@ -61,8 +61,6 @@ const dataProvider = ( params: queryParams, }); - // console.log(url, requestMethod, queryParams, data, headers) - return { data, total: parseInt(headers["x-total-count"]) ?? 100, diff --git a/client/src/pages/filaments/edit.tsx b/client/src/pages/filaments/edit.tsx index 7d57ff97..53e78105 100644 --- a/client/src/pages/filaments/edit.tsx +++ b/client/src/pages/filaments/edit.tsx @@ -52,7 +52,6 @@ export const FilamentEdit: React.FC = () => { // Update colorType state useEffect(() => { - console.log(formProps.initialValues?.multi_color_hexes); if (formProps.initialValues?.multi_color_hexes) { setColorType("multi"); } else { @@ -325,13 +324,13 @@ export const FilamentEdit: React.FC = () => { diff --git a/client/src/pages/locations/components/locationContainer.tsx b/client/src/pages/locations/components/locationContainer.tsx index cecb6071..dd334aa4 100644 --- a/client/src/pages/locations/components/locationContainer.tsx +++ b/client/src/pages/locations/components/locationContainer.tsx @@ -141,7 +141,6 @@ export function LocationContainer() { useEffect(() => { // Check if they're not the same if (JSON.stringify(locationsList) !== JSON.stringify(settingsLocations)) { - console.log("Updating locations settings", locationsList, settingsLocations); setLocationsSetting.mutate(locationsList); } }, [spoolLocations]); diff --git a/client/src/pages/locations/components/spoolCard.tsx b/client/src/pages/locations/components/spoolCard.tsx index 0f2c7f1c..055e66e3 100644 --- a/client/src/pages/locations/components/spoolCard.tsx +++ b/client/src/pages/locations/components/spoolCard.tsx @@ -164,7 +164,7 @@ export function SpoolCard({ #{spool.id} {filament_name}
- + {record?.archived ? ( - + ) : ( - + )} {defaultButtons} From 0827cc8a5aa10f3e870ab6d832211d0a670039ae Mon Sep 17 00:00:00 2001 From: Donkie Date: Sun, 24 Nov 2024 14:45:16 +0100 Subject: [PATCH 14/16] Improvements to default location --- .../pages/locations/components/location.tsx | 25 ++++++++++--- .../components/locationContainer.tsx | 37 +++++++++++-------- .../pages/locations/components/spoolCard.tsx | 2 +- client/src/pages/locations/functions.ts | 8 ++-- client/src/pages/locations/locations.css | 19 ++++++++-- 5 files changed, 64 insertions(+), 27 deletions(-) diff --git a/client/src/pages/locations/components/location.tsx b/client/src/pages/locations/components/location.tsx index eebd5261..2a569961 100644 --- a/client/src/pages/locations/components/location.tsx +++ b/client/src/pages/locations/components/location.tsx @@ -4,9 +4,10 @@ import { useRef, useState } from "react"; import { useDrag, useDrop } from "react-dnd"; import { DeleteOutlined } from "@ant-design/icons"; -import { useUpdate } from "@refinedev/core"; +import { useTranslate, useUpdate } from "@refinedev/core"; import { ISpool } from "../../spools/model"; import { DragItem, ItemTypes, SpoolDragItem } from "../dnd"; +import { EMPTYLOC } from "../functions"; import { SpoolList } from "./spoolList"; export function Location({ @@ -30,6 +31,7 @@ export function Location({ locationSpoolOrder: number[]; setLocationSpoolOrder: (spoolOrder: number[]) => void; }) { + const t = useTranslate(); const [editTitle, setEditTitle] = useState(false); const [newTitle, setNewTitle] = useState(title); const { mutate: updateSpool } = useUpdate({ @@ -47,9 +49,11 @@ export function Location({ }); }; + const dropTypes = title == EMPTYLOC ? [ItemTypes.SPOOL] : [ItemTypes.CONTAINER, ItemTypes.SPOOL]; + const ref = useRef(null); const [{ handlerId }, drop] = useDrop({ - accept: [ItemTypes.CONTAINER, ItemTypes.SPOOL], + accept: dropTypes, collect(monitor) { return { handlerId: monitor.getHandlerId(), @@ -113,7 +117,7 @@ export function Location({ const [{ isDragging }, drag] = useDrag({ type: ItemTypes.CONTAINER, - canDrag: !editTitle, + canDrag: !editTitle && title != EMPTYLOC, item: () => { return { title, index }; }, @@ -122,11 +126,20 @@ export function Location({ }), }); + const displayTitle = title == EMPTYLOC ? t("locations.no_location") : title; + const opacity = isDragging ? 0 : 1; drag(drop(ref)); + const canEditTitle = title != EMPTYLOC; + return ( -
+

{editTitle ? ( ) : ( { + if (!canEditTitle) return; setNewTitle(title); setEditTitle(true); }} > - {title} + {displayTitle} )} {showDelete &&

); diff --git a/client/src/pages/locations/index.tsx b/client/src/pages/locations/index.tsx index f9f127e8..4c40d52a 100644 --- a/client/src/pages/locations/index.tsx +++ b/client/src/pages/locations/index.tsx @@ -1,4 +1,4 @@ -import { IResourceComponentsProps } from "@refinedev/core"; +import { IResourceComponentsProps, useTranslate } from "@refinedev/core"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; import React from "react"; @@ -11,10 +11,14 @@ import "./locations.css"; dayjs.extend(utc); export const Locations: React.FC = () => { + const t = useTranslate(); return ( - - - +
+

{t("locations.locations")}

+ + + +
); };