diff --git a/apps/yadoms-cs/src/main.tsx b/apps/yadoms-cs/src/main.tsx index afedcff3..be34c0c0 100644 --- a/apps/yadoms-cs/src/main.tsx +++ b/apps/yadoms-cs/src/main.tsx @@ -1,5 +1,6 @@ import '@mantine/core/styles.css'; import '@mantine/dates/styles.css'; +import '@mantine/notifications/styles.css'; import 'mantine-react-table/styles.css'; import * as ReactDOM from 'react-dom/client'; import App from './app/app'; diff --git a/libs/domain/plugins/src/lib/service/plugin-form.service.ts b/libs/domain/plugins/src/lib/service/plugin-form.service.ts index 9d2c53d4..2ff770d5 100644 --- a/libs/domain/plugins/src/lib/service/plugin-form.service.ts +++ b/libs/domain/plugins/src/lib/service/plugin-form.service.ts @@ -159,10 +159,6 @@ export const getNestedSectionFields = ( field: PluginConfigurationSchemaField; }> = []; for (const [key, field] of Object.entries(configurationSchema)) { - console.log('field?.typ', field?.type); - console.log('parentKey', parentKey); - console.log('selectedKey', selectedKey); - console.log('key', key); switch (field?.type) { case PluginConfigurationSchemaType.CheckboxSection: newInitialValues.push({ @@ -251,6 +247,5 @@ export const getNestedSectionFields = ( }); } } - console.log('newInitialValue sections', newInitialValues); return newInitialValues; }; diff --git a/libs/pages/plugins/src/lib/ui/choose-plugin-modal/choose-plugin-modal.tsx b/libs/pages/plugins/src/lib/ui/choose-plugin-modal/choose-plugin-modal.tsx index 8bbdca63..41321071 100644 --- a/libs/pages/plugins/src/lib/ui/choose-plugin-modal/choose-plugin-modal.tsx +++ b/libs/pages/plugins/src/lib/ui/choose-plugin-modal/choose-plugin-modal.tsx @@ -78,7 +78,7 @@ export function ChoosePluginModal(props: ChoosePluginModalProps) { - + diff --git a/libs/pages/plugins/src/lib/ui/create-new-plugin/create-new-plugin.tsx b/libs/pages/plugins/src/lib/ui/create-new-plugin/create-new-plugin.tsx index 50416f60..058cd78f 100644 --- a/libs/pages/plugins/src/lib/ui/create-new-plugin/create-new-plugin.tsx +++ b/libs/pages/plugins/src/lib/ui/create-new-plugin/create-new-plugin.tsx @@ -41,6 +41,12 @@ export function CreateNewPlugin(props: CreateNewPluginProps) { props.onClose(); } + function closeAllModals() { + pluginConfigurationModalHandlers.close(); + choosePluginModalHandlers.close(); + props.onClose(); + } + return ( <> closePluginConfigurationModal()} + onCloseAllModals={closeAllModals} selectedPluginType={selectedPluginType} selectedPluginConfigurationSchema={selectedPluginConfigurationSchema} /> diff --git a/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugin-configuration-modal.tsx b/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugin-configuration-modal.tsx index 1fdbc7cb..3f141b51 100644 --- a/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugin-configuration-modal.tsx +++ b/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugin-configuration-modal.tsx @@ -25,6 +25,7 @@ export interface PluginConfigurationModalProps { onClose: () => void; selectedPluginConfigurationSchema: PluginConfigurationSchema; selectedPluginType: string; + onCloseAllModals: () => void; } export interface ItemProps extends React.ComponentPropsWithoutRef<'div'> { @@ -54,33 +55,11 @@ export function PluginConfigurationModal(props: PluginConfigurationModalProps) { }) ); }, [props.selectedPluginType, props.selectedPluginConfigurationSchema]); - const form = useForm({ initialValues, - //validate: (values) => - // validateForm(values, props.selectedPluginConfigurationSchema), + validate: (values) => validateForm(values), }); - const onSubmit = () => { - console.log('values on submit', form.values); - const errorValues = Object.values(form.errors); - if (errorValues.length === 0) { - // handle successful form submission - notifications.show({ - title: 'Form submitted', - message: 'Your form has been submitted successfully.', - color: theme.colors.green[6], - }); - } else { - // handle validation errors - notifications.show({ - title: 'Validation error', - message: 'Please fix the errors in the form and try again.', - color: 'red', - }); - } - }; - const handleClose = () => { form.reset(); props.onClose(); @@ -104,10 +83,34 @@ export function PluginConfigurationModal(props: PluginConfigurationModalProps) {
{ - console.log('form', form); - console.log(values); - })} + onSubmit={form.onSubmit( + (values, event) => { + console.log( + values, // <- form.getValues() at the moment of submit + event // <- form element submit event + ); + notifications.show({ + title: 'Form submitted', + message: 'Your form has been submitted successfully.', + color: theme.colors.green[6], + position: 'bottom-right', + }); + }, + (validationErrors, values, event) => { + form.validate(); + console.log( + 'failed', + validationErrors, // <- form.errors at the moment of submit + values, // <- form.getValues() at the moment of submit + event // <- form element submit event + ); + notifications.show({ + title: 'Validation error', + message: 'Please fix the errors in the form and try again.', + color: 'red', + }); + } + )} > {t('plugins.modal.plugin-configuration.back')} - diff --git a/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugins-configuration-forms.ts b/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugins-configuration-forms.ts index 7274f027..11ca7778 100644 --- a/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugins-configuration-forms.ts +++ b/libs/pages/plugins/src/lib/ui/plugin-configuration-modal/plugins-configuration-forms.ts @@ -1,32 +1,68 @@ -import { PluginConfigurationSchema } from '@yadoms/domain/plugins'; +import { PluginConfigurationSchemaType } from '@yadoms/domain/plugins'; -export const validateForm = ( - values: Record, - schema: PluginConfigurationSchema -) => { +export const validateForm: ( + values: Record +) => Record = (values: Record) => { const errors: Record = {}; - const validateField = (key: string, value: any, field: any) => { - if (field.required && (!value || value.trim() === '')) { - errors[key] = `${field.name} is required`; - } - if (field.regex && !new RegExp(field.regex).test(value)) { - errors[key] = field.regexErrorMessage || `${field.name} is invalid`; - } - }; const validateObject = ( - obj: Record, - schema: PluginConfigurationSchema + values: Record, + path = 'configuration' ) => { - Object.entries(schema).forEach(([key, field]) => { - if (field.type === 'section') { - validateObject(obj[key] || {}, field.content || {}); - } else { - validateField(key, obj[key], field); + Object.entries(values).forEach(([key, field]) => { + const currentPath = `${path}.${key}`; + console.log('key', key); + console.log('field', field); + console.log('field.type', field.type); + + switch (field.type) { + case PluginConfigurationSchemaType.String: + if (field.required && field.value?.trim() === '') { + errors[`${currentPath}.value`] = `${field.name} is required`; + } + if (field.regex && !new RegExp(field.regex).test(field.value)) { + errors[`${currentPath}.value`] = + field.regexErrorMessage || `${field.name} is invalid`; + } + break; + + case PluginConfigurationSchemaType.Integer: + if ( + field.required && + (field.value === null || + field.value === undefined || + field.value === '') + ) { + errors[`${currentPath}.value`] = `${field.name} is required`; + } + if (field.regex && !new RegExp(field.regex).test(field.value)) { + errors[`${currentPath}.value`] = + field.regexErrorMessage || `${field.name} is invalid`; + } + break; + + case PluginConfigurationSchemaType.Decimal: + if ( + field.value === null || + field.value === undefined || + field.value === '' + ) { + errors[`${currentPath}.value`] = `${field.name} is required`; + } + break; + + case PluginConfigurationSchemaType.Section: + console.log('section currentPath', currentPath); + validateObject(field.content, `${currentPath}.content`); + break; + default: + break; } }); }; - validateObject(values, schema); + validateObject(values['configuration']); + + console.log('errors', errors); return errors; }; diff --git a/package-lock.json b/package-lock.json index 508fefea..5388732d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,12 @@ "license": "MIT", "dependencies": { "@emotion/react": "^11.11.4", - "@mantine/core": "^7.10.1", - "@mantine/dates": "^7.10.1", - "@mantine/form": "^7.10.1", - "@mantine/hooks": "^7.10.1", - "@mantine/modals": "^7.10.1", - "@mantine/notifications": "^7.10.1", + "@mantine/core": "^7.12.0", + "@mantine/dates": "^7.12.0", + "@mantine/form": "^7.12.0", + "@mantine/hooks": "^7.12.0", + "@mantine/modals": "^7.12.0", + "@mantine/notifications": "^7.12.0", "@reduxjs/toolkit": "2.2.5", "@tabler/icons-react": "^3.5.0", "@tanstack/react-query": "^5.39.0", @@ -24,7 +24,7 @@ "dayjs": "^1.11.11", "i18next": "^23.11.5", "i18next-browser-languagedetector": "^8.0.0", - "mantine-react-table": "^2.0.0-beta.3", + "mantine-react-table": "^2.0.0-beta.6", "react": "18.3.1", "react-dom": "18.3.1", "react-i18next": "^14.1.2", @@ -3139,9 +3139,9 @@ } }, "node_modules/@mantine/core": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.10.1.tgz", - "integrity": "sha512-l9ypojKN3PjwO1CSLIsqxi7mA25+7w+xc71Q+JuCCREI0tuGwkZsKbIOpuTATIJOjPh8ycLiW7QxX1LYsRTq6w==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.12.0.tgz", + "integrity": "sha512-FxsaIaEnqxV71MBGGsvXXad2q9KYTaIQFVP4TSAZI6xLChklXF/qJTqvabweaoW9BaVQT75b/BnUoJFzPfyAfw==", "dependencies": { "@floating-ui/react": "^0.26.9", "clsx": "^2.1.1", @@ -3151,30 +3151,30 @@ "type-fest": "^4.12.0" }, "peerDependencies": { - "@mantine/hooks": "7.10.1", + "@mantine/hooks": "7.12.0", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/dates": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-7.10.1.tgz", - "integrity": "sha512-XkzYaHgzJPrquG78/exJd0dLeghJvRgypfSRwFH7IcR34Eo2MD3nsuorZp09i9sYnROcXqIFhZWgwk5cqg/8nw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-7.12.0.tgz", + "integrity": "sha512-68oDcDV+FnhQK90J9vFtO872rT303nGwR4DpAQqFAzdNBWxc3h5089/S+rehYryH4Pcwru4t0FqSB4fRvlUtLw==", "dependencies": { "clsx": "^2.1.1" }, "peerDependencies": { - "@mantine/core": "7.10.1", - "@mantine/hooks": "7.10.1", + "@mantine/core": "7.12.0", + "@mantine/hooks": "7.12.0", "dayjs": ">=1.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/form": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.10.1.tgz", - "integrity": "sha512-mZwzg4GEWKEDKEIZu9FmSpGFzYYhFD2YArVOXUM0MMciUqX7yxSCon1PaPJxrV8ldc6FE+JLVI2+G2KVxJ3ZXA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.12.0.tgz", + "integrity": "sha512-npNHxjis/tOun12EYPYP9cQwJbtFHcGZF1m2yNCcNFVMdkBtTiqH23DdGByXmJRkypYQssSMdQTm3F1zfGsjdQ==", "dependencies": { "fast-deep-equal": "^3.1.3", "klona": "^2.0.6" @@ -3184,43 +3184,43 @@ } }, "node_modules/@mantine/hooks": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.10.1.tgz", - "integrity": "sha512-0EH9WBWUdtQLGU3Ak+csQ77EtUxI6pPNfwZdRJQWcaA3f8SFOLo9h9CGxiikFExerhvuCeUlaTf3s+TB9Op/rw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.12.0.tgz", + "integrity": "sha512-UKMSpQZMdmecZX1PKPoknfUOE9MfDPiZR1myU4wUUKpaZibvvmhYuy8mcOOmYWegapRS3ErKIAc2cNnJ1Dk4RQ==", "peerDependencies": { "react": "^18.2.0" } }, "node_modules/@mantine/modals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-7.10.1.tgz", - "integrity": "sha512-2riQSNpVV7f0baizlqcggz9hx9/+y6SQTnW3zEkl/RIkuyK9dpeMFUG6M+M8ntwP79b7x9n7Em9PMWxRbgi28A==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-7.12.0.tgz", + "integrity": "sha512-CXt2nUK0VuWc+cwC1flCeH5FnQYjA8iQfGgZ37wSFv2qxzJFQ61QlRJjdgIG7T+DccUHjqXKkjYohLxXE36EQQ==", "peerDependencies": { - "@mantine/core": "7.10.1", - "@mantine/hooks": "7.10.1", + "@mantine/core": "7.12.0", + "@mantine/hooks": "7.12.0", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/notifications": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.10.1.tgz", - "integrity": "sha512-cx3JR3BJzEzH6t2EF1ysrWVY/rdJk0WbSBQo/qFamJd2sbU+8XAHriI8Cx6hNo7uRGCwd8VGAj7Cf3aWK2VC5A==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.12.0.tgz", + "integrity": "sha512-eW2g66b1K/EUdHD842QnQHWdKWbk1mCJkzDAyxcMGZ2BqU2zzpTUZdexbfDg2BqE/Mj/BGc3B9r2mKHt/6ebBg==", "dependencies": { - "@mantine/store": "7.10.1", + "@mantine/store": "7.12.0", "react-transition-group": "4.4.5" }, "peerDependencies": { - "@mantine/core": "7.10.1", - "@mantine/hooks": "7.10.1", + "@mantine/core": "7.12.0", + "@mantine/hooks": "7.12.0", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/store": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.10.1.tgz", - "integrity": "sha512-KrGBsSoMsfrYeLxPwf5rFv0s2Nl/4wf+AaF/U1SpQrMgPI8vYokPXx52Wp3jCmlo12NCZnCIG+/6YHAdTWH1qQ==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.12.0.tgz", + "integrity": "sha512-gKOJQVKTxJQbjhG/qlaLiv47ydHgdN+ZC2jFRJHr1jjNeiCqzIT4wX1ofG27c5byPTAwAHvuf+/FLOV3rywUpA==", "peerDependencies": { "react": "^18.2.0" } @@ -9277,11 +9277,11 @@ } }, "node_modules/@tanstack/react-table": { - "version": "8.17.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.17.3.tgz", - "integrity": "sha512-5gwg5SvPD3lNAXPuJJz1fOCEZYk9/GeBFH3w/hCgnfyszOIzwkwgp5I7Q4MJtn0WECp84b5STQUDdmvGi8m3nA==", + "version": "8.19.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.19.3.tgz", + "integrity": "sha512-MtgPZc4y+cCRtU16y1vh1myuyZ2OdkWgMEBzyjYsoMWMicKZGZvcDnub3Zwb6XF2pj9iRMvm1SO1n57lS0vXLw==", "dependencies": { - "@tanstack/table-core": "8.17.3" + "@tanstack/table-core": "8.19.3" }, "engines": { "node": ">=12" @@ -9296,11 +9296,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", - "integrity": "sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.3.tgz", + "integrity": "sha512-9ICwbDUUzN99CJIGc373i8NLoj6zFTKI2Hlcmo0+lCSAhPQ5mxq4dGOMKmLYoEFyHcGQ64Bd6ZVbnPpM6lNK5w==", "dependencies": { - "@tanstack/virtual-core": "3.5.0" + "@tanstack/virtual-core": "3.8.3" }, "funding": { "type": "github", @@ -9312,9 +9312,9 @@ } }, "node_modules/@tanstack/table-core": { - "version": "8.17.3", - "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.17.3.tgz", - "integrity": "sha512-mPBodDGVL+fl6d90wUREepHa/7lhsghg2A3vFpakEhrhtbIlgNAZiMr7ccTgak5qbHqF14Fwy+W1yFWQt+WmYQ==", + "version": "8.19.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.19.3.tgz", + "integrity": "sha512-IqREj9ADoml9zCAouIG/5kCGoyIxPFdqdyoxis9FisXFi5vT+iYfEfLosq4xkU/iDbMcEuAj+X8dWRLvKYDNoQ==", "engines": { "node": ">=12" }, @@ -9324,9 +9324,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz", - "integrity": "sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz", + "integrity": "sha512-vd2A2TnM5lbnWZnHi9B+L2gPtkSeOtJOAw358JqokIH1+v2J7vUAzFVPwB/wrye12RFOurffXu33plm4uQ+JBQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -18060,13 +18060,13 @@ "dev": true }, "node_modules/mantine-react-table": { - "version": "2.0.0-beta.4", - "resolved": "https://registry.npmjs.org/mantine-react-table/-/mantine-react-table-2.0.0-beta.4.tgz", - "integrity": "sha512-uMsSKWCC7TAbdApnYu4FhDr5bLU1l5YdmEtvyI+RkEGG7tKBbelOb9rlLnVpL55G8C6kH70l3Fw3lChcWDZSQw==", + "version": "2.0.0-beta.6", + "resolved": "https://registry.npmjs.org/mantine-react-table/-/mantine-react-table-2.0.0-beta.6.tgz", + "integrity": "sha512-eaHdVjJWFLIAGS0PwdMisvs1U9IUanEzL+vm1+YcoDtUNFVGms1jw7neK43YH+CmA2YsFLfwRqHrtFnfI12Rag==", "dependencies": { "@tanstack/match-sorter-utils": "8.15.1", - "@tanstack/react-table": "8.17.3", - "@tanstack/react-virtual": "3.5.0" + "@tanstack/react-table": "8.19.3", + "@tanstack/react-virtual": "3.8.3" }, "engines": { "node": ">=16" diff --git a/package.json b/package.json index b045b207..17de1ded 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "private": true, "dependencies": { "@emotion/react": "^11.11.4", - "@mantine/core": "^7.10.1", - "@mantine/dates": "^7.10.1", - "@mantine/form": "^7.10.1", - "@mantine/hooks": "^7.10.1", - "@mantine/modals": "^7.10.1", - "@mantine/notifications": "^7.10.1", + "@mantine/core": "^7.12.0", + "@mantine/dates": "^7.12.0", + "@mantine/form": "^7.12.0", + "@mantine/hooks": "^7.12.0", + "@mantine/modals": "^7.12.0", + "@mantine/notifications": "^7.12.0", "@reduxjs/toolkit": "2.2.5", "@tabler/icons-react": "^3.5.0", "@tanstack/react-query": "^5.39.0", @@ -34,7 +34,7 @@ "dayjs": "^1.11.11", "i18next": "^23.11.5", "i18next-browser-languagedetector": "^8.0.0", - "mantine-react-table": "^2.0.0-beta.3", + "mantine-react-table": "^2.0.0-beta.6", "react": "18.3.1", "react-dom": "18.3.1", "react-i18next": "^14.1.2",