@axinom/mosaic-ui 0.63.0-rc.5 → 0.63.0-rc.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.63.0-rc.5",
3
+ "version": "0.63.0-rc.6",
4
4
  "description": "UI components for building Axinom Mosaic applications",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -112,5 +112,5 @@
112
112
  "publishConfig": {
113
113
  "access": "public"
114
114
  },
115
- "gitHead": "61dacf2b863f576ca0680aaa3431b5a195686e7e"
115
+ "gitHead": "37f68c4083df80f25b1fd94ec348c5bbf54a639c"
116
116
  }
@@ -23,11 +23,28 @@ export const BulkEditFormFieldsConfigConverter = (
23
23
  const keys = Object.keys(config);
24
24
 
25
25
  const FormFields: React.FC = () => {
26
- const { setFieldValue, setFieldTouched, values } = useFormikContext<Data>();
26
+ const {
27
+ setFieldValue,
28
+ setFieldTouched,
29
+ setErrors,
30
+ errors,
31
+ validateForm,
32
+ values,
33
+ } = useFormikContext<Data>();
27
34
 
28
35
  const onFieldRemoved = (field: string): void => {
29
- setFieldValue(field, undefined); // Clear the field value when removed
30
- setFieldTouched(field, false); // Mark the field as not touched
36
+ setFieldValue(field, undefined, false); // Clear the field value when removed
37
+ setFieldTouched(field, false, false); // Mark the field as not touched
38
+
39
+ if (errors[field]) {
40
+ // If there was an error for this field, clear it
41
+ const newErrors = { ...errors };
42
+ delete newErrors[field];
43
+
44
+ setErrors(newErrors);
45
+
46
+ validateForm();
47
+ }
31
48
  };
32
49
 
33
50
  // Effect to clear empty fields
@@ -41,6 +58,10 @@ export const BulkEditFormFieldsConfigConverter = (
41
58
  });
42
59
  }, [setFieldValue, values]);
43
60
 
61
+ const onFieldAdded = (field: string): void => {
62
+ setFieldTouched(field, true); // Mark the field as touched when added
63
+ };
64
+
44
65
  const fields = useMemo(
45
66
  () =>
46
67
  keys
@@ -66,6 +87,16 @@ export const BulkEditFormFieldsConfigConverter = (
66
87
  name={key}
67
88
  key={key}
68
89
  label={fieldConfig.label}
90
+ validate={(value: unknown) => {
91
+ if (fieldType === 'Array') {
92
+ // Array can be empty, so no validation needed
93
+ return;
94
+ }
95
+ if (value === null || value === undefined || value === '') {
96
+ return 'This field is required';
97
+ }
98
+ }}
99
+ autoFocus={true}
69
100
  as={Component}
70
101
  />
71
102
  );
@@ -75,9 +106,14 @@ export const BulkEditFormFieldsConfigConverter = (
75
106
  );
76
107
 
77
108
  return (
78
- <FieldSelection onFieldRemoved={onFieldRemoved}>{fields}</FieldSelection>
109
+ <FieldSelection
110
+ onFieldRemoved={onFieldRemoved}
111
+ onFieldAdded={onFieldAdded}
112
+ >
113
+ {fields}
114
+ </FieldSelection>
79
115
  );
80
116
  };
81
117
 
82
- return <FormFields />; // Return the FormFields component
118
+ return <FormFields />;
83
119
  };
