From 6db6c866995ad805578ff8bfe0a3e13352771fc1 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:07:51 +0300 Subject: [PATCH 1/2] fix(2163): Saved to local storage --- GUI/src/components/ServicesTable/index.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/GUI/src/components/ServicesTable/index.tsx b/GUI/src/components/ServicesTable/index.tsx index 2daff8cf4..30c84dbac 100644 --- a/GUI/src/components/ServicesTable/index.tsx +++ b/GUI/src/components/ServicesTable/index.tsx @@ -15,6 +15,15 @@ type ServicesTableProps = { isCommon?: boolean; }; +const DEFAULT_PAGE_SIZE = 10; +const PAGE_SIZE_OPTIONS = new Set([10, 20, 30, 50]); +const PAGE_SIZE_STORAGE_KEY = 'page-size'; + +const getStoredPageSize = (): number => { + const stored = Number(localStorage.getItem(PAGE_SIZE_STORAGE_KEY)); + return PAGE_SIZE_OPTIONS.has(stored) ? stored : DEFAULT_PAGE_SIZE; +}; + const ServicesTable: FC = ({ isCommon = false }) => { const { t } = useTranslation(); const [isDeletePopupVisible, setIsDeletePopupVisible] = useState(false); @@ -22,7 +31,7 @@ const ServicesTable: FC = ({ isCommon = false }) => { const navigate = useNavigate(); const [pagination, setPagination] = useState({ pageIndex: 0, - pageSize: 10, + pageSize: getStoredPageSize(), }); const [sorting, setSorting] = useState([{ id: 'name', desc: false }]); @@ -121,6 +130,9 @@ const ServicesTable: FC = ({ isCommon = false }) => { sorting={sorting} setPagination={(state: PaginationState) => { if (state.pageIndex === pagination.pageIndex && state.pageSize === pagination.pageSize) return; + if (state.pageSize !== pagination.pageSize) { + localStorage.setItem(PAGE_SIZE_STORAGE_KEY, String(state.pageSize)); + } setPagination(state); if (isCommon) { loadCommonServices(state, sorting); @@ -137,7 +149,7 @@ const ServicesTable: FC = ({ isCommon = false }) => { } }} isClientSide={false} - pagesCount={services[services.length - 1]?.totalPages ?? 1} + pagesCount={services.at(-1)?.totalPages ?? 1} /> ); From 3a61d23d36313fdc7d9a5896da62712c9615888b Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 26 Aug 2026 04:07:43 +0300 Subject: [PATCH 2/2] chore(1148): Modified overview logic and design --- .../POST/get-services-dependency-data.sql | 9 + DSL/Resql/services/POST/get-services-list.sql | 18 +- .../services/GET/services-dependency-data.yml | 20 + GUI/package-lock.json | 522 +++++++++--------- GUI/package.json | 1 + GUI/src/components/DataTable/DataTable.scss | 25 + GUI/src/components/DataTable/Pagination.tsx | 76 +++ GUI/src/components/DataTable/index.tsx | 142 ++--- .../ServicesTable/DependencyExpandedView.scss | 214 +++++++ .../ServicesTable/DependencyExpandedView.tsx | 238 ++++++++ .../ServicesTable/ServicesTable.scss | 164 +++++- GUI/src/components/ServicesTable/columns.tsx | 301 +++++----- GUI/src/components/ServicesTable/index.tsx | 388 ++++++++++--- .../ServicesTable/service-table-utils.test.ts | 23 + .../ServicesTable/service-table-utils.ts | 32 ++ GUI/src/i18n/en/common.json | 30 + GUI/src/i18n/et/common.json | 30 + GUI/src/pages/OverviewPage.tsx | 12 +- GUI/src/resources/api-constants.ts | 1 + GUI/src/store/services.store.ts | 179 +++--- GUI/src/utils/pinned-services.ts | 111 ++++ GUI/src/utils/service-dependencies.test.ts | 84 +++ GUI/src/utils/service-dependencies.ts | 141 +++++ GUI/src/utils/service-import.ts | 2 +- 24 files changed, 2113 insertions(+), 650 deletions(-) create mode 100644 DSL/Resql/services/POST/get-services-dependency-data.sql create mode 100644 DSL/Ruuter/services/GET/services-dependency-data.yml create mode 100644 GUI/src/components/DataTable/Pagination.tsx create mode 100644 GUI/src/components/ServicesTable/DependencyExpandedView.scss create mode 100644 GUI/src/components/ServicesTable/DependencyExpandedView.tsx create mode 100644 GUI/src/components/ServicesTable/service-table-utils.test.ts create mode 100644 GUI/src/components/ServicesTable/service-table-utils.ts create mode 100644 GUI/src/utils/pinned-services.ts create mode 100644 GUI/src/utils/service-dependencies.test.ts create mode 100644 GUI/src/utils/service-dependencies.ts diff --git a/DSL/Resql/services/POST/get-services-dependency-data.sql b/DSL/Resql/services/POST/get-services-dependency-data.sql new file mode 100644 index 000000000..41a0b00b9 --- /dev/null +++ b/DSL/Resql/services/POST/get-services-dependency-data.sql @@ -0,0 +1,9 @@ +SELECT + service_id, + name, + current_state AS state, + is_common, + structure::json +FROM services +WHERE NOT deleted +ORDER BY name ASC; diff --git a/DSL/Resql/services/POST/get-services-list.sql b/DSL/Resql/services/POST/get-services-list.sql index 903bceedc..878441944 100644 --- a/DSL/Resql/services/POST/get-services-list.sql +++ b/DSL/Resql/services/POST/get-services-list.sql @@ -1,19 +1,29 @@ SELECT + id, service_id, name, description, + examples, + entities, current_state AS state, ruuter_type AS type, + is_common, slot, - CEIL((SELECT COUNT(DISTINCT service_id) FROM services WHERE NOT deleted AND (:is_common::TEXT = '' OR is_common = (:is_common::TEXT)::BOOLEAN) AND (:search IS NULL OR :search = '' OR LOWER(name) LIKE LOWER('%' || :search || '%'))) / :page_size::DECIMAL) AS total_pages + CEIL((SELECT COUNT(DISTINCT service_id) FROM services WHERE NOT deleted AND (:is_common::TEXT = '' OR is_common = (:is_common::TEXT)::BOOLEAN) AND (:search IS NULL OR :search = '' OR LOWER(name) LIKE LOWER('%' || :search || '%') OR LOWER(description) LIKE LOWER('%' || :search || '%'))) / :page_size::DECIMAL) AS total_pages FROM services WHERE NOT deleted AND (:is_common::TEXT = '' OR is_common = (:is_common::TEXT)::BOOLEAN) - AND (:search IS NULL OR :search = '' OR LOWER(name) LIKE LOWER('%' || :search || '%')) -ORDER BY + AND (:search IS NULL OR :search = '' OR LOWER(name) LIKE LOWER('%' || :search || '%') OR LOWER(description) LIKE LOWER('%' || :search || '%')) +ORDER BY + CASE WHEN :search IS NOT NULL AND :search != '' AND LOWER(name) = LOWER(:search) THEN 0 + WHEN :search IS NOT NULL AND :search != '' AND LOWER(name) LIKE LOWER(:search || '%') THEN 1 + WHEN :search IS NOT NULL AND :search != '' AND LOWER(name) LIKE LOWER('%' || :search || '%') THEN 2 + ELSE 3 END, CASE WHEN :sorting = 'name asc' THEN name END ASC, CASE WHEN :sorting = 'name desc' THEN name END DESC, CASE WHEN :sorting = 'state asc' THEN current_state END ASC, CASE WHEN :sorting = 'state desc' THEN current_state END DESC, - name ASC + CASE WHEN :sorting = 'id asc' THEN id END ASC, + CASE WHEN :sorting = 'id desc' THEN id END DESC, + id ASC OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Ruuter/services/GET/services-dependency-data.yml b/DSL/Ruuter/services/GET/services-dependency-data.yml new file mode 100644 index 000000000..799c28b0c --- /dev/null +++ b/DSL/Ruuter/services/GET/services-dependency-data.yml @@ -0,0 +1,20 @@ +declaration: + call: declare + version: 0.1 + description: "Returns all services with structure for dependency graph computation" + method: get + accepts: json + returns: json + namespace: service + +get_services_dependency_data: + call: http.post + args: + url: "[#SERVICE_RESQL]/get-services-dependency-data" + result: results + +return_ok: + status: 200 + wrapper: false + return: ${results.response.body} + next: end diff --git a/GUI/package-lock.json b/GUI/package-lock.json index d548b3eb4..2ab713718 100644 --- a/GUI/package-lock.json +++ b/GUI/package-lock.json @@ -79,6 +79,7 @@ "@types/d3-timer": "^3.0.2", "@types/howler": "^2.2.11", "@types/jsoneditor": "^9.9.6", + "@types/node": "^26.3.0", "@types/react": "^18.2.0", "@types/react-datepicker": "^4.8.0", "@types/react-dom": "^18.2.0", @@ -4457,9 +4458,9 @@ "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" }, "node_modules/@remix-run/router": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.3.tgz", - "integrity": "sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==", + "version": "1.23.4", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.4.tgz", + "integrity": "sha512-q7j5geK7xs3UJSdm9/iytUNclBnLmYx1EnSeCFXHPeutdqgIMeFeHtUZgS3EhlKxdBEAu8OwtJCwmLrEzpSs7Q==", "engines": { "node": ">=14.0.0" } @@ -4534,9 +4535,9 @@ "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", - "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.0.tgz", + "integrity": "sha512-70TeIFezKKy65LgAVyQh+w94/gjWhvPWaLaGGeMEgVrPkQhuj/M5bAYYZzIFUj9Y69oHyTm5Um/R6gcLh4A8JA==", "cpu": [ "arm" ], @@ -4547,9 +4548,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", - "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.0.tgz", + "integrity": "sha512-YC86tYIHK6M1IV+wbzO+Bxk8RCBr6ZyWYgWxUCzaZD8mc8rrFoIJDNzDrkHBYRc/wKdrsIXmm6/F7NzrAO+OrA==", "cpu": [ "arm64" ], @@ -4560,9 +4561,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", - "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.0.tgz", + "integrity": "sha512-oI+ECtUcli0y0fi4xpW82GdPIXdTkI8G8DSjG2LRuw09fPAGykaWYH/hXxiKuTxiAjiPSTIIuYUqof5Z2hShWw==", "cpu": [ "arm64" ], @@ -4573,9 +4574,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", - "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.0.tgz", + "integrity": "sha512-NwV+1s7TiKrMe4owHyKB/dTLD7ZJD0YEBEhIz+hvav1Cu1GReJjF+rsdNwjzENQeIAbE/CoNiaAc5Vz2h5DPAA==", "cpu": [ "x64" ], @@ -4586,9 +4587,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", - "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.0.tgz", + "integrity": "sha512-tWtHBTu5gOPK4u4Urtk4qAHW3zZ9rQAmbssO8gp7ELvGTGI3aCiq6NqyTQ0PCIg7KbHJF2UkGDDs77YZGxfjCA==", "cpu": [ "arm64" ], @@ -4599,9 +4600,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", - "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.0.tgz", + "integrity": "sha512-2qPoJiwTvtHQ27NnYvTnsgk8laXWYuVmNESG8WFZBcEPKLfZ3I27qBJarjVRQtwGeYyRfq5ZowHXih9lm2BItw==", "cpu": [ "x64" ], @@ -4612,9 +4613,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", - "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.0.tgz", + "integrity": "sha512-FQwsTRvLNuHoTdICABJQfbPUSEueISGmnpT06tXTMpfprf5NiKLSXKA0A+w45wJnCmZAnzgqBwbt6ARFuyOi5w==", "cpu": [ "arm" ], @@ -4625,9 +4626,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", - "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.0.tgz", + "integrity": "sha512-BBVTXziw8mY1a4ZbWME9tZyfzqXCDPqaC7Z3heQ29p5dkvXzwL0NwelO8zLa8c3RBKvl3YTuSnBgsBhYBtwjIw==", "cpu": [ "arm" ], @@ -4638,9 +4639,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", - "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.0.tgz", + "integrity": "sha512-w2Iyy9+RqKwx3d9qWMKsJg0FfRBsY0/pXNv0mCQ3ueRvJI6+QAScfD4nrMlzFLs2HNVW6Ew+mtZfDl9b7Ew5/Q==", "cpu": [ "arm64" ], @@ -4651,9 +4652,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", - "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.0.tgz", + "integrity": "sha512-YK++KtrFRHYE0P6/RtYEAy9t8F37znP+K03RrIuLPYOL6SVlObRumf/0OE4V/h63xL9DwkWbNssZfmA9hawuDA==", "cpu": [ "arm64" ], @@ -4664,9 +4665,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", - "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.0.tgz", + "integrity": "sha512-aBfOG6fP7YkkPmTqPwufRJeFyz7WPpECv9XNbnsk9+vg7rxdih0lbtEel7jcRng4LZrrmU3FfitCFyEj4BWDWg==", "cpu": [ "loong64" ], @@ -4677,9 +4678,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", - "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.0.tgz", + "integrity": "sha512-LGaHEOeHNAag9VuS1Crs5DFg4RrU9MPi2nVnNJk9DTePx/B6RRYKVmrIXt2h7YOJlwjaFJ6lwtFDliZxScTLrQ==", "cpu": [ "loong64" ], @@ -4690,9 +4691,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", - "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.0.tgz", + "integrity": "sha512-jClvk+J0FC3b7Udvegiw5/4hErbHtmsNsQgENnKXDWtNCJXsJYZH5WURvu7imDOO38xYml24eeh5x3A04ppwCw==", "cpu": [ "ppc64" ], @@ -4703,9 +4704,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", - "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.0.tgz", + "integrity": "sha512-0OJlaGK+8+B777Ql5okIpD7ua5Ro9+VB9Ve0OKa28OQJZ1RbuUBVNHK/e3pr4BROqsyPl1JrPO1ZxJseCNffcA==", "cpu": [ "ppc64" ], @@ -4716,9 +4717,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", - "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.0.tgz", + "integrity": "sha512-Ygsx+HoNH7afwi1bTIXbnTvVnsO+zurPLSYxybV1hHFVU72OWOCl6v05ql/z0hkpAPx+DK7Kn9Bi7MayCcjLTA==", "cpu": [ "riscv64" ], @@ -4729,9 +4730,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", - "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.0.tgz", + "integrity": "sha512-pDQxtMGb+OvG3fLwR2OkZlSd47hW+kWg4BYMG/++sR6RqorQccwPTDsxda5hPwiIeIErAnCF9ma3SAU06bdQtQ==", "cpu": [ "riscv64" ], @@ -4742,9 +4743,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", - "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.0.tgz", + "integrity": "sha512-0BnUG9mS8I4SSHr3XsxVhuCMEiu+rX61xxZF5vujso4LaiAGFZFxvDjg6Xn6tLPNTUAfuCvQYas4LMQMVsKRSQ==", "cpu": [ "s390x" ], @@ -4755,9 +4756,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", - "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.0.tgz", + "integrity": "sha512-Adu/VttB1dpPNW+FEacrZ+xVm9tFty84+RrFzsqlFaPxoJB+9XXyDGtp5dCOoBwGBIEVH0To7lExFXEx0BIF4A==", "cpu": [ "x64" ], @@ -4768,9 +4769,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", - "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.0.tgz", + "integrity": "sha512-NQ3bDvjUbFKmP23671xUlXtKmqVsUBd6M4PQCvbmNtOy06hnQIdKHy8oG/6S3R/S6He1JgPk6A5VT+prAJMYEw==", "cpu": [ "x64" ], @@ -4781,9 +4782,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", - "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.0.tgz", + "integrity": "sha512-u2eDAl4+0aFvA13GxlGBtTI3SS3sdgwgtV0HyjZ0QaQVCgNE+jqNGey+GtxWiq+wxr/UycAx/OnfJzApCFamvA==", "cpu": [ "x64" ], @@ -4794,9 +4795,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", - "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.0.tgz", + "integrity": "sha512-XvRb5vfW3wAZQ+ZUG21AnHHDKtNcw99eigzEhjr//NZ3u7SoBaPP0seSc7FgP7p1epAEdAoZckMW9WY/+4w70w==", "cpu": [ "arm64" ], @@ -4807,9 +4808,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", - "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.0.tgz", + "integrity": "sha512-iZPmniy4kNBf5yo2RezbkYNNK5HPbXE9+g+twnbqSng7dtLEJy1SKoxiE/ni4FDacjyuZpEeb9U054N4EoKHYw==", "cpu": [ "arm64" ], @@ -4820,9 +4821,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", - "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.0.tgz", + "integrity": "sha512-mFBBd+LF37fnE8JnYUOH+imj0aPFPK30vpar4ehJkgnLj9sZn8ZxiRENmLtgIwxK7TC8klF6N57fxdNBwQoqOA==", "cpu": [ "ia32" ], @@ -4833,9 +4834,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", - "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.0.tgz", + "integrity": "sha512-ujeqEY3B+zbGn3Z4Q03cUBG/LGWnBJncVT36WER31LcOsQk9+1dmINKKtvmmfChUvRbK1G0R8OhMWFgHgaZtAw==", "cpu": [ "x64" ], @@ -4846,9 +4847,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", - "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.0.tgz", + "integrity": "sha512-hncn90N4sOky0L2LKE5oESKLbxCPeVo4eLA2LSMoDzM+879ml4WSr+Rr4DWknNIVVvS1Hirkc9hx02W6YxS8rQ==", "cpu": [ "x64" ], @@ -5247,9 +5248,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.6.4", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.4.tgz", - "integrity": "sha512-QCGwP6QrjypBLwyj5cuyfVamkaIEy/XGY+1VDehbtbQqOggYmTFpFOdWR5mPz14vX8vXLMVjDHlRNBcClyO9ew==", + "version": "14.6.6", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.6.tgz", + "integrity": "sha512-Jbs9FpkkIDw8FgSc6kOVsOv8JuuqGAL7J4X1oot77JxAoDlkNn2GRkd0aYRVuQ+pVQAiHWVkE4rX/dkF5fBiCw==", "dev": true, "engines": { "node": ">=12", @@ -5460,6 +5461,15 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.25.tgz", "integrity": "sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==" }, + "node_modules/@types/node": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz", + "integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==", + "dev": true, + "dependencies": { + "undici-types": "~8.3.0" + } + }, "node_modules/@types/prop-types": { "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", @@ -5520,16 +5530,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.67.0.tgz", - "integrity": "sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.68.0.tgz", + "integrity": "sha512-WASHDpCm6qO5jj9g1a+8NiW5+GCkAyLReR56/4VruYmNgfUmqpxOfZ2Yfb8xGfJPWv5Qi6LSD8sXdces3vbp/Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.67.0", - "@typescript-eslint/type-utils": "8.67.0", - "@typescript-eslint/utils": "8.67.0", - "@typescript-eslint/visitor-keys": "8.67.0", + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/type-utils": "8.68.0", + "@typescript-eslint/utils": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -5542,7 +5552,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.67.0", + "@typescript-eslint/parser": "^8.68.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -5557,15 +5567,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.67.0.tgz", - "integrity": "sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.68.0.tgz", + "integrity": "sha512-fHq2VC1kpyYfvEcbiMjOpySY4WS7voEp89yAThrHRX5sm9j2lzYppCb2umFMEed4fWcyeLjHxrz0mpjNBaBxMQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.67.0", - "@typescript-eslint/types": "8.67.0", - "@typescript-eslint/typescript-estree": "8.67.0", - "@typescript-eslint/visitor-keys": "8.67.0", + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", "debug": "^4.4.3" }, "engines": { @@ -5581,13 +5591,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz", - "integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.68.0.tgz", + "integrity": "sha512-5GQtWZCXFcFYux955pvoS02WLc49pXNlvIxocKjS0clvwo3in1RdlzVKyiqQH9vE5AKWFLTaUgeQkOrTS+0Qxw==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.67.0", - "@typescript-eslint/types": "^8.67.0", + "@typescript-eslint/tsconfig-utils": "^8.68.0", + "@typescript-eslint/types": "^8.68.0", "debug": "^4.4.3" }, "engines": { @@ -5602,13 +5612,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.67.0.tgz", - "integrity": "sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.68.0.tgz", + "integrity": "sha512-T5eXpcaJNg8bhjHJ8Rjp68Vq/QBteYtTKY8TZqVNPaUbuz0f6jI9t6aDkylwvalpAB9XTTFeFOjrjXAZ3YvmVA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.67.0", - "@typescript-eslint/visitor-keys": "8.67.0" + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5619,9 +5629,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz", - "integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.68.0.tgz", + "integrity": "sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5635,14 +5645,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.67.0.tgz", - "integrity": "sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.68.0.tgz", + "integrity": "sha512-X77zqoY1EjeWGs/0JNxeaMfp5C5lIz4Tw8y66F1Ne8Faq6g424sBNYM6xBAqElfGZPLpWS+CZAp0DXyKDzWiHg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.67.0", - "@typescript-eslint/typescript-estree": "8.67.0", - "@typescript-eslint/utils": "8.67.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0", + "@typescript-eslint/utils": "8.68.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -5659,9 +5669,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz", - "integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.68.0.tgz", + "integrity": "sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5672,15 +5682,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz", - "integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.68.0.tgz", + "integrity": "sha512-OKKsD0tYmoNiU5PW2zehO1yO56jYOm1ShYlxon/Z0SJNidAkdVg86eg9ruRuoXf8xfnuWZGbwDsStkoXbZtIIA==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.67.0", - "@typescript-eslint/tsconfig-utils": "8.67.0", - "@typescript-eslint/types": "8.67.0", - "@typescript-eslint/visitor-keys": "8.67.0", + "@typescript-eslint/project-service": "8.68.0", + "@typescript-eslint/tsconfig-utils": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -5747,15 +5757,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.67.0.tgz", - "integrity": "sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.68.0.tgz", + "integrity": "sha512-PB5gJMMOg0Q5P1tsgWtEAqQacJXq0qEqRHDX/YJ4FaTMLfZPpHB3gjl2EJuiZyPABxmj4ZQYiY9m1bdAJ5y7tQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.67.0", - "@typescript-eslint/types": "8.67.0", - "@typescript-eslint/typescript-estree": "8.67.0" + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5770,12 +5780,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz", - "integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.68.0.tgz", + "integrity": "sha512-YR65gGdGvTUAWLldC3xLOvOzamdGzB4A5/N8rehEaHs3Zvoe39BhgY+u0SPch1OvrVTfLcc55wsSgK2NcnTS/A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/types": "8.68.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -5981,11 +5991,11 @@ } }, "node_modules/@xyflow/react": { - "version": "12.11.3", - "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.11.3.tgz", - "integrity": "sha512-G3jogHz2GWUtIOkhavUGno2YzY9u6fILIJBttfsBendb0/HWB90JG+sOTAvlIMEwyvq9zgy9V9ZQSwyQjR5QzQ==", + "version": "12.11.5", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.11.5.tgz", + "integrity": "sha512-QqoryGkqEhWBuQN9bZWRKhwr3Uoj9lCGj/tg0NnIWHHEOXV+5c8cYsc7Q9TST63V92lHqcNV9P5cjvJ9ZAmblQ==", "dependencies": { - "@xyflow/system": "0.0.80", + "@xyflow/system": "0.0.81", "classcat": "^5.0.3", "zustand": "^4.4.0" }, @@ -6005,9 +6015,9 @@ } }, "node_modules/@xyflow/system": { - "version": "0.0.80", - "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.80.tgz", - "integrity": "sha512-ywc3ZqG91brzWrH1WlwMdIX4goOfrpBy6AbLdVSaof/Xx9l138ijIKRExM6EkMro2F+OImGmSiA/WKcXvKVcfA==", + "version": "0.0.81", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.81.tgz", + "integrity": "sha512-hfbafW4i7uLq7ILok8QWFFm4KMFw22lbZNJHKfHOMSOOoCk5e5m8yfr84UV9NaJajmogWaLVnp2XFU9JQejlqg==", "dependencies": { "@types/d3-drag": "^3.0.7", "@types/d3-interpolate": "^3.0.4", @@ -6414,9 +6424,9 @@ "dev": true }, "node_modules/baseline-browser-mapping": { - "version": "2.11.13", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", - "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", + "version": "2.11.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz", + "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==", "dev": true, "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -6571,9 +6581,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001809", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", - "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true, "funding": [ { @@ -7031,9 +7041,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.21", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz", - "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==" + "version": "1.11.23", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz", + "integrity": "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==" }, "node_modules/debug": { "version": "4.4.3", @@ -7280,9 +7290,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.405", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.405.tgz", - "integrity": "sha512-bNglH7lPH5l+yHOes7Zr4VqxhOy4BQ9ZBUX4VdoFgxMpzJk7W1ZoO3Vgd9Pxa9PyjQ76sfm2aKH/nzEcCNRlew==", + "version": "1.5.415", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz", + "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==", "dev": true }, "node_modules/emoji-regex": { @@ -7570,6 +7580,7 @@ "version": "9.39.5", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", @@ -8074,9 +8085,9 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", - "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", "funding": [ { "type": "github", @@ -9065,9 +9076,9 @@ } }, "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==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.1.0.tgz", + "integrity": "sha512-bUi/yjmtKYcRVUtWRGr0UA6xEFh2I6zWUwMrUXB3s7bmYCaZ8a+0ZsTRkrawh/mzlSD1Y0Ph8bp/U+TvBpWDNw==", "engines": { "node": ">=0.10.0" } @@ -10314,9 +10325,9 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "devOptional": true, "engines": { "node": ">=12" @@ -10679,9 +10690,9 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-hook-form": { - "version": "7.85.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.85.0.tgz", - "integrity": "sha512-U2MTriFXnclmV4rOE20p2DcRFv5WEg3FIcBFOKcOLFHDVvGIMPvLTkTWefUsonmlaVy23khVDxDWym6uJVGOzw==", + "version": "7.86.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.86.0.tgz", + "integrity": "sha512-4kbWJrh5jPZt1+YqVcXcGKffGcXV/XVbozknLh0Yjh0KhpoAkus21TAQhzRYqNwFkkObmnSvRlZZ3GT+ehoIrA==", "engines": { "node": ">=18.0.0" }, @@ -10857,11 +10868,11 @@ } }, "node_modules/react-router": { - "version": "6.30.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.4.tgz", - "integrity": "sha512-SVUsDe+DybHM/WmYKIVYhZh1o5Dcuf16yM6WjG02Q9XVFMZIJyHYhwrr6bFBXZkVP6z69kNkMyBCujt8FaFLJA==", + "version": "6.30.6", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.6.tgz", + "integrity": "sha512-5HfK7k5im7LTOB0EqCQmfvy4C13G92Ssj1VTmouTK3AJvyjKTnFuCV0vcMAD/JS+JC4DvDIBRrlAeJIFjh5VWg==", "dependencies": { - "@remix-run/router": "1.23.3" + "@remix-run/router": "1.23.4" }, "engines": { "node": ">=14.0.0" @@ -10871,12 +10882,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.30.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.4.tgz", - "integrity": "sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==", + "version": "6.30.6", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.6.tgz", + "integrity": "sha512-0RHKZz7wwffvkU+2MFVT2NnjK44ssLEV+m0CAJaS2Ksmorrwj7WxH00jO0SOCW26/tINUnJHToXblDs33I38YQ==", "dependencies": { - "@remix-run/router": "1.23.3", - "react-router": "6.30.4" + "@remix-run/router": "1.23.4", + "react-router": "6.30.6" }, "engines": { "node": ">=14.0.0" @@ -11239,9 +11250,9 @@ "dev": true }, "node_modules/sanitize-html": { - "version": "2.17.6", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.6.tgz", - "integrity": "sha512-M4bo9tfv1yfhQZZKkc6dL07ALrGJtfvNOuhX3hU9AVPR/uPQ+nKOJBqTYc7LfMQblTW04mtSWDJWEyLvygJsLA==", + "version": "2.17.7", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.7.tgz", + "integrity": "sha512-PGtEkc9cbnedU3s9TmzDbpsZ8w086g/0Q8k8/oIO1NLNU3i5k9yn835CrjJSajp1KMmkisbO1qPXxNKO3welAg==", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", @@ -11256,9 +11267,9 @@ } }, "node_modules/sass": { - "version": "1.102.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", - "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==", + "version": "1.103.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.103.1.tgz", + "integrity": "sha512-9icZURbP51S6S0QGoyaeqk9uB06GNWxsFYWfH5RgpFgqK5FA8tJcM3AdVxrZEVJ7dz+L87nG95gBKf4VuaMHGw==", "dependencies": { "chokidar": "^5.0.0", "immutable": "^5.1.5", @@ -11761,9 +11772,9 @@ } }, "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", "dev": true, "engines": { "node": ">=12" @@ -11848,10 +11859,13 @@ } }, "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.1.0.tgz", + "integrity": "sha512-bwLf38YmY+TDYHJw1Ex0Co8c4yeXuJAo8YnXGZrscxrvYoVVIvLeniEkV1Ks/54VteMnL4FtyN1+P+TZJdUPmQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/symbol-tree": { "version": "3.2.4", @@ -12225,15 +12239,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.67.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.67.0.tgz", - "integrity": "sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.68.0.tgz", + "integrity": "sha512-MHy0Y0ynqeEbx/S45+i/bBssdy3X6KNBfmJAP35GrgtNxu2TQ5K5xsFDhAnmsq1jvpdoZOPG1LGtJo0HWqYCrQ==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.67.0", - "@typescript-eslint/parser": "8.67.0", - "@typescript-eslint/typescript-estree": "8.67.0", - "@typescript-eslint/utils": "8.67.0" + "@typescript-eslint/eslint-plugin": "8.68.0", + "@typescript-eslint/parser": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0", + "@typescript-eslint/utils": "8.68.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12265,6 +12279,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -12940,9 +12960,9 @@ } }, "node_modules/vite-node/node_modules/rollup": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", - "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.0.tgz", + "integrity": "sha512-T5vnZ2y4QqC3/4P+w2+JO+Q/OVdnPsv4XcSYJYMEn0R9/jjl5AgLwO9LAZMzP2lN71O6pypn91rB7lDstUkfrQ==", "dev": true, "dependencies": { "@types/estree": "1.0.9" @@ -12956,31 +12976,31 @@ }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.62.4", - "@rollup/rollup-android-arm64": "4.62.4", - "@rollup/rollup-darwin-arm64": "4.62.4", - "@rollup/rollup-darwin-x64": "4.62.4", - "@rollup/rollup-freebsd-arm64": "4.62.4", - "@rollup/rollup-freebsd-x64": "4.62.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", - "@rollup/rollup-linux-arm-musleabihf": "4.62.4", - "@rollup/rollup-linux-arm64-gnu": "4.62.4", - "@rollup/rollup-linux-arm64-musl": "4.62.4", - "@rollup/rollup-linux-loong64-gnu": "4.62.4", - "@rollup/rollup-linux-loong64-musl": "4.62.4", - "@rollup/rollup-linux-ppc64-gnu": "4.62.4", - "@rollup/rollup-linux-ppc64-musl": "4.62.4", - "@rollup/rollup-linux-riscv64-gnu": "4.62.4", - "@rollup/rollup-linux-riscv64-musl": "4.62.4", - "@rollup/rollup-linux-s390x-gnu": "4.62.4", - "@rollup/rollup-linux-x64-gnu": "4.62.4", - "@rollup/rollup-linux-x64-musl": "4.62.4", - "@rollup/rollup-openbsd-x64": "4.62.4", - "@rollup/rollup-openharmony-arm64": "4.62.4", - "@rollup/rollup-win32-arm64-msvc": "4.62.4", - "@rollup/rollup-win32-ia32-msvc": "4.62.4", - "@rollup/rollup-win32-x64-gnu": "4.62.4", - "@rollup/rollup-win32-x64-msvc": "4.62.4", + "@rollup/rollup-android-arm-eabi": "4.63.0", + "@rollup/rollup-android-arm64": "4.63.0", + "@rollup/rollup-darwin-arm64": "4.63.0", + "@rollup/rollup-darwin-x64": "4.63.0", + "@rollup/rollup-freebsd-arm64": "4.63.0", + "@rollup/rollup-freebsd-x64": "4.63.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.0", + "@rollup/rollup-linux-arm-musleabihf": "4.63.0", + "@rollup/rollup-linux-arm64-gnu": "4.63.0", + "@rollup/rollup-linux-arm64-musl": "4.63.0", + "@rollup/rollup-linux-loong64-gnu": "4.63.0", + "@rollup/rollup-linux-loong64-musl": "4.63.0", + "@rollup/rollup-linux-ppc64-gnu": "4.63.0", + "@rollup/rollup-linux-ppc64-musl": "4.63.0", + "@rollup/rollup-linux-riscv64-gnu": "4.63.0", + "@rollup/rollup-linux-riscv64-musl": "4.63.0", + "@rollup/rollup-linux-s390x-gnu": "4.63.0", + "@rollup/rollup-linux-x64-gnu": "4.63.0", + "@rollup/rollup-linux-x64-musl": "4.63.0", + "@rollup/rollup-openbsd-x64": "4.63.0", + "@rollup/rollup-openharmony-arm64": "4.63.0", + "@rollup/rollup-win32-arm64-msvc": "4.63.0", + "@rollup/rollup-win32-ia32-msvc": "4.63.0", + "@rollup/rollup-win32-x64-gnu": "4.63.0", + "@rollup/rollup-win32-x64-msvc": "4.63.0", "fsevents": "~2.3.2" } }, @@ -13563,9 +13583,9 @@ } }, "node_modules/vitest/node_modules/rollup": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", - "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "version": "4.63.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.0.tgz", + "integrity": "sha512-T5vnZ2y4QqC3/4P+w2+JO+Q/OVdnPsv4XcSYJYMEn0R9/jjl5AgLwO9LAZMzP2lN71O6pypn91rB7lDstUkfrQ==", "dev": true, "dependencies": { "@types/estree": "1.0.9" @@ -13579,31 +13599,31 @@ }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.62.4", - "@rollup/rollup-android-arm64": "4.62.4", - "@rollup/rollup-darwin-arm64": "4.62.4", - "@rollup/rollup-darwin-x64": "4.62.4", - "@rollup/rollup-freebsd-arm64": "4.62.4", - "@rollup/rollup-freebsd-x64": "4.62.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", - "@rollup/rollup-linux-arm-musleabihf": "4.62.4", - "@rollup/rollup-linux-arm64-gnu": "4.62.4", - "@rollup/rollup-linux-arm64-musl": "4.62.4", - "@rollup/rollup-linux-loong64-gnu": "4.62.4", - "@rollup/rollup-linux-loong64-musl": "4.62.4", - "@rollup/rollup-linux-ppc64-gnu": "4.62.4", - "@rollup/rollup-linux-ppc64-musl": "4.62.4", - "@rollup/rollup-linux-riscv64-gnu": "4.62.4", - "@rollup/rollup-linux-riscv64-musl": "4.62.4", - "@rollup/rollup-linux-s390x-gnu": "4.62.4", - "@rollup/rollup-linux-x64-gnu": "4.62.4", - "@rollup/rollup-linux-x64-musl": "4.62.4", - "@rollup/rollup-openbsd-x64": "4.62.4", - "@rollup/rollup-openharmony-arm64": "4.62.4", - "@rollup/rollup-win32-arm64-msvc": "4.62.4", - "@rollup/rollup-win32-ia32-msvc": "4.62.4", - "@rollup/rollup-win32-x64-gnu": "4.62.4", - "@rollup/rollup-win32-x64-msvc": "4.62.4", + "@rollup/rollup-android-arm-eabi": "4.63.0", + "@rollup/rollup-android-arm64": "4.63.0", + "@rollup/rollup-darwin-arm64": "4.63.0", + "@rollup/rollup-darwin-x64": "4.63.0", + "@rollup/rollup-freebsd-arm64": "4.63.0", + "@rollup/rollup-freebsd-x64": "4.63.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.0", + "@rollup/rollup-linux-arm-musleabihf": "4.63.0", + "@rollup/rollup-linux-arm64-gnu": "4.63.0", + "@rollup/rollup-linux-arm64-musl": "4.63.0", + "@rollup/rollup-linux-loong64-gnu": "4.63.0", + "@rollup/rollup-linux-loong64-musl": "4.63.0", + "@rollup/rollup-linux-ppc64-gnu": "4.63.0", + "@rollup/rollup-linux-ppc64-musl": "4.63.0", + "@rollup/rollup-linux-riscv64-gnu": "4.63.0", + "@rollup/rollup-linux-riscv64-musl": "4.63.0", + "@rollup/rollup-linux-s390x-gnu": "4.63.0", + "@rollup/rollup-linux-x64-gnu": "4.63.0", + "@rollup/rollup-linux-x64-musl": "4.63.0", + "@rollup/rollup-openbsd-x64": "4.63.0", + "@rollup/rollup-openharmony-arm64": "4.63.0", + "@rollup/rollup-win32-arm64-msvc": "4.63.0", + "@rollup/rollup-win32-ia32-msvc": "4.63.0", + "@rollup/rollup-win32-x64-gnu": "4.63.0", + "@rollup/rollup-win32-x64-msvc": "4.63.0", "fsevents": "~2.3.2" } }, diff --git a/GUI/package.json b/GUI/package.json index cf38d0b0f..730267b80 100644 --- a/GUI/package.json +++ b/GUI/package.json @@ -104,6 +104,7 @@ "@types/d3-timer": "^3.0.2", "@types/howler": "^2.2.11", "@types/jsoneditor": "^9.9.6", + "@types/node": "^26.3.0", "@types/react": "^18.2.0", "@types/react-datepicker": "^4.8.0", "@types/react-dom": "^18.2.0", diff --git a/GUI/src/components/DataTable/DataTable.scss b/GUI/src/components/DataTable/DataTable.scss index ec59e0346..99527b078 100644 --- a/GUI/src/components/DataTable/DataTable.scss +++ b/GUI/src/components/DataTable/DataTable.scss @@ -31,6 +31,15 @@ position: relative; } + &--sticky-header { + thead th { + position: sticky; + top: 0; + z-index: 2; + background-color: get-color(white); + } + } + td { padding: 12px 24px 12px 16px; border-bottom: 1px solid get-color(black-coral-2); @@ -69,6 +78,18 @@ } } + &__empty { + text-align: center; + padding: 32px 16px; + color: get-color(black-coral-11); + font-style: italic; + } + + &__sub-row-cell { + padding: 0 !important; + border-bottom: 1px solid get-color(black-coral-2); + } + &__filter { position: absolute; top: 100%; @@ -201,6 +222,10 @@ th { color: var(--dark-text-primary); } + + &.data-table--sticky-header thead th { + background-color: var(--dark-bg-light); + } &__pagination-wrapper { background-color: var(--dark-bg-highlight); } diff --git a/GUI/src/components/DataTable/Pagination.tsx b/GUI/src/components/DataTable/Pagination.tsx new file mode 100644 index 000000000..acbffe084 --- /dev/null +++ b/GUI/src/components/DataTable/Pagination.tsx @@ -0,0 +1,76 @@ +import clsx from 'clsx'; +import { FC, useId } from 'react'; +import { useTranslation } from 'react-i18next'; +import { MdOutlineEast, MdOutlineWest } from 'react-icons/md'; +import { Link } from 'react-router-dom'; + +import './DataTable.scss'; + +type TablePaginationProps = { + pageIndex: number; + pageSize: number; + pageCount: number; + onPageChange: (pageIndex: number) => void; + onPageSizeChange: (pageSize: number) => void; + alwaysShow?: boolean; +}; + +const TablePagination: FC = ({ + pageIndex, + pageSize, + pageCount, + onPageChange, + onPageSizeChange, + alwaysShow = false, +}) => { + const id = useId(); + const { t } = useTranslation(); + const safePageCount = Math.max(pageCount, 1); + const showPagination = alwaysShow || safePageCount * pageSize > pageSize; + + if (!showPagination) return null; + + return ( +
+
+ + + +
+
+ + +
+
+ ); +}; + +export default TablePagination; diff --git a/GUI/src/components/DataTable/index.tsx b/GUI/src/components/DataTable/index.tsx index dc417fa13..c9ea5ae3e 100644 --- a/GUI/src/components/DataTable/index.tsx +++ b/GUI/src/components/DataTable/index.tsx @@ -18,12 +18,11 @@ import { } from '@tanstack/react-table'; import clsx from 'clsx'; import { Icon, Track } from 'components'; -import React, { CSSProperties, FC, ReactNode, useId } from 'react'; -import { useTranslation } from 'react-i18next'; -import { MdExpandLess, MdExpandMore, MdOutlineEast, MdOutlineWest, MdUnfoldMore } from 'react-icons/md'; -import { Link } from 'react-router-dom'; +import React, { CSSProperties, FC, ReactNode } from 'react'; +import { MdExpandLess, MdExpandMore, MdUnfoldMore } from 'react-icons/md'; import Filter from './Filter'; +import TablePagination from './Pagination'; import './DataTable.scss'; type DataTableProps = { @@ -48,6 +47,10 @@ type DataTableProps = { meta?: TableMeta; withScrollWrapper?: boolean; renderSubRow?: (row: Row) => ReactNode; + renderBeforeRow?: (row: Row, index: number) => ReactNode; + stickyHeader?: boolean; + hidePagination?: boolean; + emptyMessage?: string; alwaysShowPagination?: boolean; }; @@ -63,7 +66,8 @@ declare module '@tanstack/table-core' { declare module '@tanstack/react-table' { interface TableMeta { - getRowStyles: (row: Row) => CSSProperties; + getRowStyles?: (row: Row) => CSSProperties; + getRowProps?: (row: Row) => Record; onRowClick?: (row: Row) => void; } } @@ -98,10 +102,12 @@ const DataTable: FC = ({ meta, withScrollWrapper = true, renderSubRow, + renderBeforeRow, + stickyHeader = false, + hidePagination = false, + emptyMessage, alwaysShowPagination = false, }) => { - const id = useId(); - const { t } = useTranslation(); const tablePagination = pagination ?? { pageIndex: 0, pageSize: 10, @@ -151,7 +157,7 @@ const DataTable: FC = ({ className={`data-table${withScrollWrapper ? '__scrollWrapper' : ''}`} style={withScrollWrapper ? undefined : { overflowX: 'hidden' }} > - +
{!disableHead && ( {table.getHeaderGroups().map((headerGroup) => ( @@ -161,7 +167,7 @@ const DataTable: FC = ({ {header.isPlaceholder ? null : ( {sortable && header.column.getCanSort() && ( - {tableBodyPrefix} - {table.getRowModel().rows.map((row) => ( - - table.options.meta?.onRowClick?.(row)}> - {row.getVisibleCells().map((cell) => ( - - ))} - - {renderSubRow && ( - - + + ) : ( + table.getRowModel().rows.map((row, index) => { + const subRowContent = renderSubRow?.(row); + const beforeRowContent = renderBeforeRow?.(row, index); + return ( + + {beforeRowContent} + table.options.meta?.onRowClick?.(row)} > - {renderSubRow(row)} - - - )} - - ))} + {row.getVisibleCells().map((cell) => ( + + ))} + + {subRowContent && ( + + + + )} + + ); + }) + )}
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
+ + {emptyMessage} +
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+ {subRowContent} +
- {tablePagination && ( -
- {(alwaysShowPagination || - table.getPageCount() * table.getState().pagination.pageSize > table.getState().pagination.pageSize) && ( -
- - - -
- )} -
- - -
-
+ {tablePagination && !hidePagination && ( + table.setPageIndex(pageIndex)} + onPageSizeChange={(pageSize) => table.setPageSize(pageSize)} + /> )} ); diff --git a/GUI/src/components/ServicesTable/DependencyExpandedView.scss b/GUI/src/components/ServicesTable/DependencyExpandedView.scss new file mode 100644 index 000000000..a27d156b7 --- /dev/null +++ b/GUI/src/components/ServicesTable/DependencyExpandedView.scss @@ -0,0 +1,214 @@ +.dependency-expanded-view { + display: grid; + grid-template-columns: minmax(0, 1fr) 32px minmax(0, 1fr) 32px minmax(0, 1fr); + gap: 4px; + align-items: start; + padding: 16px; + background-color: #f9fafb; + border-radius: 0; + + &--loopback { + background-color: #f5f8fc; + border: 1px dashed #8f91a8; + } +} + +.dependency-column { + min-width: 0; + + &--current { + .dependency-column__nodes--centered { + justify-content: center; + min-height: 44px; + } + } + + &__title { + font-size: 12px; + font-weight: 600; + color: #555867; + margin: 0 0 8px; + } + + &__loopback-note { + margin: 8px 0 0; + font-size: 12px; + color: #555867; + font-style: italic; + } + + &__nodes { + display: flex; + flex-direction: column; + gap: 8px; + + &--scroll { + max-height: calc(5 * 44px + 4 * 8px); + overflow-y: auto; + } + } + + &__empty { + font-size: 13px; + color: #8f91a8; + margin: 0; + font-style: italic; + padding: 12px 0; + } +} + +.dependency-flow-lines { + display: flex; + flex-direction: column; + gap: 8px; + padding-top: 28px; + + &--incoming, + &--outgoing { + justify-content: flex-start; + } +} + +.dependency-flow-line { + display: flex; + align-items: center; + height: 44px; + flex-shrink: 0; + + &--spacer { + visibility: hidden; + } + + &__shaft { + flex: 1; + height: 2px; + background-color: #b4b5c6; + } + + &__arrow { + width: 0; + height: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + } + + &--incoming { + .dependency-flow-line__arrow { + border-left: 7px solid #b4b5c6; + } + } + + &--outgoing { + flex-direction: row-reverse; + + .dependency-flow-line__arrow { + border-right: 7px solid #b4b5c6; + } + } +} + +.dependency-node { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: #fff; + border: 1px solid #d2d3d8; + border-radius: 4px; + min-height: 44px; + + &--deleted { + border-color: #d73e3e; + background: #fdf5f5; + + .dependency-node__name { + text-decoration: line-through; + color: #8f91a8; + } + + .dependency-node__count { + opacity: 0.4; + pointer-events: none; + } + } + + &--loopback { + border-color: #8f91a8; + border-style: dashed; + } + + &--current { + border-color: #005aa3; + border-width: 2px; + background: #eef4fa; + box-shadow: 0 0 0 1px rgba(0, 90, 163, 0.15); + } + + &__name { + flex: 1; + min-width: 0; + text-align: left; + background: none; + border: none; + padding: 0; + color: #005aa3; + cursor: pointer; + font: inherit; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + &:disabled { + cursor: default; + } + } + + &__counts { + flex-shrink: 0; + } + + &__count { + background: none; + border: none; + color: #555867; + cursor: pointer; + font-size: 12px; + padding: 2px 4px; + + &:disabled { + cursor: default; + opacity: 0.5; + } + } +} + +[data-theme='dark'] { + .dependency-expanded-view { + background-color: var(--dark-bg-extra-light); + + &--loopback { + background-color: var(--dark-bg-light); + } + } + + .dependency-node { + background: var(--dark-bg-light); + border-color: var(--dark-border); + + &--deleted { + background: rgba(215, 62, 62, 0.1); + } + } + + .dependency-flow-line__shaft { + background-color: #8f91a8; + } + + .dependency-flow-line--incoming .dependency-flow-line__arrow { + border-left-color: #8f91a8; + } + + .dependency-flow-line--outgoing .dependency-flow-line__arrow { + border-right-color: #8f91a8; + } +} diff --git a/GUI/src/components/ServicesTable/DependencyExpandedView.tsx b/GUI/src/components/ServicesTable/DependencyExpandedView.tsx new file mode 100644 index 000000000..e800a1fd4 --- /dev/null +++ b/GUI/src/components/ServicesTable/DependencyExpandedView.tsx @@ -0,0 +1,238 @@ +import { Icon, Track } from '@buerokratt-ria/header/src/components'; +import { Row } from '@tanstack/react-table'; +import Label from 'components/Label'; +import i18n from 'i18n'; +import { FC } from 'react'; +import { MdLoop } from 'react-icons/md'; +import { NavigateFunction } from 'react-router-dom'; +import { ROUTES } from 'resources/routes-constants'; +import useServiceListStore from 'store/services.store'; +import { Service, ServiceState } from 'types'; +import { DependencyReference, hasLoopbackReference } from 'utils/service-dependencies'; + +import './DependencyExpandedView.scss'; + +const MAX_VISIBLE_NODES = 5; +const NODE_HEIGHT = 44; +const NODE_GAP = 8; + +interface DependencyExpandedViewProps { + readonly row: Row; + readonly navigate: NavigateFunction; + readonly onFocusService: (serviceId: string) => void; + readonly onStateClick: (service: Service) => void; +} + +const getLabelType = (serviceState: ServiceState) => { + switch (serviceState) { + case ServiceState.Ready: + return 'warning-dark'; + case ServiceState.Active: + return 'success-light'; + case ServiceState.Draft: + return 'disabled'; + case ServiceState.Inactive: + return 'warning-dark'; + default: + return 'info'; + } +}; + +const toService = (node: DependencyReference): Service => ({ + serviceId: node.serviceId, + name: node.name, + state: (node.state as ServiceState) ?? ServiceState.Draft, + isCommon: node.isCommon ?? false, + type: 'POST', + id: 0, + slot: '', + examples: [], + entities: [], + totalPages: 1, + endpoints: [], +}); + +const DependencyNode: FC<{ + readonly node: DependencyReference; + readonly navigate: NavigateFunction; + readonly onFocusService: (serviceId: string) => void; + readonly onStateClick?: (service: Service) => void; + readonly dependencyMap: ReturnType['dependencyMap']; + readonly isCurrent?: boolean; +}> = ({ node, navigate, onFocusService, onStateClick, dependencyMap, isCurrent = false }) => { + const isDeleted = node.status === 'deleted'; + const isLoopback = node.isSelfReference; + const incomingCount = dependencyMap[node.serviceId]?.incoming.length ?? 0; + const outgoingCount = dependencyMap[node.serviceId]?.outgoing.length ?? 0; + + const handleNameClick = () => { + if (isDeleted) return; + useServiceListStore.getState().setSelectedService(toService(node)); + navigate(ROUTES.replaceWithId(ROUTES.EDITSERVICE_ROUTE, node.serviceId)); + }; + + return ( +
+ {isLoopback && ( + } size="small" aria-label={i18n.t('overview.dependencies.loopback') as string} /> + )} + + {isDeleted ? ( + + ) : ( + node.state && ( + onStateClick?.(toService(node))}> + + + ) + )} + + + + +
+ ); +}; + +const FlowLine: FC<{ direction: 'incoming' | 'outgoing' }> = ({ direction }) => ( + +); + +const NodeStack: FC<{ + readonly title: string; + readonly nodes: DependencyReference[]; + readonly emptyLabel: string; + readonly navigate: NavigateFunction; + readonly onFocusService: (serviceId: string) => void; + readonly onStateClick: (service: Service) => void; + readonly dependencyMap: ReturnType['dependencyMap']; +}> = ({ title, nodes, emptyLabel, navigate, onFocusService, onStateClick, dependencyMap }) => { + const needsScroll = nodes.length > MAX_VISIBLE_NODES; + + return ( +
+

{title}

+
+ {nodes.length === 0 ? ( +

{emptyLabel}

+ ) : ( + nodes.map((node) => ( + + )) + )} +
+
+ ); +}; + +const DependencyExpandedView: FC = ({ row, navigate, onFocusService, onStateClick }) => { + const dependencyMap = useServiceListStore((state) => state.dependencyMap); + const service = row.original; + const dependencies = dependencyMap[service.serviceId] ?? { incoming: [], outgoing: [] }; + const isLoopback = hasLoopbackReference(dependencyMap, service.serviceId); + + const currentNode: DependencyReference = { + serviceId: service.serviceId, + name: service.name, + state: service.state, + isCommon: service.isCommon, + status: 'active', + }; + + const rowCount = Math.max(dependencies.incoming.length, dependencies.outgoing.length, 1); + + return ( +
+ + +
+ {dependencies.incoming.length > 0 + ? dependencies.incoming.map((node) => ) + : rowCount > 0 &&
} +
+ +
+

{i18n.t('overview.dependencies.currentService')}

+
+ +
+ {isLoopback && ( +

{i18n.t('overview.dependencies.loopbackNote')}

+ )} +
+ +
+ {dependencies.outgoing.length > 0 + ? dependencies.outgoing.map((node) => ) + : rowCount > 0 &&
} +
+ + +
+ ); +}; + +export default DependencyExpandedView; diff --git a/GUI/src/components/ServicesTable/ServicesTable.scss b/GUI/src/components/ServicesTable/ServicesTable.scss index 2ee983c6a..77e006fab 100644 --- a/GUI/src/components/ServicesTable/ServicesTable.scss +++ b/GUI/src/components/ServicesTable/ServicesTable.scss @@ -1,5 +1,154 @@ @import 'src/styles/settings/variables/_colors'; +.services-table__search { + position: relative; + margin-bottom: 16px; + + .input { + width: 100%; + } + + .input__wrapper input { + padding-left: 40px; + padding-right: 36px; + } +} + +.services-table__search-icon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #8f91a8; + pointer-events: none; + z-index: 1; + display: flex; + align-items: center; +} + +.services-table__search-clear { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + font-size: 20px; + line-height: 1; + cursor: pointer; + color: #8f91a8; +} + +.services-table { + display: flex; + flex-direction: column; + max-height: calc(100vh - 280px); + min-height: 480px; + + &__content { + flex: 1; + min-height: 0; + overflow-y: auto; + padding: 0 16px; + + .data-table { + margin-bottom: 0; + } + } + + .data-table__pagination-wrapper { + flex-shrink: 0; + border-top: 1px solid #e5e7eb; + background: #fff; + } + + &__section-row { + td { + padding: 8px 16px 4px; + font-size: 11px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + color: #8f91a8; + background: #f5f8fc; + border-bottom: none; + } + } + + &__expand-btn { + display: inline-flex; + align-items: center; + justify-content: center; + background: none; + border: none; + padding: 0; + cursor: pointer; + color: rgba(0, 0, 0, 0.54); + flex-shrink: 0; + } + + &__name-link { + cursor: pointer; + color: #005aa3; + background: none; + border: none; + padding: 0; + font: inherit; + text-align: left; + } + + &__info-icon { + margin-left: 4px; + cursor: help; + flex-shrink: 0; + } + + &__dependency-panel { + margin: 0 -8px 8px; + padding: 0 8px; + border-top: 1px solid #d2d3d8; + background: #f9fafb; + } +} + +.dependency-count-btn { + display: inline-flex; + align-items: center; + gap: 6px; + background: none; + border: none; + color: #555867; + cursor: pointer; + font: inherit; + font-size: 14px; + font-weight: 400; + padding: 0; + min-width: auto; + + &__count { + min-width: 1ch; + } + + .icon { + color: #8f91a8; + } + + &:hover { + color: #005aa3; + + .icon { + color: #005aa3; + } + } +} + +.service-state-btn { + background: none; + border: none; + padding: 0; + cursor: pointer; +} + .data-table { td { padding-right: 0; @@ -14,8 +163,21 @@ } } -[dark-theme='dark'] .data-table { +[dark-theme='dark'] .data-table, +[data-theme='dark'] .services-table { .icon { color: var(--dark-text-label); } + + .data-table__pagination-wrapper { + border-color: var(--dark-border); + background: var(--dark-bg-light); + } +} + +[data-theme='dark'] .services-table__search { + .services-table__search-icon, + .services-table__search-clear { + color: var(--dark-text-label); + } } diff --git a/GUI/src/components/ServicesTable/columns.tsx b/GUI/src/components/ServicesTable/columns.tsx index 0e1b95df4..59b11ccc3 100644 --- a/GUI/src/components/ServicesTable/columns.tsx +++ b/GUI/src/components/ServicesTable/columns.tsx @@ -4,174 +4,185 @@ import Label from 'components/Label'; import Tooltip from 'components/Tooltip'; import i18n from 'i18n'; import { AiOutlineInfoCircle } from 'react-icons/ai'; +import { GoGitBranch, GoGitMerge } from 'react-icons/go'; import { IoCopyOutline } from 'react-icons/io5'; -import { MdDeleteOutline, MdOutlineDescription, MdOutlineEdit } from 'react-icons/md'; +import { + MdChevronRight, + MdDeleteOutline, + MdExpandMore, + MdOutlineEdit, + MdOutlinePushPin, + MdPushPin, +} from 'react-icons/md'; import { NavigateFunction } from 'react-router-dom'; import { ROUTES } from 'resources/routes-constants'; import useServiceListStore from 'store/services.store'; import useStore from 'store/store'; import useToastStore from 'store/toasts.store'; import { Service, ServiceState } from 'types'; +import { togglePinnedService } from 'utils/pinned-services'; +import { getDependencyCounts } from 'utils/service-dependencies'; interface GetColumnsConfig { - isCommon: boolean; navigate: NavigateFunction; hideDeletePopup: () => void; - showReadyPopup: () => void; + onStateClick: (service: Service) => void; + expandedServiceIds: string[]; + onToggleExpand: (serviceId: string) => void; + onFocusDependencies: (serviceId: string) => void; + onPinToggle: () => void; + pinnedServiceIds: string[]; } -export const getColumns = ({ isCommon, navigate, hideDeletePopup, showReadyPopup }: GetColumnsConfig) => { +export const getColumns = ({ + navigate, + hideDeletePopup, + onStateClick, + expandedServiceIds, + onToggleExpand, + onFocusDependencies, + onPinToggle, + pinnedServiceIds, +}: GetColumnsConfig) => { const columnHelper = createColumnHelper(); const userInfo = useStore.getState().userInfo; + const dependencyMap = useServiceListStore.getState().dependencyMap; return [ columnHelper.accessor('name', { header: i18n.t('overview.service.name') ?? '', - meta: { - size: 620, - }, - cell: (props) => ( - - - - - - - } - > -
- } size="medium" /> -
-
- - ), - }), - columnHelper.accessor('description', { - header: i18n.t('overview.service.description') ?? '', - meta: { - size: 200, - }, + enableSorting: true, + meta: { size: 360 }, cell: (props) => { - const description = props.row.original.description ?? ''; - const isLong = description.length > 80; - const truncated = isLong ? `${description.slice(0, 80)}...` : description; + const service = props.row.original; + const isExpanded = expandedServiceIds.includes(service.serviceId); + const examples = service.examples?.length ? service.examples.join('\n') : i18n.t('overview.service.noExamples'); + const keywords = service.entities?.length ? service.entities.join(', ') : i18n.t('overview.service.noKeywords'); return ( - - + + + -