@deenruv/admin-dashboard 1.0.5 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/DeenruvAdminPanel.js +5 -4
  2. package/dist/DeenruvDeveloperIndicator.js +1 -1
  3. package/dist/components/ContentAreaSkeleton.js +5 -0
  4. package/dist/components/Menu/LanguagesDropdown.js +4 -3
  5. package/dist/components/Menu/Navigation.js +10 -9
  6. package/dist/components/Menu/Notifications.js +2 -1
  7. package/dist/components/Menu/flag-icons.js +16 -0
  8. package/dist/components/Menu/index.js +3 -2
  9. package/dist/pages/Custom404.js +16 -2
  10. package/dist/pages/Root.js +2 -2
  11. package/dist/pages/admins/Detail.js +7 -7
  12. package/dist/pages/admins/_components/AdminDetailView.js +17 -9
  13. package/dist/pages/channels/Detail.js +12 -12
  14. package/dist/pages/channels/_components/ChannelDetailView.js +25 -17
  15. package/dist/pages/collections/Detail.js +8 -7
  16. package/dist/pages/collections/List.js +1 -2
  17. package/dist/pages/collections/_components/CollectionDetailView.js +65 -22
  18. package/dist/pages/collections/_components/CollectionProductVariantsDrawer.js +1 -1
  19. package/dist/pages/countries/Detail.js +5 -5
  20. package/dist/pages/countries/_components/CountryDetailView.js +15 -8
  21. package/dist/pages/customer-groups/Detail.js +3 -3
  22. package/dist/pages/customer-groups/_components/CustomerGroupsDetailView.js +4 -4
  23. package/dist/pages/customers/Detail.js +6 -8
  24. package/dist/pages/customers/_components/AddressForm.js +48 -60
  25. package/dist/pages/customers/_components/AddressesCard.js +1 -1
  26. package/dist/pages/customers/_components/CustomerDetailView.js +9 -9
  27. package/dist/pages/dashboard/Dashboard.js +3 -2
  28. package/dist/pages/extensions/Extensions.js +12 -13
  29. package/dist/pages/facets/Detail.js +6 -6
  30. package/dist/pages/facets/_components/AddFacetValueDialog.js +39 -39
  31. package/dist/pages/facets/_components/FacetDetailView.js +19 -12
  32. package/dist/pages/global-settings/GlobalSettingsComponent.js +9 -8
  33. package/dist/pages/global-settings/index.js +4 -4
  34. package/dist/pages/orders/List.js +2 -1
  35. package/dist/pages/orders/_components/AddressCard.js +123 -78
  36. package/dist/pages/orders/_components/CustomerSelectCard.js +38 -43
  37. package/dist/pages/orders/_components/FulfillmentModal.js +47 -28
  38. package/dist/pages/orders/_components/ModifyingCard.js +30 -13
  39. package/dist/pages/orders/_components/OrderLineCustomFields.js +2 -1
  40. package/dist/pages/orders/_components/PossibleOrderStates.js +2 -1
  41. package/dist/pages/orders/_components/ProductsCard.js +2 -1
  42. package/dist/pages/orders/_components/SurchargeCard.js +58 -60
  43. package/dist/pages/orders/_components/TopActions.js +2 -1
  44. package/dist/pages/payment-methods/Detail.js +8 -7
  45. package/dist/pages/payment-methods/_components/PaymentMethodDetailView.js +22 -14
  46. package/dist/pages/products/Detail.js +9 -7
  47. package/dist/pages/products/_components/AddOptionGroupDialog.js +36 -14
  48. package/dist/pages/products/_components/BasicFieldsCard.js +5 -2
  49. package/dist/pages/products/_components/OptionValueCard.js +25 -23
  50. package/dist/pages/products/_components/ProductDetailSidebar.js +15 -7
  51. package/dist/pages/products/_components/ProductDetailView.js +51 -17
  52. package/dist/pages/products/_components/Variant.js +105 -57
  53. package/dist/pages/promotions/Detail.js +13 -11
  54. package/dist/pages/promotions/_components/OptionsCard.js +1 -1
  55. package/dist/pages/promotions/_components/PromotionDetailSidebar.js +9 -6
  56. package/dist/pages/promotions/_components/PromotionDetailView.js +26 -20
  57. package/dist/pages/roles/Detail.js +5 -5
  58. package/dist/pages/roles/_components/RoleDetailView.js +13 -8
  59. package/dist/pages/sellers/Detail.js +4 -4
  60. package/dist/pages/sellers/_components/SellerDetailView.js +4 -4
  61. package/dist/pages/shipping-methods/Detail.js +14 -12
  62. package/dist/pages/shipping-methods/_components/Lines.js +1 -1
  63. package/dist/pages/shipping-methods/_components/ShippingMethodDetailView.js +26 -13
  64. package/dist/pages/shipping-methods/_components/TestCard.js +67 -21
  65. package/dist/pages/status/_components/Health.js +2 -1
  66. package/dist/pages/status/_components/Jobs.js +2 -6
  67. package/dist/pages/stock-locations/Detail.js +4 -4
  68. package/dist/pages/stock-locations/_components/StockLocationDetailView.js +5 -5
  69. package/dist/pages/tax-categories/Detail.js +4 -4
  70. package/dist/pages/tax-categories/_components/TaxCategoryDetailView.js +7 -7
  71. package/dist/pages/tax-rates/Detail.js +8 -8
  72. package/dist/pages/tax-rates/_components/TaxRateDetailView.js +13 -9
  73. package/dist/pages/zones/Detail.js +4 -4
  74. package/dist/pages/zones/_components/ZoneDetailView.js +8 -7
  75. package/dist/version.js +1 -1
  76. package/package.json +79 -78
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useCallback } from 'react';
3
3
  import { useParams } from 'react-router';
4
- import { useTranslation, DetailView, createDeenruvForm, getMutation, useMutation, } from '@deenruv/react-ui-devkit';
4
+ import { useTranslation, DetailView, createDeenruvForm, getMutation, useMutation } from '@deenruv/react-ui-devkit';
5
5
  import { ShippingMethodDetailView } from "./_components/ShippingMethodDetailView.js";
