diff --git a/src/frontend/package.json b/src/frontend/package.json index 8e99823c6f..ee09e91414 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -93,7 +93,7 @@ "react": "^19.1.1", "react-dom": "^19.1.1", "react-grid-layout": "1.4.4", - "react-hook-form": "^7.54.2", + "react-hook-form": "^7.62.0", "react-is": "^19.1.1", "react-router-dom": "^6.26.2", "react-select": "^5.9.0", @@ -101,7 +101,7 @@ "react-window": "1.8.11", "recharts": "^2.15.0", "styled-components": "^6.1.14", - "zustand": "^5.0.3" + "zustand": "^5.0.8" }, "devDependencies": { "@babel/core": "^7.26.10", diff --git a/src/frontend/src/components/buttons/PrintingActions.tsx b/src/frontend/src/components/buttons/PrintingActions.tsx index 571cf0545c..b65ec6eeb6 100644 --- a/src/frontend/src/components/buttons/PrintingActions.tsx +++ b/src/frontend/src/components/buttons/PrintingActions.tsx @@ -34,7 +34,12 @@ export function PrintingActions({ const enabled = useMemo(() => items.length > 0, [items]); - const [pluginKey, setPluginKey] = useState(''); + const defaultLabelPlugin = useMemo( + () => userSettings.getSetting('LABEL_DEFAULT_PRINTER'), + [userSettings] + ); + + const [pluginKey, setPluginKey] = useState(null); const labelPrintingEnabled = useMemo(() => { return enableLabels && globalSettings.isSet('LABEL_ENABLE'); @@ -96,7 +101,8 @@ export function PrintingActions({ fields['plugin'] = { ...fields['plugin'], - value: userSettings.getSetting('LABEL_DEFAULT_PRINTER'), + default: defaultLabelPlugin, + value: pluginKey, filters: { active: true, mixin: 'labels' @@ -109,11 +115,12 @@ export function PrintingActions({ }; return fields; - }, [printingFields.data, items]); + }, [defaultLabelPlugin, pluginKey, printingFields.data, items]); const labelModal = useCreateApiFormModal({ url: apiUrl(ApiEndpoints.label_print), title: t`Print Label`, + modalId: 'print-labels', fields: labelFields, timeout: 5000, onClose: () => { @@ -128,8 +135,9 @@ export function PrintingActions({ }); const reportModal = useCreateApiFormModal({ - title: t`Print Report`, url: apiUrl(ApiEndpoints.report_print), + title: t`Print Report`, + modalId: 'print-reports', timeout: 5000, fields: { template: { diff --git a/src/frontend/src/components/forms/fields/RelatedModelField.tsx b/src/frontend/src/components/forms/fields/RelatedModelField.tsx index 2164ac4540..bc74b6c5e2 100644 --- a/src/frontend/src/components/forms/fields/RelatedModelField.tsx +++ b/src/frontend/src/components/forms/fields/RelatedModelField.tsx @@ -46,6 +46,14 @@ export function RelatedModelField({ // Keep track of the primary key value for this field const [pk, setPk] = useState(null); + // Handle condition where the form is rebuilt dynamically + useEffect(() => { + const value = field.value || pk; + if (value && value != form.getValues()[fieldName]) { + form.setValue(fieldName, value); + } + }, [pk, field.value]); + const [offset, setOffset] = useState(0); const [initialData, setInitialData] = useState<{}>({}); @@ -118,12 +126,10 @@ export function RelatedModelField({ // If the value is unchanged, do nothing if (field.value === pk) return; - if ( - field?.value !== null && - field?.value !== undefined && - field?.value !== '' - ) { - const url = `${definition.api_url}${field.value}/`; + const id = pk || field.value; + + if (id !== null && id !== undefined && id !== '') { + const url = `${definition.api_url}${id}/`; if (!url) { setPk(null); diff --git a/src/frontend/src/components/settings/SettingList.tsx b/src/frontend/src/components/settings/SettingList.tsx index f54960e86c..ca1e76627f 100644 --- a/src/frontend/src/components/settings/SettingList.tsx +++ b/src/frontend/src/components/settings/SettingList.tsx @@ -2,20 +2,14 @@ import { t } from '@lingui/core/macro'; import { Trans } from '@lingui/react/macro'; import { Alert, Skeleton, Stack, Text } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState -} from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useStore } from 'zustand'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import type { ModelType } from '@lib/enums/ModelType'; import { apiUrl } from '@lib/functions/Api'; import type { Setting, SettingsStateProps } from '@lib/types/Settings'; -import { IconExclamationCircle } from '@tabler/icons-react'; +import { IconExclamationCircle, IconInfoCircle } from '@tabler/icons-react'; import { useApi } from '../../contexts/ApiContext'; import { useEditApiFormModal } from '../../hooks/UseForm'; import { @@ -152,6 +146,14 @@ export function SettingList({ return ; } + if ((keys || allKeys).length === 0) { + return ( + } title={t`No Settings`}> + {t`There are no configurable settings available`} + + ); + } + return ( <> {editSettingModal.modal} @@ -211,13 +213,20 @@ export function PluginSettingList({ pluginKey: string; onLoaded?: (settings: SettingsStateProps) => void; }>) { - const pluginSettingsStore = useRef( - createPluginSettingsState({ - plugin: pluginKey, - endpoint: ApiEndpoints.plugin_setting_list - }) - ).current; - const pluginSettings = useStore(pluginSettingsStore); + const store = useMemo( + () => + createPluginSettingsState({ + plugin: pluginKey, + endpoint: ApiEndpoints.plugin_setting_list + }), + [pluginKey] + ); + + const pluginSettings = useStore(store); + + useEffect(() => { + pluginSettings.fetchSettings(); + }, [pluginSettings.fetchSettings]); return ; } @@ -229,13 +238,20 @@ export function PluginUserSettingList({ pluginKey: string; onLoaded?: (settings: SettingsStateProps) => void; }>) { - const pluginUserSettingsState = useRef( - createPluginSettingsState({ - plugin: pluginKey, - endpoint: ApiEndpoints.plugin_user_setting_list - }) - ).current; - const pluginUserSettings = useStore(pluginUserSettingsState); + const store = useMemo( + () => + createPluginSettingsState({ + plugin: pluginKey, + endpoint: ApiEndpoints.plugin_user_setting_list + }), + [pluginKey] + ); + + const pluginUserSettings = useStore(store); + + useEffect(() => { + pluginUserSettings.fetchSettings(); + }, [pluginUserSettings.fetchSettings]); return ; } @@ -249,13 +265,20 @@ export function MachineSettingList({ configType: 'M' | 'D'; onChange?: () => void; }>) { - const machineSettingsStore = useRef( - createMachineSettingsState({ - machine: machinePk, - configType: configType - }) - ).current; - const machineSettings = useStore(machineSettingsStore); + const store = useMemo( + () => + createMachineSettingsState({ + machine: machinePk, + configType: configType + }), + [machinePk, configType] + ); + + const machineSettings = useStore(store); + + useEffect(() => { + machineSettings.fetchSettings(); + }, [machineSettings.fetchSettings]); return ; } diff --git a/src/frontend/src/states/SettingsStates.tsx b/src/frontend/src/states/SettingsStates.tsx index a44445a4c3..4eeecb3053 100644 --- a/src/frontend/src/states/SettingsStates.tsx +++ b/src/frontend/src/states/SettingsStates.tsx @@ -12,7 +12,6 @@ import type { SettingsLookup, SettingsStateProps } from '@lib/types/Settings'; -import { useEffect } from 'react'; import { api } from '../App'; import { useUserState } from './UserState'; @@ -132,7 +131,7 @@ export const createPluginSettingsState = ({ }: CreatePluginSettingStateProps) => { const pathParams: PathParams = { plugin }; - const store = createStore()((set, get) => ({ + return createStore()((set, get) => ({ settings: [], lookup: {}, loaded: false, @@ -188,12 +187,6 @@ export const createPluginSettingsState = ({ return isTrue(value); } })); - - useEffect(() => { - store.getState().fetchSettings(); - }, [plugin]); - - return store; }; /** @@ -210,7 +203,7 @@ export const createMachineSettingsState = ({ }: CreateMachineSettingStateProps) => { const pathParams: PathParams = { machine, config_type: configType }; - const store = createStore()((set, get) => ({ + return createStore((set, get) => ({ settings: [], lookup: {}, loaded: false, @@ -255,12 +248,6 @@ export const createMachineSettingsState = ({ return isTrue(value); } })); - - useEffect(() => { - store.getState().fetchSettings(); - }, [machine, configType]); - - return store; }; /* diff --git a/src/frontend/src/tables/machine/MachineListTable.tsx b/src/frontend/src/tables/machine/MachineListTable.tsx index d57a63f6b7..bc15a60e62 100644 --- a/src/frontend/src/tables/machine/MachineListTable.tsx +++ b/src/frontend/src/tables/machine/MachineListTable.tsx @@ -307,7 +307,10 @@ function MachineDrawer({ multiple defaultValue={['machine-info', 'machine-settings', 'driver-settings']} > - + {t`Machine Information`} @@ -393,7 +396,10 @@ function MachineDrawer({ {machine?.is_driver_available && ( - + {t`Machine Settings`} @@ -409,7 +415,10 @@ function MachineDrawer({ )} {machine?.is_driver_available && ( - + {t`Driver Settings`} diff --git a/src/frontend/tests/pui_machines.spec.ts b/src/frontend/tests/pui_machines.spec.ts index 2e268cd2d0..4a9d830a2f 100644 --- a/src/frontend/tests/pui_machines.spec.ts +++ b/src/frontend/tests/pui_machines.spec.ts @@ -33,21 +33,35 @@ test('Machines - Activation', async ({ browser, request }) => { }); await page.reload(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1000); - await page.getByRole('button', { name: 'action-button-add-machine' }).click(); - await page - .getByRole('textbox', { name: 'text-field-name' }) - .fill('my-dummy-machine'); - await page - .getByRole('textbox', { name: 'choice-field-machine_type' }) - .fill('label'); - await page.getByRole('option', { name: 'Label Printer' }).click(); + // Create machine config if it does not already exist + const exists: boolean = await page + .getByRole('cell', { name: 'my-dummy-machine' }) + .isVisible({ timeout: 250 }); - await page.getByRole('textbox', { name: 'choice-field-driver' }).click(); - await page - .getByRole('option', { name: 'Sample Label Printer Driver' }) - .click(); - await page.getByRole('button', { name: 'Submit' }).click(); + if (!exists) { + await page + .getByRole('button', { name: 'action-button-add-machine' }) + .click(); + await page + .getByRole('textbox', { name: 'text-field-name' }) + .fill('my-dummy-machine'); + await page + .getByRole('textbox', { name: 'choice-field-machine_type' }) + .fill('label'); + await page.getByRole('option', { name: 'Label Printer' }).click(); + + await page.getByRole('textbox', { name: 'choice-field-driver' }).click(); + await page + .getByRole('option', { name: 'Sample Label Printer Driver' }) + .click(); + await page.getByRole('button', { name: 'Submit' }).click(); + } else { + // Machine already exists - just click on it to open the "machine drawer" + await page.getByRole('cell', { name: 'my-dummy-machine' }).click(); + } // Creating the new machine opens the "machine drawer" @@ -59,9 +73,14 @@ test('Machines - Activation', async ({ browser, request }) => { // Edit the available setting await page.getByRole('button', { name: 'edit-setting-CONNECTION' }).click(); + + const setting_value = await page + .getByRole('textbox', { name: 'text-field-value' }) + .inputValue(); + await page .getByRole('textbox', { name: 'text-field-value' }) - .fill('a new value'); + .fill(`${setting_value}-2`); await page.getByRole('button', { name: 'Submit' }).click(); await page.getByText('Setting CONNECTION updated successfully').waitFor(); diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index 511e66e006..5fe92ab7ce 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -1328,7 +1328,7 @@ "@messageformat/date-skeleton@^1.1.0": version "1.1.0" - resolved "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz#3bad068cbf5873d14592cfc7a73dd4d8615e2739" integrity sha512-rmGAfB1tIPER+gh3p/RgA+PVeRE/gxuQ2w4snFWPF5xtb5mbWR7Cbw7wCOftcUypbD6HVoxrVdyyghPm3WzP5A== "@messageformat/parser@^5.0.0": @@ -1770,53 +1770,53 @@ "@types/d3-array@^3.0.3": version "3.2.1" - resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== "@types/d3-color@*": version "3.1.3" - resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== "@types/d3-ease@^3.0.0": version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== "@types/d3-interpolate@^3.0.1": version "3.0.4" - resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== dependencies: "@types/d3-color" "*" "@types/d3-path@*": - version "3.1.0" - resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" + integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== "@types/d3-scale@^4.0.2": - version "4.0.8" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz" - integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" + integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== dependencies: "@types/d3-time" "*" "@types/d3-shape@^3.1.0": - version "3.1.6" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz" - integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== + version "3.1.7" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555" + integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== dependencies: "@types/d3-path" "*" "@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz" - integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" + integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== "@types/d3-timer@^3.0.0": version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== "@types/estree@*", "@types/estree@1.0.7", "@types/estree@^1.0.0": @@ -2660,41 +2660,41 @@ csstype@3.1.3, csstype@^3.0.2, csstype@^3.0.7: "d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== dependencies: internmap "1 - 2" "d3-color@1 - 3": version "3.1.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== d3-ease@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== "d3-format@1 - 3": version "3.1.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== "d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: d3-color "1 - 3" d3-path@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== d3-scale@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== dependencies: d3-array "2.10.0 - 3" @@ -2705,28 +2705,28 @@ d3-scale@^4.0.2: d3-shape@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== dependencies: d3-path "^3.1.0" "d3-time-format@2 - 4": version "4.1.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== dependencies: d3-time "1 - 3" "d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== dependencies: d3-array "2 - 3" d3-timer@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== date-fns@^3.6.0: @@ -2758,7 +2758,7 @@ decamelize@^1.2.0: decimal.js-light@^2.4.1: version "2.5.1" - resolved "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== dedent@^1.5.3: @@ -3017,7 +3017,7 @@ eval@0.1.8: eventemitter3@^4.0.1: version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== exsolve@^1.0.1: @@ -3045,9 +3045,9 @@ fast-equals@^4.0.3: integrity sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg== fast-equals@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz" - integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== + version "5.2.2" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.2.2.tgz#885d7bfb079fac0ce0e8450374bce29e9b742484" + integrity sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw== fdir@6.3.0: version "6.3.0" @@ -3408,7 +3408,7 @@ inquirer@^7.3.3: "internmap@1 - 2": version "2.0.3" - resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== is-arrayish@^0.2.1: @@ -3699,7 +3699,7 @@ lodash.sortby@^4.7.0: lodash@^4.17.19, lodash@^4.17.21, lodash@~4.17.15, lodash@~4.17.21: version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^4.1.0: @@ -4344,10 +4344,10 @@ react-grid-layout@1.4.4: react-resizable "^3.0.5" resize-observer-polyfill "^1.5.1" -react-hook-form@^7.54.2: - version "7.54.2" - resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.2.tgz" - integrity sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg== +react-hook-form@^7.62.0: + version "7.62.0" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.62.0.tgz#2d81e13c2c6b6d636548e440818341ca753218d0" + integrity sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" @@ -4356,7 +4356,7 @@ react-is@^16.13.1, react-is@^16.7.0: react-is@^18.0.0, react-is@^18.3.1: version "18.3.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-is@^19.1.1: @@ -4438,10 +4438,10 @@ react-simplemde-editor@^5.2.0: dependencies: "@types/codemirror" "~5.60.5" -react-smooth@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz" - integrity sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w== +react-smooth@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.4.tgz#a5875f8bb61963ca61b819cedc569dc2453894b4" + integrity sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q== dependencies: fast-equals "^5.0.1" prop-types "^15.8.1" @@ -4505,21 +4505,21 @@ readdirp@~3.5.0: recharts-scale@^0.4.4: version "0.4.5" - resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== dependencies: decimal.js-light "^2.4.1" recharts@^2.15.0: - version "2.15.0" - resolved "https://registry.npmjs.org/recharts/-/recharts-2.15.0.tgz" - integrity sha512-cIvMxDfpAmqAmVgc4yb7pgm/O1tmmkl/CjrvXuW+62/+7jj/iF9Ykm+hb/UJt42TREHMyd3gb+pkgoa2MxgDIw== + version "2.15.4" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.15.4.tgz#0ed3e66c0843bcf2d9f9a172caf97b1d05127a5f" + integrity sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw== dependencies: clsx "^2.0.0" eventemitter3 "^4.0.1" lodash "^4.17.21" react-is "^18.3.1" - react-smooth "^4.0.0" + react-smooth "^4.0.4" recharts-scale "^0.4.4" tiny-invariant "^1.3.1" victory-vendor "^36.6.8" @@ -4951,7 +4951,7 @@ through@^2.3.6: tiny-invariant@^1.3.1: version "1.3.3" - resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== tinyglobby@^0.2.13: @@ -5141,7 +5141,7 @@ uuid@^8.3.2: victory-vendor@^36.6.8: version "36.9.2" - resolved "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.9.2.tgz#668b02a448fa4ea0f788dbf4228b7e64669ff801" integrity sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ== dependencies: "@types/d3-array" "^3.0.3" @@ -5377,7 +5377,7 @@ zod@^3.22.4: resolved "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== -zustand@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz" - integrity sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg== +zustand@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.8.tgz#b998a0c088c7027a20f2709141a91cb07ac57f8a" + integrity sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==