mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 04:35:42 +00:00 
			
		
		
		
	[ui] Settings fix (#10239)
* Enhance playwright test * Update zustand * Fix machine settings * Fix for PluginSettingList * Fix user plugin settings * Fix issue in RelatedModelField * Enforce values when rebuilding a form * Update react-hook-form * Enhanced playwright testing
This commit is contained in:
		| @@ -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", | ||||
|   | ||||
| @@ -34,7 +34,12 @@ export function PrintingActions({ | ||||
|  | ||||
|   const enabled = useMemo(() => items.length > 0, [items]); | ||||
|  | ||||
|   const [pluginKey, setPluginKey] = useState<string>(''); | ||||
|   const defaultLabelPlugin = useMemo( | ||||
|     () => userSettings.getSetting('LABEL_DEFAULT_PRINTER'), | ||||
|     [userSettings] | ||||
|   ); | ||||
|  | ||||
|   const [pluginKey, setPluginKey] = useState<string | null>(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: { | ||||
|   | ||||
| @@ -46,6 +46,14 @@ export function RelatedModelField({ | ||||
|   // Keep track of the primary key value for this field | ||||
|   const [pk, setPk] = useState<number | null>(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<number>(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); | ||||
|   | ||||
| @@ -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 <Skeleton animate />; | ||||
|   } | ||||
|  | ||||
|   if ((keys || allKeys).length === 0) { | ||||
|     return ( | ||||
|       <Alert color='blue' icon={<IconInfoCircle />} title={t`No Settings`}> | ||||
|         <Text>{t`There are no configurable settings available`}</Text> | ||||
|       </Alert> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   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 <SettingList settingsState={pluginSettings} onLoaded={onLoaded} />; | ||||
| } | ||||
| @@ -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 <SettingList settingsState={pluginUserSettings} onLoaded={onLoaded} />; | ||||
| } | ||||
| @@ -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 <SettingList settingsState={machineSettings} onChange={onChange} />; | ||||
| } | ||||
|   | ||||
| @@ -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<SettingsStateProps>()((set, get) => ({ | ||||
|   return createStore<SettingsStateProps>()((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<SettingsStateProps>()((set, get) => ({ | ||||
|   return createStore<SettingsStateProps>((set, get) => ({ | ||||
|     settings: [], | ||||
|     lookup: {}, | ||||
|     loaded: false, | ||||
| @@ -255,12 +248,6 @@ export const createMachineSettingsState = ({ | ||||
|       return isTrue(value); | ||||
|     } | ||||
|   })); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     store.getState().fetchSettings(); | ||||
|   }, [machine, configType]); | ||||
|  | ||||
|   return store; | ||||
| }; | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -307,7 +307,10 @@ function MachineDrawer({ | ||||
|           multiple | ||||
|           defaultValue={['machine-info', 'machine-settings', 'driver-settings']} | ||||
|         > | ||||
|           <Accordion.Item value='machine-info'> | ||||
|           <Accordion.Item | ||||
|             key={`machine-info-${machinePk}`} | ||||
|             value='machine-info' | ||||
|           > | ||||
|             <Accordion.Control> | ||||
|               <StylishText size='lg'>{t`Machine Information`}</StylishText> | ||||
|             </Accordion.Control> | ||||
| @@ -393,7 +396,10 @@ function MachineDrawer({ | ||||
|             </Accordion.Panel> | ||||
|           </Accordion.Item> | ||||
|           {machine?.is_driver_available && ( | ||||
|             <Accordion.Item value='machine-settings'> | ||||
|             <Accordion.Item | ||||
|               key={`machine-settings-${machinePk}`} | ||||
|               value='machine-settings' | ||||
|             > | ||||
|               <Accordion.Control> | ||||
|                 <StylishText size='lg'>{t`Machine Settings`}</StylishText> | ||||
|               </Accordion.Control> | ||||
| @@ -409,7 +415,10 @@ function MachineDrawer({ | ||||
|             </Accordion.Item> | ||||
|           )} | ||||
|           {machine?.is_driver_available && ( | ||||
|             <Accordion.Item value='driver-settings'> | ||||
|             <Accordion.Item | ||||
|               key={`driver-settings-${machinePk}`} | ||||
|               value='driver-settings' | ||||
|             > | ||||
|               <Accordion.Control> | ||||
|                 <StylishText size='lg'>{t`Driver Settings`}</StylishText> | ||||
|               </Accordion.Control> | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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== | ||||
|   | ||||
		Reference in New Issue
	
	Block a user