6
6
  const CreateShippingMethodMutation = getMutation('createShippingMethod');
7
7
  const EditShippingMethodMutation = getMutation('updateShippingMethod');
@@ -13,23 +13,24 @@ export const ShippingMethodsDetailPage = () => {
13
13
  const [remove] = useMutation(DeleteShippingMethodMutation);
14
14
  const { t } = useTranslation('shippingMethods');
15
15
  const onSubmitHandler = useCallback((data) => {
16
- if (!data.code?.validatedValue) {
16
+ if (!data.code) {
17
17
  throw new Error('Name is required.');
18
18
  }
19
+ const checker = data.checker;
19
20
  const inputData = {
20
- code: data.code?.validatedValue,
21
- calculator: data.calculator?.validatedValue,
22
- fulfillmentHandler: data.fulfillmentHandler?.validatedValue,
23
- translations: data.translations.validatedValue,
24
- checker: data.checker?.validatedValue,
25
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
21
+ code: data.code,
22
+ calculator: data.calculator,
23
+ fulfillmentHandler: data.fulfillmentHandler,
24
+ translations: data.translations,
25
+ checker,
26
+ ...(data.customFields ? { customFields: data.customFields } : {}),
26
27
  };
27
28
  if (id) {
28
29
  return update({
29
30
  input: {
30
31
  id,
31
32
  ...inputData,
32
- checker: data.checker?.validatedValue?.code !== '' ? data.checker?.validatedValue : undefined,
33
+ checker: checker?.code !== '' ? checker : undefined,
33
34
  },
34
35
  });
35
36
  }
@@ -76,7 +77,6 @@ export const ShippingMethodsDetailPage = () => {
76
77
  const hasCode = !!v?.code;
77
78
  const hasInvalidArguments = v?.arguments.filter((a) => !a.value || a.value === 'false').length; // args have 'false' value by default
78
79
  const errors = [];
79
- console.log(v?.arguments);
80
80
  if (!hasCode)
81
81
  errors.push(t('validation.checkerCodeRequired'));
82
82
  if (hasInvalidArguments)
@@ -92,8 +92,10 @@ export const ShippingMethodsDetailPage = () => {
92
92
  },
93
93
  translations: {
94
94
  validate: (v) => {
95
- const { name } = v[0];
96
- if (!name)
95
+ if (!Array.isArray(v) || v.length === 0)
96
+ return [t('validation.nameRequired')];
97
+ const hasName = v.some((entry) => entry && entry.name);
98
+ if (!hasName)
97
99
  return [t('validation.nameRequired')];
98
100
  },
99
101
  },
@@ -16,5 +16,5 @@ export const Lines = ({ onLinesChange }) => {
16
16
  priceWithTax: product.priceWithTax.__typename === 'SinglePrice' ? product.priceWithTax.value : product.priceWithTax.min,
17
17
  }));
18
18
  setCurrentProducts(products);
19
- } }), _jsxs(Table, { children: [_jsx(TableHeader, { className: "text-nowrap", children: _jsxs(TableRow, { noHover: true, children: [_jsx(TableHead, { children: t('details.lines.product') }), _jsx(TableHead, { children: t('details.lines.price') }), _jsx(TableHead, { children: t('details.lines.total') })] }) }), _jsx(TableBody, { children: currentProducts.length ? (currentProducts.map((line) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex w-max items-center gap-2", children: [_jsx(ImageWithPreview, { imageClassName: "aspect-square w-10 rounded-md object-cover w-[40px] h-[40px]", src: line.featuredAsset?.preview || line.product?.featuredAsset?.preview }), _jsx("div", { className: "font-semibold", children: line.product.name })] }) }), _jsx(TableCell, { children: line.price }), _jsx(TableCell, { children: line.priceWithTax })] }, line.id)))) : (_jsx(TableCell, { colSpan: 8, children: _jsx("div", { className: "mt-4 flex items-center justify-center", children: _jsx("span", { children: t('details.lines.noItems') }) }) })) })] })] }));
19
+ } }), _jsxs(Table, { children: [_jsx(TableHeader, { className: "text-nowrap", children: _jsxs(TableRow, { noHover: true, children: [_jsx(TableHead, { children: t('details.lines.product') }), _jsx(TableHead, { children: t('details.lines.price') }), _jsx(TableHead, { children: t('details.lines.total') })] }) }), _jsx(TableBody, { children: currentProducts.length ? (currentProducts.map((line) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex w-max items-center gap-2", children: [_jsx(ImageWithPreview, { imageClassName: "aspect-square w-10 rounded-md object-cover w-[40px] h-[40px]", src: line.featuredAsset?.preview || line.product?.featuredAsset?.preview }), _jsx("div", { className: "font-semibold", children: line.product.name })] }) }), _jsx(TableCell, { children: line.price }), _jsx(TableCell, { children: line.priceWithTax })] }, line.id)))) : (_jsx(TableRow, { noHover: true, children: _jsx(TableCell, { colSpan: 3, children: _jsx("div", { className: "mt-4 flex items-center justify-center", children: _jsx("span", { children: t('details.lines.noItems') }) }) }) })) })] })] }));
20
20
  };
@@ -15,7 +15,7 @@ const SHIPPING_METHOD_FORM_KEYS = [
15
15
  ];
16
16
  export const ShippingMethodDetailView = () => {
17
17
  const { form, entity, fetchEntity, id } = useDetailView('shippingMethods-detail-view', ...SHIPPING_METHOD_FORM_KEYS);
18
- const { base: { setField, state }, } = form;
18
+ const { base } = form;
19
19
  const { t } = useTranslation('shippingMethods');
20
20
  const [fulfillmentHandlersOptions, setFulfillmentHandlersOptions] = useState();
21
21
  const { translationsLanguage: currentTranslationLng } = useSettings();
@@ -24,17 +24,17 @@ export const ShippingMethodDetailView = () => {
24
24
  const res = await fetchEntity();
25
25
  if (!res)
26
26
  return;
27
- setField('code', res.code);
28
- setField('translations', res.translations);
29
- setField('checker', {
27
+ base.setField('code', res.code);
28
+ base.setField('translations', res.translations);
29
+ base.setField('checker', {
30
30
  arguments: res.checker?.args || [],
31
31
  code: res.checker?.code || '',
32
32
  });
33
- setField('calculator', {
33
+ base.setField('calculator', {
34
34
  arguments: res.calculator?.args || [],
35
35
  code: res.calculator?.code || '',
36
36
  });
37
- setField('fulfillmentHandler', res.fulfillmentHandlerCode);
37
+ base.setField('fulfillmentHandler', res.fulfillmentHandlerCode);
38
38
  })();
39
39
  }, []);
40
40
  const fetchFulfillmentHandlers = useCallback(async () => {
@@ -49,19 +49,32 @@ export const ShippingMethodDetailView = () => {
49
49
  useEffect(() => {
50
50
  fetchFulfillmentHandlers();
51
51
  }, [id, fetchFulfillmentHandlers]);
52
- const translations = state?.translations?.value || [];
52
+ const translations = base.watch('translations') || [];
53
53
  const currentTranslationValue = translations.find((v) => v.languageCode === currentTranslationLng);
54
54
  const setTranslationField = useCallback((field, e) => {
55
- setField('translations', setInArrayBy(translations, (t) => t.languageCode !== currentTranslationLng, {
55
+ // Merge with existing translation to preserve other fields (name, description, etc.)
56
+ const baseTranslation = currentTranslationValue ?? {
57
+ languageCode: currentTranslationLng,
58
+ name: '',
59
+ description: '',
60
+ };
61
+ base.setField('translations', setInArrayBy(translations, (t) => t.languageCode === currentTranslationLng, {
62
+ ...baseTranslation,
56
63
  [field]: e,
57
64
  languageCode: currentTranslationLng,
58
65
  }));
59
- }, [currentTranslationLng, translations]);
60
- return (_jsx("main", { className: "my-4", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-wrap items-start gap-4 p-0 pt-4", children: [_jsxs("div", { className: "flex w-full flex-wrap items-start gap-4 p-0 pt-4 xl:flex-nowrap", children: [_jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.name'), value: currentTranslationValue?.name ?? undefined, onChange: (e) => setTranslationField('name', e.target.value), errors: state.translations?.errors, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.code'), value: state.code?.value ?? undefined, onChange: (e) => setField('code', e.target.value), errors: state.code?.errors, required: true }) })] }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: currentTranslationValue?.description ?? undefined, onContentChanged: (e) => setTranslationField('description', e) })] }), _jsx("div", { className: "flex basis-full", children: _jsx(SimpleSelect, { label: t('details.basic.fulfillmentHandler'), value: state.fulfillmentHandler?.value ?? undefined, onValueChange: (e) => setField('fulfillmentHandler', e), options: fulfillmentHandlersOptions, errors: state.fulfillmentHandler?.errors }) })] }) }), _jsx(DetailViewMarker, { position: 'shippingMethods-detail-view' }), _jsx(EntityCustomFields, { entityName: "shippingMethod", id: id, hideButton: true, onChange: (customFields, translations) => {
61
- setField('customFields', customFields);
66
+ }, [currentTranslationLng, translations, currentTranslationValue]);
67
+ return (_jsx("main", { className: "my-4", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-wrap items-start gap-4 p-0 pt-4", children: [_jsxs("div", { className: "flex w-full flex-wrap items-start gap-4 p-0 pt-4 xl:flex-nowrap", children: [_jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.name'), value: currentTranslationValue?.name ?? '', onChange: (e) => setTranslationField('name', e.target.value), errors: base.formState.errors?.translations?.message
68
+ ? [base.formState.errors.translations.message]
69
+ : undefined, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.code'), value: base.watch('code') ?? '', onChange: (e) => base.setField('code', e.target.value), errors: base.formState.errors?.code?.message ? [base.formState.errors.code.message] : undefined, required: true }) })] }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: currentTranslationValue?.description ?? '', onContentChanged: (e) => setTranslationField('description', e) })] }), _jsx("div", { className: "flex basis-full", children: _jsx(SimpleSelect, { label: t('details.basic.fulfillmentHandler'), value: base.watch('fulfillmentHandler') ?? '', onValueChange: (e) => base.setField('fulfillmentHandler', e), options: fulfillmentHandlersOptions, errors: base.formState.errors?.fulfillmentHandler?.message
70
+ ? [base.formState.errors.fulfillmentHandler.message]
71
+ : undefined }) })] }) }), _jsx(DetailViewMarker, { position: 'shippingMethods-detail-view' }), _jsx(EntityCustomFields, { entityName: "shippingMethod", id: id, hideButton: true, onChange: (customFields, translations) => {
72
+ base.setField('customFields', customFields);
62
73
  if (translations)
63
- setField('translations', translations);
74
+ base.setField('translations', translations);
64
75
  }, initialValues: entity && 'customFields' in entity
65
76
  ? { customFields: entity.customFields, translations: entity.translations }
66
- : { customFields: {} } }), _jsx(CheckerCard, { currentCheckerValue: state.checker?.value ?? undefined, onCheckerValueChange: (checker) => checker && setField('checker', checker), errors: state.checker?.errors }), _jsx(CalculatorCard, { currentCalculatorValue: state.calculator?.value ?? undefined, onCalculatorValueChange: (calculator) => calculator && setField('calculator', calculator), errors: state.calculator?.errors }), _jsx(TestCard, { calculator: state.calculator?.value ?? undefined, checker: state.checker?.value ?? undefined })] }) }));
77
+ : { customFields: {} } }), _jsx(CheckerCard, { currentCheckerValue: base.watch('checker') ?? undefined, onCheckerValueChange: (checker) => checker && base.setField('checker', checker), errors: base.formState.errors?.checker?.message ? [base.formState.errors.checker.message] : undefined }), _jsx(CalculatorCard, { currentCalculatorValue: base.watch('calculator') ?? undefined, onCalculatorValueChange: (calculator) => calculator && base.setField('calculator', calculator), errors: base.formState.errors?.calculator?.message
78
+ ? [base.formState.errors.calculator.message]
79
+ : undefined }), _jsx(TestCard, { calculator: base.watch('calculator') ?? undefined, checker: base.watch('checker') ?? undefined })] }) }));
67
80
  };