@@ -111,7 +111,7 @@ export const useBulkEdit = <T extends Data>({
111
111
  : undefined
112
112
  }
113
113
  showSaveHeaderAction={!noItemsSelected}
114
- saveHeaderActionTitle="Apply"
114
+ saveHeaderActionConfig={{ label: 'Apply', icon: IconName.Checkmark }}
115
115
  saveNotificationMessage="Your changes are being applied to the selected items."
116
116
  >
117
117
  {BulkEditContent}
@@ -5,6 +5,7 @@ import { OptionalObjectSchema } from 'yup/lib/object';
5
5
  import { Data } from '../../types/data';
6
6
  import { BulkEditContext } from '../Explorer/BulkEdit/BulkEditContext';
7
7
  import { QuickEditContext } from '../Explorer/QuickEdit/QuickEditContext';
8
+ import { PageHeaderJsActionProps } from '../PageHeader/PageHeaderAction';
8
9
  import { StationMessage } from '../models';
9
10
  import {
10
11
  FormActionData,
@@ -40,10 +41,10 @@ export interface FormStationProps<
40
41
  /** If set to true, the save header action is shown. (default: true) */
41
42
  showSaveHeaderAction?: boolean;
42
43
  /**
43
- * If set, this will override the default title of the save header action.
44
- * This is useful when you want to have a custom title for the save action.
44
+ * Optional configuration for the save header action button.
45
+ * Allows customizing the label and icon.
45
46
  */
46
- saveHeaderActionTitle?: string;
47
+ saveHeaderActionConfig?: Pick<PageHeaderJsActionProps, 'label' | 'icon'>;
47
48
  /**
48
49
  * If set, this will override the default notification message shown
49
50
  * after a successful save.
@@ -101,7 +102,7 @@ export const FormStation = <TValues extends Data, TSubmitResponse = unknown>({
101
102
  className = '',
102
103
  setTabTitle = true,
103
104
  showSaveHeaderAction = true,
104
- saveHeaderActionTitle,
105
+ saveHeaderActionConfig,
105
106
  saveNotificationMessage,
106
107
  }: PropsWithChildren<
107
108
  FormStationProps<TValues, TSubmitResponse>
@@ -149,7 +150,8 @@ export const FormStation = <TValues extends Data, TSubmitResponse = unknown>({
149
150
  className={classes.header}
150
151
  setTabTitle={setTabTitle}
151
152
  showSaveHeaderAction={showSaveHeaderAction}
152
- saveHeaderActionTitle={saveHeaderActionTitle}
153
+ saveHeaderActionConfig={saveHeaderActionConfig}
154
+ setValidationError={setValidationError}
153
155
  />
154
156
  {!bulkEditContext && (
155
157
  <SaveOnNavigate
@@ -10,6 +10,7 @@ import {
10
10
  PageHeaderActionType,
11
11
  PageHeaderProps,
12
12
  } from '../../PageHeader';
13
+ import { PageHeaderJsActionProps } from '../../PageHeader/PageHeaderAction';
13
14
  import { useTitle } from '../helpers/useTitle';
14
15
 
15
16
  /**
@@ -22,7 +23,8 @@ export const FormStationHeader: React.FC<
22
23
  cancelNavigationUrl?: string;
23
24
  setTabTitle?: boolean;
24
25
  showSaveHeaderAction?: boolean;
25
- saveHeaderActionTitle?: string;
26
+ saveHeaderActionConfig?: Pick<PageHeaderJsActionProps, 'label' | 'icon'>;
27
+ setValidationError: () => void;
26
28
  }
27
29
  > = ({
28
30
  titleProperty,
@@ -32,9 +34,14 @@ export const FormStationHeader: React.FC<
32
34
  className,
33
35
  setTabTitle,
34
36
  showSaveHeaderAction,
35
- saveHeaderActionTitle = 'Save',
37
+ saveHeaderActionConfig = {
38
+ label: 'Save',
39
+ icon: IconName.Save,
40
+ },
41
+ setValidationError,
36
42
  }) => {
37
- const { dirty, submitForm, resetForm } = useFormikContext<FormikValues>();
43
+ const { dirty, submitForm, resetForm, isValid } =
44
+ useFormikContext<FormikValues>();
38
45
  const quickEditContext = useContext(QuickEditContext);
39
46
  const bulkEditContext = useContext(BulkEditContext);
40
47
 
@@ -58,14 +65,18 @@ export const FormStationHeader: React.FC<
58
65
 
59
66
  if (showSaveHeaderAction) {
60
67
  actionItems.push({
61
- label: saveHeaderActionTitle,
62
- icon: IconName.Save,
68
+ label: saveHeaderActionConfig.label,
69
+ icon: saveHeaderActionConfig.icon,
63
70
  kind: 'action',
64
71
  actionType: PageHeaderActionType.Context,
65
72
  onClick: async () => {
66
73
  if (quickEditContext?.isQuickEditMode) {
67
74
  quickEditContext.refresh();
68
75
  } else if (bulkEditContext?.isBulkEditMode) {
76
+ if (!isValid) {
77
+ setValidationError();
78
+ return;
79
+ }
69
80
  await submitForm();
70
81
  history.replace(history.location.pathname);
71
82
  } else {
@@ -116,9 +127,12 @@ export const FormStationHeader: React.FC<
116
127
  cancelNavigationUrl,
117
128
  dirty,
118
129
  history,
130
+ isValid,
119
131
  quickEditContext,
120
132
  resetForm,
121
- saveHeaderActionTitle,
133
+ saveHeaderActionConfig.icon,
134
+ saveHeaderActionConfig.label,
135
+ setValidationError,
122
136
  showSaveHeaderAction,
123
137
  submitForm,
124
138
  ]);