From 4e26499eaa539e6b4a199beccdd2484d158274f7 Mon Sep 17 00:00:00 2001 From: Kazi Date: Thu, 31 Oct 2024 17:44:12 +0600 Subject: [PATCH 1/5] Update to simpler duration format --- urbackupserver/www2/src/utils/format.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/urbackupserver/www2/src/utils/format.ts b/urbackupserver/www2/src/utils/format.ts index 63ef95ca..e1cc3ce9 100644 --- a/urbackupserver/www2/src/utils/format.ts +++ b/urbackupserver/www2/src/utils/format.ts @@ -183,8 +183,8 @@ export function formatDuration(durationInSeconds: number) { const minutes = Math.floor(durationInSeconds / 60) - hours * 60; if (hours > 0) { - return `${hours} hour ${minutes} min`; + return `${hours}h ${minutes}m`; } - return `${minutes} min`; + return `${minutes}m`; } From 2f1a73fb6adba195518d2030836ab5772dbb7362 Mon Sep 17 00:00:00 2001 From: Kazi Date: Sun, 3 Nov 2024 17:18:10 +0600 Subject: [PATCH 2/5] Add format function for speed --- urbackupserver/www2/src/utils/format.ts | 52 ++++++++++++++++++------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/urbackupserver/www2/src/utils/format.ts b/urbackupserver/www2/src/utils/format.ts index e1cc3ce9..d5de1790 100644 --- a/urbackupserver/www2/src/utils/format.ts +++ b/urbackupserver/www2/src/utils/format.ts @@ -131,30 +131,56 @@ export function format_size(s: number) { return s + " " + suffix; } -export function format_size_bits(s: number) { +export function format_bits(bits: number) { let suffix = "bits"; - if (s > 1000) { - s /= 1000.0; + if (bits > 1000) { + bits /= 1000.0; suffix = "Kbit"; } - if (s > 1000) { - s /= 1000.0; + if (bits > 1000) { + bits /= 1000.0; suffix = "Mbit"; } - if (s > 1000) { - s /= 1000.0; + if (bits > 1000) { + bits /= 1000.0; suffix = "Gbit"; } - if (s > 1000) { - s /= 1000.0; + if (bits > 1000) { + bits /= 1000.0; suffix = "Tbit"; } - s *= 100; - s = Math.round(s); - s /= 100.0; + bits *= 100; + bits = Math.round(bits); + bits /= 100.0; + + return { + value: bits, + suffix, + }; +} + +export function format_size_bits(s: number) { + const { value, suffix } = format_bits(s); + const suffix_trans = i18n._(suffix); - return s + " " + (suffix_trans != null ? suffix_trans : suffix); + return value + " " + (suffix_trans != null ? suffix_trans : suffix); +} + +/** + * Convert speed from bytes/ms to bits/s + * @param bpms Speed in bytes per ms + * @returns Speed in bits per s + */ +export function format_speed_bpms_to_bps(bpms: number) { + const speedInBps = bpms * 8000; + + const { value, suffix } = format_bits(speedInBps); + + const speedSuffix = `${suffix}/s`; + + const suffix_trans = i18n._(speedSuffix); + return value + " " + (suffix_trans != null ? suffix_trans : suffix); } /** From 1660ca8f0e900ef282137f91732db1a20513997d Mon Sep 17 00:00:00 2001 From: Kazi Date: Sun, 3 Nov 2024 17:19:33 +0600 Subject: [PATCH 3/5] Add numbered actions map --- .../www2/src/features/activities/ACTIONS.ts | 43 +++++++++++++++++++ .../activities/getActionFromLastAct.test.ts | 3 +- .../activities/getActionFromLastAct.ts | 25 +---------- 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 urbackupserver/www2/src/features/activities/ACTIONS.ts diff --git a/urbackupserver/www2/src/features/activities/ACTIONS.ts b/urbackupserver/www2/src/features/activities/ACTIONS.ts new file mode 100644 index 00000000..bf96ad22 --- /dev/null +++ b/urbackupserver/www2/src/features/activities/ACTIONS.ts @@ -0,0 +1,43 @@ +export const ACTIONS = { + NONE: "None", + INCR_FILE: "Incremental file backup", + FULL_FILE: "Full file backup", + INCR_IMAGE: "Incremental image backup", + FULL_IMAGE: "Full image backup", + RESUME_INCR_FILE: "Resumed incremental file backup", + RESUME_FULL_FILE: "Resumed full file backup", + RESTORE_FILE: "File restore", + RESTORE_IMAGE: "Image restore", + UPDATE: "Client update", + CHECK_INTEGRITY: "Checking database integrity", + BACKUP_DATABASE: "Backing up database", + RECALCULATE_STATISTICS: "Recalculating statistics", + NIGHTLY_CLEANUP: "Nightly clean-up", + EMERGENCY_CLEANUP: "Emergency clean-up", + STORAGE_MIGRATION: "Storage migration", + + // Delete actions + DEL_INCR_FILE: "Deleting incremental file backup", + DEL_FULL_FILE: "Deleting full file backup", + DEL_INCR_IMAGE: "Deleting incremental image backup", + DEL_FULL_IMAGE: "Deleting full image backup", +} as const; + +export const NUMBERED_ACTIONS_MAP = new Map([ + [0, ACTIONS.NONE], + [1, ACTIONS.INCR_FILE], + [2, ACTIONS.FULL_FILE], + [3, ACTIONS.INCR_IMAGE], + [4, ACTIONS.FULL_IMAGE], + [5, ACTIONS.RESUME_INCR_FILE], + [6, ACTIONS.RESUME_FULL_FILE], + [8, ACTIONS.RESTORE_FILE], + [9, ACTIONS.RESTORE_IMAGE], + [10, ACTIONS.UPDATE], + [11, ACTIONS.CHECK_INTEGRITY], + [12, ACTIONS.BACKUP_DATABASE], + [13, ACTIONS.RECALCULATE_STATISTICS], + [14, ACTIONS.NIGHTLY_CLEANUP], + [15, ACTIONS.EMERGENCY_CLEANUP], + [16, ACTIONS.STORAGE_MIGRATION], +]); diff --git a/urbackupserver/www2/src/features/activities/getActionFromLastAct.test.ts b/urbackupserver/www2/src/features/activities/getActionFromLastAct.test.ts index 0919d412..1884ac0f 100644 --- a/urbackupserver/www2/src/features/activities/getActionFromLastAct.test.ts +++ b/urbackupserver/www2/src/features/activities/getActionFromLastAct.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from "vitest"; -import { ACTIONS, getActionFromLastAct } from "./getActionFromLastAct"; +import { getActionFromLastAct } from "./getActionFromLastAct"; +import { ACTIONS } from "./ACTIONS"; const testCases: { lastact: Parameters[0]; diff --git a/urbackupserver/www2/src/features/activities/getActionFromLastAct.ts b/urbackupserver/www2/src/features/activities/getActionFromLastAct.ts index 494d3ea9..9f58b16c 100644 --- a/urbackupserver/www2/src/features/activities/getActionFromLastAct.ts +++ b/urbackupserver/www2/src/features/activities/getActionFromLastAct.ts @@ -1,28 +1,5 @@ import { ActivityItem } from "../../api/urbackupserver"; - -export const ACTIONS = { - NONE: "None", - INCR_FILE: "Incremental file backup", - FULL_FILE: "Full file backup", - INCR_IMAGE: "Incremental image backup", - FULL_IMAGE: "Full image backup", - RESUME_INCR_FILE: "Resumed incremental file backup", - RESUME_FULL_FILE: "Resumed full file backup", - RESTORE_FILE: "File restore", - RESTORE_IMAGE: "Image restore", - - // Unused 10 - 13 - // UPDATE: "Client update", - // CHECK_INTEGRITY: "Checking database integrity", - // BACKUP_DATABASE: "Backing up database", - // RECALCULATE_STATISTICS: "Recalculating statistics", - - // Delete actions - DEL_INCR_FILE: "Deleting incremental file backup", - DEL_FULL_FILE: "Deleting full file backup", - DEL_INCR_IMAGE: "Deleting incremental image backup", - DEL_FULL_IMAGE: "Deleting full image backup", -} as const; +import { ACTIONS } from "./ACTIONS"; export function getActionFromLastAct( lastact: Pick< From 4d73f235295a710bb604825648fcc7f7ef55a912 Mon Sep 17 00:00:00 2001 From: Kazi Date: Sun, 3 Nov 2024 17:37:57 +0600 Subject: [PATCH 4/5] Add activities table --- urbackupserver/www2/package.json | 1 + urbackupserver/www2/pnpm-lock.yaml | 478 ++++++++++++++++++ .../activities/OngoingActivitiesActions.tsx | 62 +++ .../activities/OngoingActivitiesTable.tsx | 209 ++++++++ .../features/activities/ProcessSpeedChart.tsx | 36 ++ urbackupserver/www2/src/pages/Activities.tsx | 14 +- 6 files changed, 796 insertions(+), 4 deletions(-) create mode 100644 urbackupserver/www2/src/features/activities/OngoingActivitiesActions.tsx create mode 100644 urbackupserver/www2/src/features/activities/OngoingActivitiesTable.tsx create mode 100644 urbackupserver/www2/src/features/activities/ProcessSpeedChart.tsx diff --git a/urbackupserver/www2/package.json b/urbackupserver/www2/package.json index 35b71dc2..2e026480 100644 --- a/urbackupserver/www2/package.json +++ b/urbackupserver/www2/package.json @@ -13,6 +13,7 @@ "test": "vitest" }, "dependencies": { + "@fluentui/react-charting": "^5.23.11", "@fluentui/react-components": "^9.49.2", "@fluentui/react-experiments": "^8.14.152", "@fluentui/react-icons": "^2.0.239", diff --git a/urbackupserver/www2/pnpm-lock.yaml b/urbackupserver/www2/pnpm-lock.yaml index b0f3b9c9..f6b1b4e1 100644 --- a/urbackupserver/www2/pnpm-lock.yaml +++ b/urbackupserver/www2/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@fluentui/react-charting': + specifier: ^5.23.11 + version: 5.23.11(@fluentui/react@8.121.7(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@fluentui/react-components': specifier: ^9.49.2 version: 9.49.2(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) @@ -518,15 +521,30 @@ packages: '@fluentui/date-time-utilities@8.6.7': resolution: {integrity: sha512-FzM/UYne+o7zFJ1PBQc/TKW+ZY2gfG12AjP/CBF9RM9ExxGUsX3/BGYkNzw0K5KNuqSx7LFqfnhTN9fElTrTlQ==} + '@fluentui/date-time-utilities@8.6.9': + resolution: {integrity: sha512-dgOlVm4nXBWDLqijmvn4iAtyv1hVpQZjN6p0So74BW+7ASUTkQGe3lf8PHV/OjBiXfZa4qwONvmTQBGCheNU0w==} + '@fluentui/dom-utilities@2.3.5': resolution: {integrity: sha512-27DnvFFsA+1a23UGpb0E2WHvHHLNPaViJMOm4tYEGyCKV26DlBN7N5QggCd0m5fg+A+dXKWb03e0aikBquF5rQ==} + '@fluentui/dom-utilities@2.3.9': + resolution: {integrity: sha512-8PPzv31VXnyMvZrzK7iSGPRx8piJjas0xV+qaNQ1tzAXHuTaLXPeADJK/gEDH1XA/e9Vaakb3lPUpRVa8tal+w==} + '@fluentui/example-data@8.4.22': resolution: {integrity: sha512-L9xfAW7VXWH2Mo5pgIJ3nJOggvUl1HReinmPBSPd3ixzFdFDjihpuX4T8vyg1uKYAF9AD8uCuM+yOtduPrPzcg==} '@fluentui/font-icons-mdl2@8.5.42': resolution: {integrity: sha512-LX51MFKcEAg69NqIAEbtlexDNtKyfiAr+BiCkLF4+XuevE+GAocQqaHh7jInws/NOuDvyK2Vz9Z2J5WTG2Mufw==} + '@fluentui/font-icons-mdl2@8.5.54': + resolution: {integrity: sha512-4BU4+K4VnAt6Djsfeh69N6PdgWcp+/q2QQ/Vi7O4A3Uc9/1KUKqTD349gYnXf/JAkpVsWammIBByIFBaQGlFWA==} + + '@fluentui/foundation-legacy@8.4.20': + resolution: {integrity: sha512-6/NRrsce4EIYgJSrxbmLSCP/qsHP7oh8tO83FHGc5b8aA5snE5dcvpHzrzrt5v5xH26dj6WGRFOO8wInDBpg+Q==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/foundation-legacy@8.4.8': resolution: {integrity: sha512-v0QPnlclvTlzC3DElPNGzQ3ybPxSqSLKTPAdzVsLpeM72IbnoomPPJIJTXKOBRdswxQhx7I3OFLHr69ciPwvbA==} peerDependencies: @@ -536,9 +554,15 @@ packages: '@fluentui/keyboard-key@0.4.21': resolution: {integrity: sha512-V77gXinXpX2FosoJExSvDAcqLUtpDuefDKQ+gmIGRrCoXOWBaG+fGn1bM1fQlo66+fsaTY7hafnBLt/QVmGv4g==} + '@fluentui/keyboard-key@0.4.23': + resolution: {integrity: sha512-9GXeyUqNJUdg5JiQUZeGPiKnRzMRi9YEUn1l9zq6X/imYdMhxHrxpVZS12129cBfgvPyxt9ceJpywSfmLWqlKA==} + '@fluentui/keyboard-keys@9.0.7': resolution: {integrity: sha512-vaQ+lOveQTdoXJYqDQXWb30udSfTVcIuKk1rV0X0eGAgcHeSDeP1HxMy+OgHOQZH3OiBH4ZYeWxb+tmfiDiygQ==} + '@fluentui/merge-styles@8.6.13': + resolution: {integrity: sha512-IWgvi2CC+mcQ7/YlCvRjsmHL2+PUz7q+Pa2Rqk3a+QHN0V1uBvgIbKk5y/Y/awwDXy1yJHiqMCcDHjBNmS1d4A==} + '@fluentui/merge-styles@8.6.8': resolution: {integrity: sha512-QdUX5ZhhnhO25k9wY9jXY3O6vhL/YfKfV1bac0kDKVkEjYszIGq8joKhrVeIUsNvaQer4zl4MMvlLOA5vcL78g==} @@ -609,6 +633,15 @@ packages: react: '>=16.14.0 <19.0.0' react-dom: '>=16.14.0 <19.0.0' + '@fluentui/react-charting@5.23.11': + resolution: {integrity: sha512-kwGpylPeKcCYPUfn+n7qd+D1U/hlTPmwO9p+mpE60wbPxum/auhyDgZ3rMsZVxdx2WQ0KbPySkxHitIQnAuX1Q==} + peerDependencies: + '@fluentui/react': ^8.121.7 + '@types/react': '>=16.8.0 <19.0.0' + '@types/react-dom': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + react-dom: '>=16.8.0 <19.0.0' + '@fluentui/react-checkbox@9.2.23': resolution: {integrity: sha512-6Iqp8MFwXFNQMwhdcbMwfPZM/09IwOPG+3ij3v4SKpO0ktuP71CzDhEC0VLqyHJvybmFQIyqCelsZY5K702sUQ==} peerDependencies: @@ -682,12 +715,24 @@ packages: react: '>=16.14.0 <19.0.0' react-dom: '>=16.14.0 <19.0.0' + '@fluentui/react-focus@8.9.17': + resolution: {integrity: sha512-YxnxkLcsECT9CwzJEInZzgwYcngRE+LgDgtMWphXooqeYzH2TrUUeKxncbd5dibQ9gS6mpGN8pApyskEi3yDyg==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/react-focus@8.9.5': resolution: {integrity: sha512-n0vyp3I9mfP7eZqVVdM8HMLxjKWtNHM8DrbNLQC+WjuatnQR7No20yLi2vg1y16EiUhDKG/Mi9H0ohJvsYz15w==} peerDependencies: '@types/react': '>=16.8.0 <19.0.0' react: '>=16.8.0 <19.0.0' + '@fluentui/react-hooks@8.8.16': + resolution: {integrity: sha512-PQ1BeOp+99mdO0g7j6QLtChfXG1LxXeHG0q5CtUeD1OUGR+vUDK84h60sw7e7qU9sSmvPmHO7jn69Lg3CS+DXw==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/react-hooks@8.8.5': resolution: {integrity: sha512-YqEa5/NEbGoAd1hokzUD/Zl3gnZJWwpg4KyqEJKMZgnWkBLaHgePtaH1HBORr/beKDC0ITPw6hqLUASl6QKTEg==} peerDependencies: @@ -807,6 +852,12 @@ packages: '@types/react': '>=16.14.0 <19.0.0' react: '>=16.14.0 <19.0.0' + '@fluentui/react-portal-compat-context@9.0.12': + resolution: {integrity: sha512-5AVXWX9GnbvwnJZYUb4LSIF7BsI/N8oTI6+7Yn0w6B3yaWykA8Menlz757X5tgVBjouEj4Eom+AoVvA7u8gPDA==} + peerDependencies: + '@types/react': '>=16.14.0 <19.0.0' + react: '>=16.14.0 <19.0.0' + '@fluentui/react-portal@9.4.23': resolution: {integrity: sha512-x7V8HSz7VJqYHwC8bwPdtx7NmSJBIbr8d+tqItMGX28/vvArq0tBBr1VClYHPP4kxeGTbvh0c9c3tYS1+JZtWQ==} peerDependencies: @@ -1028,6 +1079,12 @@ packages: '@types/react': '>=16.8.0 <19.0.0' react: '>=16.8.0 <19.0.0' + '@fluentui/react-window-provider@2.2.28': + resolution: {integrity: sha512-YdZ74HTaoDwlvLDzoBST80/17ExIl93tLJpTxnqK5jlJOAUVQ+mxLPF2HQEJq+SZr5IMXHsQ56w/KaZVRn72YA==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/react@8.118.6': resolution: {integrity: sha512-yLYOJoqwkCsE09KC9hPcnRbKsb9Hxsq1a7lIUoz9LhWd70ImLagwdZrFvzVu3dw1mt6E34Wx6lndv4ji1tRTQw==} peerDependencies: @@ -1036,21 +1093,53 @@ packages: react: '>=16.8.0 <19.0.0' react-dom: '>=16.8.0 <19.0.0' + '@fluentui/react@8.121.7': + resolution: {integrity: sha512-eYzAgXGSrASCiqact6UJ7K6mRxoegMyOhqfUI9G9iOn60FW85pedwalTaa2pARKXDmvTZ35EfnPMFF9ObisB6A==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + '@types/react-dom': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + react-dom: '>=16.8.0 <19.0.0' + + '@fluentui/scheme-utilities@8.3.64': + resolution: {integrity: sha512-bluXibuQBraw1Vb729DqcjOXSwxpN8m8iQKNa1TlfAEGNUnf5Nn2ZW9vk5ruXnGys3P3yz9o/ZikxX2c/03GWQ==} + '@fluentui/set-version@8.2.21': resolution: {integrity: sha512-WPHAFgPbskK0YVduc7cxm+2U+5dhd5WkzznLcqz1OeS81vAgJXWOKK4UIfCDEcqkDuDubMKDrVyHnYJYAJufJQ==} + '@fluentui/set-version@8.2.23': + resolution: {integrity: sha512-VPXaBsiaa3Xn/AY40nLU9bvDQ62lpMVnFzFTlQ8CbpdwrjxNlRxDUY5vRToNzp1+Zu5gD/+CgsXqIZGcry5L5w==} + '@fluentui/style-utilities@8.10.13': resolution: {integrity: sha512-XdwfLJKir0+HC95EdQz78D0W9mBVV694nelkSLs12wGzPkruibFfESpbOgbHrPKnnBhhiQrjzGrYvuz2+WNvkQ==} + '@fluentui/style-utilities@8.11.3': + resolution: {integrity: sha512-Qbmg8mjPXl7A0nuekJ8W4tpD4fWRnKT6hHio4cP49vIQL+wdIkG6OdI1KggDHI7oeuqqPGeXCOcj59eK2MwXtQ==} + + '@fluentui/theme-samples@8.7.182': + resolution: {integrity: sha512-AqTipeNb0RIiJrizE6AKQUbAYyjiofVNswJ72CSmOoi81vDKbxRLRIUH7hojOFI7F2upRv4yccSp94Nv+SvFlQ==} + '@fluentui/theme@2.6.51': resolution: {integrity: sha512-N0zPdE+xNGZSuiVhsdJcWpSWESk2piaQIA+kaAfY/B71Y7cWfZyzZQEITrR4IBw8EYFgPNYf7Kixo0+46ivOwQ==} peerDependencies: '@types/react': '>=16.8.0 <19.0.0' react: '>=16.8.0 <19.0.0' + '@fluentui/theme@2.6.63': + resolution: {integrity: sha512-BZ+YG4Vqb+ulhmZzDv8yZFuYo2kHp1m2cttBZLkc+61FnrwCaDBmJxwg65gXoF7wwXKh2qJIcJueSLMmvVyAOQ==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/tokens@1.0.0-alpha.16': resolution: {integrity: sha512-Gr9G8LIlUhZYX5j6CfDQrofQqsWAz/q54KabWn1tWV/1083WwyoTZXiG1k6b37NnK7Feye7D7Nz+4MNqoKpXGw==} + '@fluentui/utilities@8.15.19': + resolution: {integrity: sha512-20WoYz0wW7pkmur+7qxTwRfvkdAnHfylLdCYSm91WLupb0cwQ1wWZWIuyo+e0cjcvem1T9TC1+NjWs0kavTWBg==} + peerDependencies: + '@types/react': '>=16.8.0 <19.0.0' + react: '>=16.8.0 <19.0.0' + '@fluentui/utilities@8.15.8': resolution: {integrity: sha512-FVURRfFXOi5WuyB6c58F+A6aHllbV2oa/FdjP8pBn/MX9p+Pwy54wXNXNagYvLJ4GmylFk73XssAoUE5zy3QpQ==} peerDependencies: @@ -1287,6 +1376,45 @@ packages: '@types/crypto-js@4.2.2': resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-path@1.0.11': + resolution: {integrity: sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw==} + + '@types/d3-path@3.1.0': + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} + + '@types/d3-sankey@0.12.4': + resolution: {integrity: sha512-YTicQNwioitIlvuvlfW2GfO6sKxpohzg2cSQttlXAPjFwoBuN+XpGLhUN3kLutG/dI3GCLC+DUorqiJt7Naetw==} + + '@types/d3-scale@4.0.8': + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@1.3.12': + resolution: {integrity: sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==} + + '@types/d3-shape@3.1.6': + resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==} + + '@types/d3-time-format@3.0.4': + resolution: {integrity: sha512-or9DiDnYI1h38J9hxKEsw513+KVuFbEVhl7qdxcaudoiqWWepapUen+2vAriFGexr6W5+P4l9+HJrB39GG+oRg==} + + '@types/d3-time@3.0.3': + resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -1637,6 +1765,68 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@3.0.0: + resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==} + + d3-time@2.1.1: + resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} @@ -1906,6 +2096,13 @@ packages: resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} engines: {node: '>=8.0.0'} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -2954,11 +3151,21 @@ snapshots: '@fluentui/set-version': 8.2.21 tslib: 2.6.2 + '@fluentui/date-time-utilities@8.6.9': + dependencies: + '@fluentui/set-version': 8.2.23 + tslib: 2.6.2 + '@fluentui/dom-utilities@2.3.5': dependencies: '@fluentui/set-version': 8.2.21 tslib: 2.6.2 + '@fluentui/dom-utilities@2.3.9': + dependencies: + '@fluentui/set-version': 8.2.23 + tslib: 2.6.2 + '@fluentui/example-data@8.4.22': dependencies: tslib: 2.6.2 @@ -2973,6 +3180,26 @@ snapshots: - '@types/react' - react + '@fluentui/font-icons-mdl2@8.5.54(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/set-version': 8.2.23 + '@fluentui/style-utilities': 8.11.3(@types/react@18.3.1)(react@18.3.1) + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + tslib: 2.6.2 + transitivePeerDependencies: + - '@types/react' + - react + + '@fluentui/foundation-legacy@8.4.20(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/merge-styles': 8.6.13 + '@fluentui/set-version': 8.2.23 + '@fluentui/style-utilities': 8.11.3(@types/react@18.3.1)(react@18.3.1) + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/foundation-legacy@8.4.8(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/merge-styles': 8.6.8 @@ -2987,10 +3214,19 @@ snapshots: dependencies: tslib: 2.6.2 + '@fluentui/keyboard-key@0.4.23': + dependencies: + tslib: 2.6.2 + '@fluentui/keyboard-keys@9.0.7': dependencies: '@swc/helpers': 0.5.11 + '@fluentui/merge-styles@8.6.13': + dependencies: + '@fluentui/set-version': 8.2.23 + tslib: 2.6.2 + '@fluentui/merge-styles@8.6.8': dependencies: '@fluentui/set-version': 8.2.21 @@ -3134,6 +3370,39 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@fluentui/react-charting@5.23.11(@fluentui/react@8.121.7(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@fluentui/react': 8.121.7(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@fluentui/react-focus': 8.9.17(@types/react@18.3.1)(react@18.3.1) + '@fluentui/set-version': 8.2.23 + '@fluentui/theme-samples': 8.7.182(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@microsoft/load-themed-styles': 1.10.295 + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-format': 3.0.4 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-sankey': 0.12.4 + '@types/d3-scale': 4.0.8 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.6 + '@types/d3-time': 3.0.3 + '@types/d3-time-format': 3.0.4 + '@types/react': 18.3.1 + '@types/react-dom': 18.3.0 + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-format: 3.1.0 + d3-hierarchy: 3.1.2 + d3-sankey: 0.12.3 + d3-scale: 4.0.2 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 3.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.6.2 + '@fluentui/react-checkbox@9.2.23(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)': dependencies: '@fluentui/react-field': 9.1.64(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) @@ -3341,6 +3610,17 @@ snapshots: transitivePeerDependencies: - scheduler + '@fluentui/react-focus@8.9.17(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/keyboard-key': 0.4.23 + '@fluentui/merge-styles': 8.6.13 + '@fluentui/set-version': 8.2.23 + '@fluentui/style-utilities': 8.11.3(@types/react@18.3.1)(react@18.3.1) + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/react-focus@8.9.5(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/keyboard-key': 0.4.21 @@ -3352,6 +3632,15 @@ snapshots: react: 18.3.1 tslib: 2.6.2 + '@fluentui/react-hooks@8.8.16(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/react-window-provider': 2.2.28(@types/react@18.3.1)(react@18.3.1) + '@fluentui/set-version': 8.2.23 + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/react-hooks@8.8.5(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/react-window-provider': 2.2.25(@types/react@18.3.1)(react@18.3.1) @@ -3578,6 +3867,12 @@ snapshots: '@types/react': 18.3.1 react: 18.3.1 + '@fluentui/react-portal-compat-context@9.0.12(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@swc/helpers': 0.5.11 + '@types/react': 18.3.1 + react: 18.3.1 + '@fluentui/react-portal@9.4.23(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@fluentui/react-shared-contexts': 9.18.0(@types/react@18.3.1)(react@18.3.1) @@ -4030,6 +4325,13 @@ snapshots: react: 18.3.1 tslib: 2.6.2 + '@fluentui/react-window-provider@2.2.28(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/set-version': 8.2.23 + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/react@8.118.6(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@fluentui/date-time-utilities': 8.6.7 @@ -4051,10 +4353,44 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tslib: 2.6.2 + '@fluentui/react@8.121.7(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@fluentui/date-time-utilities': 8.6.9 + '@fluentui/font-icons-mdl2': 8.5.54(@types/react@18.3.1)(react@18.3.1) + '@fluentui/foundation-legacy': 8.4.20(@types/react@18.3.1)(react@18.3.1) + '@fluentui/merge-styles': 8.6.13 + '@fluentui/react-focus': 8.9.17(@types/react@18.3.1)(react@18.3.1) + '@fluentui/react-hooks': 8.8.16(@types/react@18.3.1)(react@18.3.1) + '@fluentui/react-portal-compat-context': 9.0.12(@types/react@18.3.1)(react@18.3.1) + '@fluentui/react-window-provider': 2.2.28(@types/react@18.3.1)(react@18.3.1) + '@fluentui/set-version': 8.2.23 + '@fluentui/style-utilities': 8.11.3(@types/react@18.3.1)(react@18.3.1) + '@fluentui/theme': 2.6.63(@types/react@18.3.1)(react@18.3.1) + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@microsoft/load-themed-styles': 1.10.295 + '@types/react': 18.3.1 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.6.2 + + '@fluentui/scheme-utilities@8.3.64(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/set-version': 8.2.23 + '@fluentui/theme': 2.6.63(@types/react@18.3.1)(react@18.3.1) + tslib: 2.6.2 + transitivePeerDependencies: + - '@types/react' + - react + '@fluentui/set-version@8.2.21': dependencies: tslib: 2.6.2 + '@fluentui/set-version@8.2.23': + dependencies: + tslib: 2.6.2 + '@fluentui/style-utilities@8.10.13(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/merge-styles': 8.6.8 @@ -4067,6 +4403,30 @@ snapshots: - '@types/react' - react + '@fluentui/style-utilities@8.11.3(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/merge-styles': 8.6.13 + '@fluentui/set-version': 8.2.23 + '@fluentui/theme': 2.6.63(@types/react@18.3.1)(react@18.3.1) + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@microsoft/load-themed-styles': 1.10.295 + tslib: 2.6.2 + transitivePeerDependencies: + - '@types/react' + - react + + '@fluentui/theme-samples@8.7.182(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@fluentui/react': 8.121.7(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@fluentui/scheme-utilities': 8.3.64(@types/react@18.3.1)(react@18.3.1) + '@fluentui/set-version': 8.2.23 + tslib: 2.6.2 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - react + - react-dom + '@fluentui/theme@2.6.51(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/merge-styles': 8.6.8 @@ -4076,10 +4436,29 @@ snapshots: react: 18.3.1 tslib: 2.6.2 + '@fluentui/theme@2.6.63(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/merge-styles': 8.6.13 + '@fluentui/set-version': 8.2.23 + '@fluentui/utilities': 8.15.19(@types/react@18.3.1)(react@18.3.1) + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/tokens@1.0.0-alpha.16': dependencies: '@swc/helpers': 0.5.11 + '@fluentui/utilities@8.15.19(@types/react@18.3.1)(react@18.3.1)': + dependencies: + '@fluentui/dom-utilities': 2.3.9 + '@fluentui/merge-styles': 8.6.13 + '@fluentui/react-window-provider': 2.2.28(@types/react@18.3.1)(react@18.3.1) + '@fluentui/set-version': 8.2.23 + '@types/react': 18.3.1 + react: 18.3.1 + tslib: 2.6.2 + '@fluentui/utilities@8.15.8(@types/react@18.3.1)(react@18.3.1)': dependencies: '@fluentui/dom-utilities': 2.3.5 @@ -4354,6 +4733,42 @@ snapshots: '@types/crypto-js@4.2.2': {} + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-format@3.0.4': {} + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-path@1.0.11': {} + + '@types/d3-path@3.1.0': {} + + '@types/d3-sankey@0.12.4': + dependencies: + '@types/d3-shape': 1.3.12 + + '@types/d3-scale@4.0.8': + dependencies: + '@types/d3-time': 3.0.3 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@1.3.12': + dependencies: + '@types/d3-path': 1.0.11 + + '@types/d3-shape@3.1.6': + dependencies: + '@types/d3-path': 3.1.0 + + '@types/d3-time-format@3.0.4': {} + + '@types/d3-time@3.0.3': {} + '@types/estree@1.0.5': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -4753,6 +5168,65 @@ snapshots: csstype@3.1.3: {} + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-color@3.1.0: {} + + d3-format@3.1.0: {} + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 3.0.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@3.0.0: + dependencies: + d3-time: 2.1.1 + + d3-time@2.1.1: + dependencies: + d3-array: 2.12.1 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + date-fns@3.6.0: {} debug@4.3.4: @@ -5083,6 +5557,10 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 + internmap@1.0.1: {} + + internmap@2.0.3: {} + is-arrayish@0.2.1: {} is-binary-path@2.1.0: diff --git a/urbackupserver/www2/src/features/activities/OngoingActivitiesActions.tsx b/urbackupserver/www2/src/features/activities/OngoingActivitiesActions.tsx new file mode 100644 index 00000000..675eaf89 --- /dev/null +++ b/urbackupserver/www2/src/features/activities/OngoingActivitiesActions.tsx @@ -0,0 +1,62 @@ +import { tokens, Button, makeStyles } from "@fluentui/react-components"; +import { OpenRegular } from "@fluentui/react-icons"; +import { useMutation } from "@tanstack/react-query"; + +import type { ProcessItem } from "../../api/urbackupserver"; +import { urbackupServer } from "../../App"; + +function useStopProcessMutation() { + return useMutation({ + mutationFn: ({ + clientId, + processId, + }: { + clientId: number; + processId: number; + }) => urbackupServer.stopProcess(clientId, processId, false), + }); +} + +const useStyles = makeStyles({ + root: { + display: "flex", + gap: tokens.spacingHorizontalXS, + }, + stopButton: { + minWidth: 0, + }, +}); + +export function OngoingActivitiesActions({ + process, +}: { + process: ProcessItem; +}) { + const stopProcessMutatiion = useStopProcessMutation(); + + const classes = useStyles(); + + return ( +
+ {process.can_stop_backup && ( + + )} + {process.can_show_backup_log && ( + + )} +
+ ); +} diff --git a/urbackupserver/www2/src/features/activities/OngoingActivitiesTable.tsx b/urbackupserver/www2/src/features/activities/OngoingActivitiesTable.tsx new file mode 100644 index 00000000..c7199865 --- /dev/null +++ b/urbackupserver/www2/src/features/activities/OngoingActivitiesTable.tsx @@ -0,0 +1,209 @@ +import { + DataGrid, + DataGridHeader, + DataGridRow, + DataGridHeaderCell, + DataGridBody, + DataGridCell, + TableCellLayout, + TableColumnDefinition, + createTableColumn, + TableColumnId, + DataGridCellFocusMode, + Field, + ProgressBar, + tokens, + Caption1, + Text, +} from "@fluentui/react-components"; + +import type { ProcessItem } from "../../api/urbackupserver"; +import { format_size, formatDuration } from "../../utils/format"; +import { NUMBERED_ACTIONS_MAP } from "./ACTIONS"; +import { OngoingActivitiesActions } from "./OngoingActivitiesActions"; +import { ProcessSpeedChart } from "./ProcessSpeedChart"; + +const styles: Record = { + progressField: { + width: "100%", + }, + progressWrapper: { + width: "100%", + paddingBlock: tokens.spacingVerticalM, + display: "flex", + flexDirection: "column", + gap: tokens.spacingVerticalXS, + }, +}; + +export const columns: TableColumnDefinition[] = [ + createTableColumn({ + columnId: "name", + renderHeaderCell: () => { + return "Computer name"; + }, + renderCell: (item) => { + return {item.name}; + }, + }), + createTableColumn({ + columnId: "action", + renderHeaderCell: () => { + return "Action"; + }, + renderCell: (item) => { + return ( + + {NUMBERED_ACTIONS_MAP.get(item.action)} + + ); + }, + }), + createTableColumn({ + columnId: "details", + renderHeaderCell: () => { + return "Details"; + }, + renderCell: (item) => { + if (["0", ""].includes(item.details)) { + return "-"; + } + + return ( + + Volume + {item.details} + + ); + }, + }), + createTableColumn({ + columnId: "progress", + renderHeaderCell: () => { + return "Progress"; + }, + renderCell: (item) => { + if (item.pcdone < 0) { + return ( + + + + ); + } + + return ( +
+ + + + + {format_size(item.done_bytes)} / {format_size(item.total_bytes)} + +
+ ); + }, + }), + createTableColumn({ + columnId: "eta", + renderHeaderCell: () => { + return "ETA"; + }, + renderCell: (item) => { + if (item.pcdone < 0 || item.pcdone === 100) { + return "-"; + } + + return ( + {formatDuration(item.eta_ms / 1000)} + ); + }, + }), + createTableColumn({ + columnId: "speed", + renderHeaderCell: () => { + return "Speed"; + }, + renderCell: ProcessSpeedChart, + }), + createTableColumn({ + columnId: "queue", + renderHeaderCell: () => { + return Files in Queue; + }, + renderCell: (item) => { + return {String(item.queue)}; + }, + }), + createTableColumn({ + columnId: "actions", + renderHeaderCell: () => { + return "Actions"; + }, + renderCell: (item) => { + return ; + }, + }), +]; + +const getCellFocusMode = (columnId: TableColumnId): DataGridCellFocusMode => { + switch (columnId) { + case "actions": + return "group"; + default: + return "cell"; + } +}; + +export function OngoingActivitiesTable({ data }: { data: ProcessItem[] }) { + if (data.length === 0) { + return No activities; + } + + return ( + item.id} columns={columns}> + + + {({ renderHeaderCell, columnId }) => ( + + {renderHeaderCell()} + + )} + + + > + {({ item }) => ( + key={item.id}> + {({ renderCell, columnId }) => ( + + {renderCell(item)} + + )} + + )} + + + ); +} + +/** + * Style some columns to take up less space. + */ +function getNarrowColumnStyles(columnId: TableColumnId) { + const stringId = columnId.toString(); + + return { + flexGrow: ["queue", "eta"].includes(stringId) ? "0" : "1", + flexBasis: ["queue", "eta"].includes(stringId) ? "12ch" : "0", + }; +} diff --git a/urbackupserver/www2/src/features/activities/ProcessSpeedChart.tsx b/urbackupserver/www2/src/features/activities/ProcessSpeedChart.tsx new file mode 100644 index 00000000..b792cabd --- /dev/null +++ b/urbackupserver/www2/src/features/activities/ProcessSpeedChart.tsx @@ -0,0 +1,36 @@ +import { type IChartProps, Sparkline } from "@fluentui/react-charting"; +import { tokens } from "@fluentui/react-components"; + +import type { ProcessItem } from "../../api/urbackupserver"; +import { format_speed_bpms_to_bps } from "../../utils/format"; + +const sparklineStyles = { + valueText: { + fill: tokens.colorNeutralForeground1, + }, +}; + +export function ProcessSpeedChart(process: ProcessItem) { + if (process.speed_bpms === 0 && process.past_speed_bpms.length === 0) { + return "-"; + } + + const legend = + process.speed_bpms > 0 ? format_speed_bpms_to_bps(process.speed_bpms) : ""; + + const data: IChartProps = { + chartTitle: "Speed chart", + lineChartData: [ + { + legend, + color: tokens.colorBrandBackground, + data: process.past_speed_bpms.map((d, i) => ({ + x: i + 1, + y: d, + })), + }, + ], + }; + + return ; +} diff --git a/urbackupserver/www2/src/pages/Activities.tsx b/urbackupserver/www2/src/pages/Activities.tsx index 7b87dbd8..9fcde8fd 100644 --- a/urbackupserver/www2/src/pages/Activities.tsx +++ b/urbackupserver/www2/src/pages/Activities.tsx @@ -4,11 +4,12 @@ import { useSuspenseQuery } from "@tanstack/react-query"; import { urbackupServer } from "../App"; import { LastActivitiesTable } from "../features/activities/LastActivitiesTable"; +import { OngoingActivitiesTable } from "../features/activities/OngoingActivitiesTable"; const useStyles = makeStyles({ root: { display: "grid", - gap: tokens.spacingHorizontalL, + gap: tokens.spacingVerticalXXXL, }, heading: { marginBlockStart: 0, @@ -27,14 +28,19 @@ export const ActivitiesPage = () => { const classes = useStyles(); const lastacts = progressResult.data!.lastacts; + const progress = progressResult.data!.progress; return ( }>
-
+
+

Activities

+ +
+

Last Activities

-
- + +
); From 01e14f5aa2dd92a3ac83c75c365fa74dd9562bf6 Mon Sep 17 00:00:00 2001 From: Kazi Date: Sun, 3 Nov 2024 17:38:03 +0600 Subject: [PATCH 5/5] Document to remove incorrect function param type --- urbackupserver/www2/src/utils/format.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/urbackupserver/www2/src/utils/format.ts b/urbackupserver/www2/src/utils/format.ts index d5de1790..4efeaab9 100644 --- a/urbackupserver/www2/src/utils/format.ts +++ b/urbackupserver/www2/src/utils/format.ts @@ -184,9 +184,7 @@ export function format_speed_bpms_to_bps(bpms: number) { } /** - * Formats a date object into - "YYYY-MM-DD, hh:mm" - * @param datetime {Date} - * @returns string + * Formats a date object into - "YYYY-MM-DD, hh:mm". */ export function formatDatetime(datetime: number) { const date = new Date(datetime * 1000);