@@ -1,15 +1,30 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, Input, Separator, useServer, apiClient, CustomCard, CardIcons, useGFFLP, SimpleSelect, priceFormatter, useTranslation, } from '@deenruv/react-ui-devkit';
3
- import { useCallback, useEffect, useState } from 'react';
2
+ import { Button, Input, Separator, useServer, apiClient, CustomCard, CardIcons, useDeenruvForm, z, SimpleSelect, priceFormatter, useTranslation, } from '@deenruv/react-ui-devkit';
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
4
  import { CircleCheck, CircleX } from 'lucide-react';
5
5
  import { Lines } from "./Lines";
6
+ const testShippingSchema = z.object({
7
+ shippingAddress: z
8
+ .object({
9
+ countryCode: z.string().default(''),
10
+ city: z.string().default(''),
11
+ streetLine1: z.string().default('test'),
12
+ postalCode: z.string().default(''),
13
+ province: z.string().default(''),
14
+ })
15
+ .default({ countryCode: '', city: '', streetLine1: 'test', postalCode: '', province: '' }),
16
+ calculator: z.any().optional(),
17
+ checker: z.any().optional(),
18
+ lines: z.array(z.any()).optional(),
19
+ });
6
20
  export const TestCard = ({ calculator, checker }) => {
7
21
  const { t } = useTranslation('shippingMethods');
8
22
  const [testResult, setTestResult] = useState();
9
23
  const { countries } = useServer();
10
- const { state, setField } = useGFFLP('TestShippingMethodInput', 'shippingAddress', 'calculator', 'checker', 'lines')({
11
- shippingAddress: {
12
- initialValue: {
24
+ const form = useDeenruvForm({
25
+ schema: testShippingSchema,
26
+ defaultValues: {
27
+ shippingAddress: {
13
28
  countryCode: '',
14
29
  city: '',
15
30
  streetLine1: 'test',
@@ -18,28 +33,54 @@ export const TestCard = ({ calculator, checker }) => {
18
33
  },
19
34
  },
20
35
  });
36
+ const shippingAddress = form.watch('shippingAddress');
37
+ const calculatorValue = form.watch('calculator');
38
+ const checkerValue = form.watch('checker');
39
+ const lines = form.watch('lines');
40
+ // Sync calculator/checker props into local form only when the serialized
41
+ // value actually changes. Props arrive from parent's watch() which
42
+ // returns new object refs on every render — the ref-based comparison
43
+ // prevents an infinite setValue → rerender → setValue loop.
44
+ // `form.setField` is now referentially stable (useCallback in useDeenruvForm),
45
+ // so it won't re-trigger these effects on its own.
46
+ const prevCalculatorRef = useRef(undefined);
47
+ const prevCheckerRef = useRef(undefined);
21
48
  useEffect(() => {
22
- if (calculator)
23
- setField('calculator', calculator);
24
- if (checker)
25
- setField('checker', checker);
26
- }, [calculator, checker, setField]);
49
+ const serialized = calculator ? JSON.stringify(calculator) : undefined;
50
+ if (serialized && serialized !== prevCalculatorRef.current) {
51
+ prevCalculatorRef.current = serialized;
52
+ form.setField('calculator', calculator);
53
+ }
54
+ }, [calculator, form.setField]);
55
+ useEffect(() => {
56
+ const serialized = checker ? JSON.stringify(checker) : undefined;
57
+ if (serialized && serialized !== prevCheckerRef.current) {
58
+ prevCheckerRef.current = serialized;
59
+ form.setField('checker', checker);
60
+ }
61
+ }, [checker, form.setField]);
62
+ // Read the current address via getValues inside the callback to avoid
63
+ // stale-closure issues without adding `shippingAddress` (which changes
64
+ // on every keystroke) to the dependency array.
27
65
  const setAddressField = useCallback((addressField, e) => {
28
- setField('shippingAddress', {
29
- ...state.shippingAddress.value,
66
+ const current = form.getValues('shippingAddress');
67
+ form.setField('shippingAddress', {
68
+ ...current,
30
69
  [addressField]: e,
31
70
  });
32
- }, [state.shippingAddress]);
71
+ }, [form.getValues, form.setField]);
33
72
  const testShippingMethod = useCallback(async () => {
34
- if (state.calculator && state.checker && state.shippingAddress && state.lines?.validatedValue) {
73
+ const currentValues = form.getValues();
74
+ const { calculator: calc, checker: chk, shippingAddress: addr, lines: ln } = currentValues;
75
+ if (calc && chk && addr && ln) {
35
76
  const resp = await apiClient('query')({
36
77
  testShippingMethod: [
37
78
  {
38
79
  input: {
39
- calculator: state.calculator.validatedValue,
40
- checker: state.checker.validatedValue,
41
- lines: state.lines.validatedValue,
42
- shippingAddress: state.shippingAddress.validatedValue,
80
+ calculator: calc,
81
+ checker: chk,
82
+ lines: ln,
83
+ shippingAddress: addr,
43
84
  },
44
85
  },
45
86
  {
@@ -54,9 +95,14 @@ export const TestCard = ({ calculator, checker }) => {
54
95
  });
55
96
  setTestResult(resp.testShippingMethod);
56
97
  }
57
- }, [state]);
58
- return (_jsx(CustomCard, { title: t('details.test.title'), icon: _jsx(CardIcons.shipping, {}), color: "cyan", bottomRight: _jsx(Button, { className: "w-48", onClick: testShippingMethod, children: t('details.test.button') }), children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap gap-3", children: [_jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.city'), value: state.shippingAddress?.value.city ?? undefined, onChange: (e) => setAddressField('city', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.province'), value: state.shippingAddress?.value.province ?? undefined, onChange: (e) => setAddressField('province', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.postalCode'), value: state.shippingAddress?.value.postalCode ?? undefined, onChange: (e) => setAddressField('postalCode', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(SimpleSelect, { label: t('details.test.country'), value: state.shippingAddress?.value.countryCode, onValueChange: (e) => setAddressField('countryCode', e), options: countries.map((c) => ({
98
+ }, [form.getValues]);
99
+ // Stable callback for Lines component avoids identity churn that would
100
+ // cause Lines' useEffect(onLinesChange) to re-fire every render.
101
+ const handleLinesChange = useCallback((e) => {
102
+ form.setField('lines', e);
103
+ }, [form.setField]);
104
+ return (_jsx(CustomCard, { title: t('details.test.title'), icon: _jsx(CardIcons.shipping, {}), color: "cyan", bottomRight: _jsx(Button, { className: "w-48", onClick: testShippingMethod, children: t('details.test.button') }), children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap gap-3", children: [_jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.city'), value: shippingAddress?.city ?? undefined, onChange: (e) => setAddressField('city', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.province'), value: shippingAddress?.province ?? undefined, onChange: (e) => setAddressField('province', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.test.postalCode'), value: shippingAddress?.postalCode ?? undefined, onChange: (e) => setAddressField('postalCode', e.target.value), required: true }) }), _jsx("div", { className: "flex flex-1 basis-full md:basis-1/3", children: _jsx(SimpleSelect, { label: t('details.test.country'), value: shippingAddress?.countryCode, onValueChange: (e) => setAddressField('countryCode', e), options: countries.map((c) => ({
59
105
  label: c.name,
60
106
  value: c.code,
61
- })) }) })] }), _jsx(Separator, {}), _jsx(Lines, { onLinesChange: (e) => setField('lines', e) }), testResult && (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("div", { className: "flex gap-3", children: testResult.eligible ? (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { color: "green" }), t('details.test.eligible')] })) : (_jsxs(_Fragment, { children: [_jsx(CircleX, { color: "red" }), t('details.test.notEligible')] })) }), _jsxs("div", { children: [_jsxs("span", { className: "font-semibold", children: [t('details.lines.price'), ":"] }), ' ', priceFormatter(testResult.quote?.price)] }), _jsxs("div", { children: [_jsxs("span", { className: "font-semibold", children: [t('details.lines.total'), ":"] }), ' ', priceFormatter(testResult.quote?.priceWithTax)] })] }))] }) }));
107
+ })) }) })] }), _jsx(Separator, {}), _jsx(Lines, { onLinesChange: handleLinesChange }), testResult && (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("div", { className: "flex gap-3", children: testResult.eligible ? (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { color: "green" }), t('details.test.eligible')] })) : (_jsxs(_Fragment, { children: [_jsx(CircleX, { color: "red" }), t('details.test.notEligible')] })) }), _jsxs("div", { children: [_jsxs("span", { className: "font-semibold", children: [t('details.lines.price'), ":"] }), ' ', priceFormatter(testResult.quote?.price)] }), _jsxs("div", { children: [_jsxs("span", { className: "font-semibold", children: [t('details.lines.total'), ":"] }), ' ', priceFormatter(testResult.quote?.priceWithTax)] })] }))] }) }));
62
108
  };
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useTranslation, Badge, Button, CardIcons, cn, CustomCard, Skeleton, useServer, } from '@deenruv/react-ui-devkit';
3
+ import { useShallow } from 'zustand/react/shallow';
3
4
  import { RefreshCw, AlertCircle, CheckCircle, XCircle } from 'lucide-react';
4
5
  const getStatusBadge = (status) => {
5
6
  const statusLower = status.toLowerCase();
@@ -15,7 +16,7 @@ const getStatusBadge = (status) => {
15
16
  };
16
17
  export const Health = () => {
17
18
  const { t } = useTranslation('system');
18
- const { data, lastUpdated, loading } = useServer((state) => state.status);
19
+ const { data, lastUpdated, loading } = useServer(useShallow((state) => state.status));
19
20
  const fetchStatus = useServer((state) => state.fetchStatus);
20
21
  return (_jsx(CustomCard, { title: t('health.title'), ...(lastUpdated && { description: t('health.updated') + '' + lastUpdated.toLocaleTimeString() }), color: data.status ? (data.status === 'up' ? 'green' : 'red') : 'gray', icon: _jsx(CardIcons.action, {}), upperRight: _jsxs(Button, { variant: "outline", size: "sm", onClick: fetchStatus, disabled: loading, className: "h-9", children: [_jsx(RefreshCw, { className: cn('mr-2 h-4 w-4', loading && 'animate-spin') }), loading ? t('health.refreshing') : t('health.refresh')] }), children: loading && !data.status ? (_jsxs("div", { className: "space-y-4", children: [_jsx(Skeleton, { className: "h-6 w-32" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-5 w-full" }), _jsx(Skeleton, { className: "h-5 w-full" }), _jsx(Skeleton, { className: "h-5 w-3/4" })] })] })) : data.status ? (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h3", { className: "text-base font-medium", children: t('health.status') }), getStatusBadge(data.status)] }), _jsxs("div", { children: [_jsx("h3", { className: "mb-3 text-base font-medium", children: t('health.details') }), _jsx("div", { className: "divide-y rounded-md border", children: Object.entries(data.details).map(([key, detail], index) => (_jsxs("div", { className: cn('flex items-center justify-between px-4 py-3', index % 2 === 0 ? 'bg-muted/20' : 'bg-background'), children: [_jsx("span", { className: "text-sm font-medium", children: key }), getStatusBadge(detail.status)] }, key))) })] })] })) : (_jsxs("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [_jsx(AlertCircle, { className: "mb-3 size-10 text-muted-foreground" }), _jsx("h3", { className: "text-lg font-medium", children: t('health.error.title') }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t('health.error.description') }), _jsx(Button, { variant: "outline", size: "sm", onClick: fetchStatus, className: "mt-4", children: t('health.error.button') })] })) }));
21
22
  };
@@ -153,9 +153,7 @@ export const Jobs = () => {
153
153
  accessorKey: 'jobData',
154
154
  header: () => _jsx(TableLabel, { children: t('jobs.table.jobData') }),
155
155
  cell: ({ row }) => {
156
- return JsonPopup({
157
- data: row.original.data,
158
- });
156
+ return _jsx(JsonPopup, { data: row.original.data });
159
157
  },
160
158
  },
161
159
  {
@@ -170,9 +168,7 @@ export const Jobs = () => {
170
168
  accessorKey: 'jobResult',
171
169
  header: () => _jsx(TableLabel, { children: t('jobs.table.jobResult') }),
172
170
  cell: ({ row }) => {
173
- return JobResultPopover({
174
- result: row.original.result,
175
- });
171
+ return _jsx(JobResultPopover, { result: row.original.result });
176
172
  },
177
173
  },
178
174
  {
@@ -35,13 +35,13 @@ export const StockLocationsDetailPage = () => {
35
35
  const [remove] = useMutation(DeleteStockLocationMutation);
36
36
  const { nameValidator } = useValidators();
37
37
  const onSubmitHandler = useCallback((data) => {
38
- if (!data.name?.validatedValue) {
38
+ if (!data.name) {
39
39
  throw new Error('Name is required.');
40
40
  }
41
41
  const inputData = {
42
- name: data.name.validatedValue,
43
- description: data.description?.validatedValue,
44
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
42
+ name: data.name,
43
+ description: data.description,
44
+ ...(data.customFields ? { customFields: data.customFields } : {}),
45
45
  };
46
46
  if (id) {
47
47
  return update({ input: { id, ...inputData } });
@@ -6,17 +6,17 @@ export const StockLocationDetailView = () => {
6
6
  const contentLng = useSettings((p) => p.translationsLanguage);
7
7
  const { t } = useTranslation('stockLocations');
8
8
  const { form, entity, fetchEntity, id } = useDetailView('stockLocations-detail-view', ...STOCK_LOCATION_FORM_KEYS);
9
- const { base: { setField, state }, } = form;
9
+ const { base } = form;
10
10
  useEffect(() => {
11
11
  (async () => {
12
12
  const res = await fetchEntity();
13
13
  if (!res)
14
14
  return;
15
- setField('name', res.name);
16
- setField('description', res['description']);
15
+ base.setField('name', res.name);
16
+ base.setField('description', res['description']);
17
17
  })();
18
18
  }, [contentLng]);
19
- return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(Input, { label: t('details.basic.name'), value: state.name?.value, onChange: (e) => setField('name', e.target.value), errors: state.name?.errors, required: true }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: state.description?.value ?? undefined, onContentChanged: (e) => setField('description', e) })] })] }) }), _jsx(DetailViewMarker, { position: 'stockLocations-detail-view' }), _jsx(EntityCustomFields, { entityName: "stockLocation", id: id, hideButton: true, onChange: (customFields) => {
20
- setField('customFields', customFields);
19
+ return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(Input, { label: t('details.basic.name'), value: base.watch('name'), onChange: (e) => base.setField('name', e.target.value), errors: base.formState.errors?.name?.message ? [base.formState.errors.name.message] : undefined, required: true }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: base.watch('description') ?? undefined, onContentChanged: (e) => base.setField('description', e) })] })] }) }), _jsx(DetailViewMarker, { position: 'stockLocations-detail-view' }), _jsx(EntityCustomFields, { entityName: "stockLocation", id: id, hideButton: true, onChange: (customFields) => {
20
+ base.setField('customFields', customFields);
21
21
  }, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} } })] }) }));
22
22
  };
@@ -56,13 +56,13 @@ export const TaxCategoriesDetailPage = () => {
56
56
  },
57
57
  },
58
58
  onSubmitted: (data) => {
59
- if (!data.name?.validatedValue) {
59
+ if (!data.name) {
60
60
  throw new Error('Name is required.');
61
61
  }
62
62
  const inputData = {
63
- name: data.name.validatedValue,
64
- isDefault: data.isDefault?.validatedValue,
65
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
63
+ name: data.name,
64
+ isDefault: data.isDefault,
65
+ ...(data.customFields ? { customFields: data.customFields } : {}),
66
66
  };
67
67
  return id
68
68
  ? update({
@@ -6,19 +6,19 @@ export const TaxCategoryDetailView = () => {
6
6
  const contentLng = useSettings((p) => p.translationsLanguage);
7
7
  const { id, form, entity, fetchEntity } = useDetailView('taxCategories-detail-view', ...TAX_CATEGORY_FORM_KEYS);
8
8
  const { t } = useTranslation('taxCategories');
9
- const { base: { setField, state }, } = form;
9
+ const { base } = form;
10
10
  useEffect(() => {
11
11
  (async () => {
12
12
  const res = await fetchEntity();
13
13
  if (!res)
14
14
  return;
15
- setField('name', res.name);
16
- setField('isDefault', res['isDefault']);
15
+ base.setField('name', res.name);
16
+ base.setField('isDefault', res['isDefault']);
17
17
  })();
18
18
  }, [contentLng]);
19
- return (_jsx("div", { children: _jsxs("div", { className: "flex w-full flex-col gap-4", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: state.name?.value, required: true, onChange: (e) => {
20
- setField('name', e.target.value);
21
- }, errors: state.name?.errors }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/2", children: [_jsx(Switch, { checked: state.isDefault?.value ?? undefined, onCheckedChange: (e) => setField('isDefault', e) }), _jsx(Label, { children: t('details.basic.isDefault') })] })] }) }), _jsx(DetailViewMarker, { position: 'taxCategories-detail-view' }), _jsx(EntityCustomFields, { entityName: "taxCategory", id: id, hideButton: true, onChange: (customFields) => {
22
- setField('customFields', customFields);
19
+ return (_jsx("div", { children: _jsxs("div", { className: "flex w-full flex-col gap-4", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: base.watch('name'), required: true, onChange: (e) => {
20
+ base.setField('name', e.target.value);
21
+ }, errors: base.formState.errors?.name?.message ? [base.formState.errors.name.message] : undefined }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/2", children: [_jsx(Switch, { checked: base.watch('isDefault') ?? undefined, onCheckedChange: (e) => base.setField('isDefault', e) }), _jsx(Label, { children: t('details.basic.isDefault') })] })] }) }), _jsx(DetailViewMarker, { position: 'taxCategories-detail-view' }), _jsx(EntityCustomFields, { entityName: "taxCategory", id: id, hideButton: true, onChange: (customFields) => {
22
+ base.setField('customFields', customFields);
23
23
  }, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} } })] }) }));
24
24
  };
@@ -14,17 +14,17 @@ export const TaxRatesDetailPage = () => {
14
14
  const { t } = useTranslation('taxRates');
15
15
  const { nameValidator, stringValidator, numberValidator } = useValidators();
16
16
  const onSubmitHandler = useCallback((data) => {
17
- if (!data.name?.validatedValue) {
17
+ if (!data.name) {
18
18
  throw new Error('Name is required.');
19
19
  }
20
20
  const inputData = {
21
- name: data.name.validatedValue,
22
- enabled: data.enabled.value,
23
- categoryId: data.categoryId.validatedValue,
24
- value: data.value?.validatedValue || data.value?.initialValue,
25
- zoneId: data.zoneId.validatedValue,
26
- customerGroupId: data.customerGroupId?.validatedValue,
27
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
21
+ name: data.name,
22
+ enabled: (data.enabled ?? true),
23
+ categoryId: data.categoryId,
24
+ value: data.value,
25
+ zoneId: data.zoneId,
26
+ customerGroupId: data.customerGroupId,
27
+ ...(data.customFields ? { customFields: data.customFields } : {}),
28
28
  };
29
29
  if (id) {
30
30
  return update({ input: { id, ...inputData } });
@@ -16,7 +16,7 @@ export const TaxRateDetailView = () => {
16
16
  const [taxCategoriesOptions, setTaxCategoriesOptions] = useState([]);
17
17
  const [zonesOptions, setZonesOptions] = useState([]);
18
18
  const { form, entity, fetchEntity, id } = useDetailView('taxRates-detail-view', ...TAX_RATES_FORM_KEYS);
19
- const { base: { setField, state }, } = form;
19
+ const { base } = form;
20
20
  const fetchItemsForOptions = useCallback(async () => {
21
21
  const response = await apiClient('query')({
22
22
  taxCategories: [
@@ -51,14 +51,18 @@ export const TaxRateDetailView = () => {
51
51
  console.log('ENT', entity);
52
52
  if (!entity)
53
53
  return;
54
- setField('name', entity.name);
55
- setField('enabled', entity.enabled);
56
- setField('categoryId', entity.category.id);
57
- setField('customerGroupId', entity.customerGroup?.id);
58
- setField('zoneId', entity.zone.id);
59
- setField('value', entity.value);
54
+ base.setField('name', entity.name);
55
+ base.setField('enabled', entity.enabled);
56
+ base.setField('categoryId', entity.category.id);
57
+ base.setField('customerGroupId', entity.customerGroup?.id);
58
+ base.setField('zoneId', entity.zone.id);
59
+ base.setField('value', entity.value);
60
60
  }, [entity]);
61
- return (_jsx("main", { className: "my-4 min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-col gap-4 p-0 pt-4", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: state.name?.value ?? undefined, onChange: (e) => setField('name', e.target.value), errors: state.name?.errors, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { type: "number", label: t('details.basic.value'), value: state.value?.value ?? undefined, onChange: (e) => setField('value', +e.target.value), errors: state.value?.errors, endAdornment: '%', min: 0, max: 100, required: true }) })] }), _jsxs("div", { className: "flex items-end gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(SimpleSelect, { label: t('details.basic.taxCategory'), value: state.categoryId?.value ?? undefined, onValueChange: (e) => setField('categoryId', e), options: taxCategoriesOptions, errors: state.categoryId?.errors, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(SimpleSelect, { label: t('details.basic.zone'), value: state.zoneId?.value ?? undefined, onValueChange: (e) => setField('zoneId', e), options: zonesOptions, errors: state.zoneId?.errors, required: true }) })] }), _jsx("div", { className: "flex items-end gap-4", children: _jsxs("div", { className: "mb-2 flex basis-full items-center gap-3 md:basis-1/2", children: [_jsx(Switch, { checked: state.enabled?.value ?? undefined, onCheckedChange: (e) => setField('enabled', e) }), _jsx(Label, { children: t('details.basic.enabled') })] }) })] }) }), _jsx(DetailViewMarker, { position: 'taxRates-detail-view' }), _jsx(EntityCustomFields, { entityName: "taxRate", id: id, onChange: (customFields) => {
62
- setField('customFields', customFields);
61
+ return (_jsx("main", { className: "my-4 min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex flex-col gap-4 p-0 pt-4", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: base.watch('name') ?? undefined, onChange: (e) => base.setField('name', e.target.value), errors: base.formState.errors?.name?.message ? [base.formState.errors.name.message] : undefined, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { type: "number", label: t('details.basic.value'), value: base.watch('value') ?? undefined, onChange: (e) => base.setField('value', +e.target.value), errors: base.formState.errors?.value?.message ? [base.formState.errors.value.message] : undefined, endAdornment: '%', min: 0, max: 100, required: true }) })] }), _jsxs("div", { className: "flex items-end gap-4", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(SimpleSelect, { label: t('details.basic.taxCategory'), value: base.watch('categoryId') ?? undefined, onValueChange: (e) => base.setField('categoryId', e), options: taxCategoriesOptions, errors: base.formState.errors?.categoryId?.message
62
+ ? [base.formState.errors.categoryId.message]
63
+ : undefined, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(SimpleSelect, { label: t('details.basic.zone'), value: base.watch('zoneId') ?? undefined, onValueChange: (e) => base.setField('zoneId', e), options: zonesOptions, errors: base.formState.errors?.zoneId?.message
64
+ ? [base.formState.errors.zoneId.message]
65
+ : undefined, required: true }) })] }), _jsx("div", { className: "flex items-end gap-4", children: _jsxs("div", { className: "mb-2 flex basis-full items-center gap-3 md:basis-1/2", children: [_jsx(Switch, { checked: base.watch('enabled') ?? undefined, onCheckedChange: (e) => base.setField('enabled', e) }), _jsx(Label, { children: t('details.basic.enabled') })] }) })] }) }), _jsx(DetailViewMarker, { position: 'taxRates-detail-view' }), _jsx(EntityCustomFields, { entityName: "taxRate", id: id, onChange: (customFields) => {
66
+ base.setField('customFields', customFields);
63
67
  }, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} }, hideButton: true })] }) }));
64
68
  };
@@ -43,15 +43,15 @@ export const ZonesDetailPage = () => {
43
43
  });
44
44
  }, [id, t]);
45
45
  const onSubmitHandler = useCallback((data, additionalData) => {
46
- if (!data.name?.validatedValue) {
46
+ if (!data.name) {
47
47
  throw new Error('Name is required.');
48
48
  }
49
49
  const { membersIdsToRemove = [], membersIdsToAdd = [] } = additionalData && 'membersIdsToRemove' in additionalData && 'membersIdsToAdd' in additionalData
50
50
  ? additionalData
51
51
  : {};
52
52
  const inputData = {
53
- name: data.name.validatedValue,
54
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
53
+ name: data.name,
54
+ ...(data.customFields ? { customFields: data.customFields } : {}),
55
55
  };
56
56
  if (id) {
57
57
  return Promise.all([
@@ -60,7 +60,7 @@ export const ZonesDetailPage = () => {
60
60
  ]).then(([res]) => res);
61
61
  }
62
62
  else {
63
- return create({ input: { ...inputData, memberIds: data.memberIds?.validatedValue } });
63
+ return create({ input: { ...inputData, memberIds: data.memberIds } });
64
64
  }
65
65
  }, [id, update, create]);
66
66
  const onDeleteHandler = useCallback(() => {
@@ -4,7 +4,7 @@ import { Input, Label, MultipleSelector, useServer, useDetailView, DetailViewMar
4
4
  const STOCK_LOCATION_FORM_KEYS = ['CreateZoneInput', 'name', 'memberIds', 'customFields'];
5
5
  export const ZoneDetailView = () => {
6
6
  const { form, fetchEntity, entity, setAdditionalData, id } = useDetailView('zones-detail-view', ...STOCK_LOCATION_FORM_KEYS);
7
- const { base: { setField, state }, } = form;
7
+ const { base } = form;
8
8
  const editMode = useMemo(() => !!id, [id]);
9
9
  const { t } = useTranslation('zones');
10
10
  const [countriesOptions, setCountriesOptions] = useState();
@@ -19,12 +19,12 @@ export const ZoneDetailView = () => {
19
19
  const res = await fetchEntity();
20
20
  if (!res)
21
21
  return;
22
- setField('name', res.name);
23
- setField('memberIds', res.members.map((m) => m.id));
22
+ base.setField('name', res.name);
23
+ base.setField('memberIds', res.members.map((m) => m.id));
24
24
  })();
25
25
  }, []);
26
26
  const handleChange = useCallback((options) => {
27
- setField('memberIds', options.map((o) => o.value));
27
+ base.setField('memberIds', options.map((o) => o.value));
28
28
  if (editMode && entity) {
29
29
  const backendMembersIds = entity.members.map((m) => m.id);
30
30
  const optionValues = options.map((o) => o.value);
@@ -39,11 +39,12 @@ export const ZoneDetailView = () => {
39
39
  // if currentState doesn't include BE ids, remove them
40
40
  setMembersIdsToRemove(toRemove);
41
41
  }
42
- }, [editMode, setField, entity]);
43
- return (_jsx("main", { className: "my-4 min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex gap-3", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: state.name?.value, onChange: (e) => setField('name', e.target.value), errors: state.name?.errors, required: true }) }), _jsxs("div", { className: "flex basis-full flex-col md:basis-1/2", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.members') }), _jsx(MultipleSelector, { options: countriesOptions, value: state?.memberIds?.value?.map((id) => ({
42
+ }, [editMode, base.setField, entity]);
43
+ const memberIds = base.watch('memberIds');
44
+ return (_jsx("main", { className: "my-4 min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex gap-3", children: [_jsx("div", { className: "flex basis-full md:basis-1/2", children: _jsx(Input, { label: t('details.basic.name'), value: base.watch('name'), onChange: (e) => base.setField('name', e.target.value), errors: base.formState.errors?.name?.message ? [base.formState.errors.name.message] : undefined, required: true }) }), _jsxs("div", { className: "flex basis-full flex-col md:basis-1/2", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.members') }), _jsx(MultipleSelector, { options: countriesOptions, value: memberIds?.map((id) => ({
44
45
  label: countriesOptions?.find((o) => o.value === id)?.label || id,
45
46
  value: id,
46
47
  })), placeholder: t('details.basic.memberPlaceholder'), onChange: handleChange, hideClearAllButton: true })] })] }) }), _jsx(DetailViewMarker, { position: 'zones-detail-view' }), _jsx(EntityCustomFields, { entityName: "zone", id: id, hideButton: true, onChange: (customFields) => {
47
- setField('customFields', customFields);
48
+ base.setField('customFields', customFields);
48
49
  }, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} } })] }) }));
49
50
  };
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const ADMIN_DASHBOARD_VERSION = '1.0.5';
1
+ export const ADMIN_DASHBOARD_VERSION = '1.0.9';