@headless-adminapp/fluent 1.1.11 → 1.1.12

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.
@@ -0,0 +1,7 @@
1
+ import { SectionEditableGridControl } from '@headless-adminapp/core/experience/form';
2
+ interface EditableGridControlProps {
3
+ readOnly?: boolean;
4
+ control: SectionEditableGridControl;
5
+ }
6
+ export declare function EditableGridControl({ readOnly, control, }: Readonly<EditableGridControlProps>): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EditableGridControl = EditableGridControl;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const dataform_1 = require("@headless-adminapp/app/dataform");
7
+ const getRecord_1 = require("@headless-adminapp/app/dataform/DataFormProvider/getRecord");
8
+ const saveRecord_1 = require("@headless-adminapp/app/dataform/utils/saveRecord");
9
+ const form_1 = require("@headless-adminapp/app/form");
10
+ const locale_1 = require("@headless-adminapp/app/locale");
11
+ const metadata_1 = require("@headless-adminapp/app/metadata");
12
+ const transport_1 = require("@headless-adminapp/app/transport");
13
+ const icons_1 = require("@headless-adminapp/icons");
14
+ const react_query_1 = require("@tanstack/react-query");
15
+ const react_1 = require("react");
16
+ const react_hook_form_1 = require("react-hook-form");
17
+ const BodyLoading_1 = require("../../components/BodyLoading");
18
+ const TableUi_1 = require("./TableUi");
19
+ function EditableGridControl({ readOnly, control, }) {
20
+ const recordId = (0, dataform_1.useRecordId)();
21
+ const dataService = (0, transport_1.useDataService)();
22
+ const { schemaStore } = (0, metadata_1.useMetadata)();
23
+ const { language, region } = (0, locale_1.useLocale)();
24
+ const formValidationStrings = (0, form_1.useFormValidationStrings)();
25
+ const schema = schemaStore.getSchema(control.logicalName);
26
+ const alias = control.alias ? control.alias : 'items';
27
+ const parentFormInstance = (0, dataform_1.useFormInstance)();
28
+ const localFormInstance = (0, react_hook_form_1.useForm)({
29
+ mode: 'all',
30
+ defaultValues: {
31
+ items: [],
32
+ },
33
+ resolver: (0, dataform_1.editableSubgridFormValidator)({
34
+ alias,
35
+ control,
36
+ schema: schemaStore.getSchema(control.logicalName),
37
+ language,
38
+ region,
39
+ schemaStore,
40
+ strings: formValidationStrings,
41
+ formReadOnly: readOnly,
42
+ }),
43
+ shouldUnregister: false,
44
+ });
45
+ const queryClient = (0, react_query_1.useQueryClient)();
46
+ const { data, isFetching } = (0, react_query_1.useQuery)({
47
+ queryKey: ['editable-grid', recordId, control],
48
+ queryFn: async () => {
49
+ return (0, getRecord_1.getEditableSubgridRecords)({
50
+ control,
51
+ schemaStore,
52
+ dataService,
53
+ recordId,
54
+ });
55
+ },
56
+ enabled: !!recordId && !control.alias,
57
+ });
58
+ const formInstanceRef = (0, react_1.useRef)(localFormInstance);
59
+ formInstanceRef.current = localFormInstance;
60
+ (0, react_1.useEffect)(() => {
61
+ if (!data) {
62
+ return;
63
+ }
64
+ formInstanceRef.current.reset({
65
+ items: data,
66
+ });
67
+ }, [data]);
68
+ const formControl = control.alias
69
+ ? parentFormInstance.control
70
+ : localFormInstance.control;
71
+ const fieldArray = (0, react_hook_form_1.useFieldArray)({
72
+ control: formControl,
73
+ name: alias,
74
+ keyName: '__key',
75
+ shouldUnregister: false,
76
+ });
77
+ const handleAddRow = () => {
78
+ const newItem = {
79
+ $entity: schema.logicalName,
80
+ [schema.idAttribute]: null,
81
+ [control.associatedAttribute]: {
82
+ id: recordId,
83
+ },
84
+ };
85
+ control.controls.forEach((control) => {
86
+ if (typeof control === 'string') {
87
+ newItem[control] = null;
88
+ }
89
+ else {
90
+ newItem[control.attributeName] = null;
91
+ }
92
+ });
93
+ fieldArray.append(newItem);
94
+ };
95
+ const handleSave = async () => {
96
+ await localFormInstance.handleSubmit(async (values) => {
97
+ try {
98
+ await (0, saveRecord_1.saveEditableGridControl)({
99
+ recordId,
100
+ values,
101
+ initialValues: localFormInstance.formState.defaultValues,
102
+ control,
103
+ dataService,
104
+ schemaStore,
105
+ alias,
106
+ });
107
+ await queryClient.invalidateQueries({
108
+ queryKey: ['editable-grid', recordId, control],
109
+ });
110
+ }
111
+ catch (error) {
112
+ console.error(error);
113
+ }
114
+ }, (errors) => {
115
+ console.error(errors);
116
+ })();
117
+ };
118
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
119
+ display: 'flex',
120
+ flexDirection: 'column',
121
+ position: 'relative',
122
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
123
+ display: 'flex',
124
+ paddingInline: 16,
125
+ paddingBlock: 8,
126
+ height: 40,
127
+ alignItems: 'center',
128
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', width: '100%' }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Body1Strong, { children: control.label }), (0, jsx_runtime_1.jsx)("div", { style: { flex: 1 } }), (0, jsx_runtime_1.jsx)("div", { style: { marginRight: -12 }, children: !control.alias && !readOnly && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Save, {}), appearance: "subtle", style: { minWidth: 0 }, disabled: localFormInstance.formState.isSubmitting ||
129
+ !localFormInstance.formState.isValid ||
130
+ !localFormInstance.formState.isDirty, onClick: handleSave, children: "Save" })) })] }) }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }) }), (0, jsx_runtime_1.jsx)("div", { style: { padding: 16, position: 'relative' }, children: (0, jsx_runtime_1.jsx)(TableUi_1.TableUi, { schema: schema, control: control, formControl: formControl, alias: alias, onAddRow: handleAddRow, onRemoveRow: (index) => {
131
+ fieldArray.remove(index);
132
+ }, rows: fieldArray.fields }) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: isFetching || localFormInstance.formState.isSubmitting })] }));
133
+ }
@@ -0,0 +1,15 @@
1
+ import { SectionEditableGridControl } from '@headless-adminapp/core/experience/form';
2
+ import { Schema } from '@headless-adminapp/core/schema';
3
+ import { FC } from 'react';
4
+ import { Control } from 'react-hook-form';
5
+ interface TableUiProps {
6
+ schema: Schema;
7
+ control: SectionEditableGridControl;
8
+ formControl: Control;
9
+ onAddRow?: () => void;
10
+ onRemoveRow?: (index: number) => void;
11
+ rows: Record<'__key', string>[];
12
+ alias: string;
13
+ }
14
+ export declare const TableUi: FC<TableUiProps>;
15
+ export {};
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TableUi = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const icons_1 = require("@headless-adminapp/icons");
7
+ const react_hook_form_1 = require("react-hook-form");
8
+ const SectionControl_1 = require("../../DataForm/SectionControl");
9
+ const StandardControl_1 = require("../StandardControl");
10
+ const useStyles = (0, react_components_1.makeStyles)({
11
+ table: {
12
+ '& tbody tr:hover': {
13
+ backgroundColor: 'transparent',
14
+ },
15
+ '& tr': {
16
+ borderBottom: `${react_components_1.tokens.strokeWidthThin} solid transparent`,
17
+ },
18
+ '& th': {
19
+ fontWeight: react_components_1.tokens.fontWeightMedium,
20
+ paddingInline: react_components_1.tokens.spacingHorizontalXS,
21
+ },
22
+ '& td': {
23
+ paddingInline: react_components_1.tokens.spacingHorizontalXS,
24
+ },
25
+ '& tbody tr:last-child': {
26
+ borderBottom: 'none',
27
+ },
28
+ '& td:first-child': {
29
+ paddingLeft: 0,
30
+ },
31
+ '& th:first-child': {
32
+ paddingLeft: 0,
33
+ },
34
+ '& td:last-child': {
35
+ paddingRight: 0,
36
+ },
37
+ '& th:last-child': {
38
+ paddingRight: 0,
39
+ },
40
+ },
41
+ });
42
+ const TableUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, alias, }) => {
43
+ const styles = useStyles();
44
+ return ((0, jsx_runtime_1.jsxs)(react_components_1.Table, { className: styles.table, children: [(0, jsx_runtime_1.jsxs)("colgroup", { children: [control.controls.map((_, index) => ((0, jsx_runtime_1.jsx)("col", {}, index))), (0, jsx_runtime_1.jsx)("col", { style: { width: 36 } })] }), (0, jsx_runtime_1.jsx)(react_components_1.TableHeader, { children: (0, jsx_runtime_1.jsxs)(react_components_1.TableRow, { children: [control.controls.map((control) => {
45
+ const attributeName = typeof control === 'string' ? control : control.attributeName;
46
+ const attribute = schema.attributes[attributeName];
47
+ if (!attribute) {
48
+ return null;
49
+ }
50
+ return ((0, jsx_runtime_1.jsx)(react_components_1.TableHeaderCell, { children: attribute.label ?? attribute.label }, attributeName));
51
+ }), (0, jsx_runtime_1.jsx)(react_components_1.TableHeaderCell, { children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Add, { size: 16 }), appearance: "subtle", onClick: onAddRow }) })] }) }), (0, jsx_runtime_1.jsx)(react_components_1.TableBody, { children: rows.map((item, index) => ((0, jsx_runtime_1.jsxs)(react_components_1.TableRow, { children: [control.controls.map((control) => {
52
+ const attributeName = typeof control === 'string' ? control : control.attributeName;
53
+ const attribute = schema.attributes[attributeName];
54
+ if (!attribute) {
55
+ return null;
56
+ }
57
+ return ((0, jsx_runtime_1.jsx)(react_components_1.TableCell, { children: (0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { name: `${alias}.${index}.${attributeName}`, control: formControl, render: ({ field, fieldState, formState }) => {
58
+ const isError = (fieldState.isTouched || formState.isSubmitted) &&
59
+ !!fieldState.error?.message;
60
+ return ((0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelHidden: true, labelPosition: "top", isError: isError, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value ?? null, onChange: field.onChange, onBlur: field.onBlur, placeholder: "" }) }));
61
+ } }) }, attributeName));
62
+ }), (0, jsx_runtime_1.jsx)(react_components_1.TableCell, { children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Delete, { size: 16 }), appearance: "subtle", onClick: () => onRemoveRow?.(index) }) })] }, item.__key))) })] }));
63
+ };
64
+ exports.TableUi = TableUi;
@@ -0,0 +1 @@
1
+ export { EditableGridControl } from './EditableGridControl';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EditableGridControl = void 0;
4
+ var EditableGridControl_1 = require("./EditableGridControl");
5
+ Object.defineProperty(exports, "EditableGridControl", { enumerable: true, get: function () { return EditableGridControl_1.EditableGridControl; } });
@@ -16,6 +16,7 @@ const react_hook_form_1 = require("react-hook-form");
16
16
  const componentStore_1 = require("../componentStore");
17
17
  const SectionControl_1 = require("../DataForm/SectionControl");
18
18
  const layout_1 = require("../form/layout");
19
+ const EditableGridControl_1 = require("./EditableGridControl/EditableGridControl");
19
20
  const StandardControl_1 = require("./StandardControl");
20
21
  const SubgridControl_1 = require("./SubgridControl");
21
22
  function SectionContainer({ section }) {
@@ -98,7 +99,13 @@ function SectionContainer({ section }) {
98
99
  } }, control.attributeName) }, control.attributeName));
99
100
  }
100
101
  case 'editablegrid': {
101
- return null;
102
+ const disabled = (0, utils_1.getIsFieldDisabled)({
103
+ isFormReadonly,
104
+ disabledFields: disabledControls,
105
+ attribute: null,
106
+ control,
107
+ });
108
+ return ((0, jsx_runtime_1.jsx)(EditableGridControl_1.EditableGridControl, { readOnly: disabled, control: control }));
102
109
  }
103
110
  case 'quickview':
104
111
  return null;
@@ -5,6 +5,7 @@ interface AttributeControllerProps<TFieldValues extends FieldValues = FieldValue
5
5
  attributeName: FieldPath<TFieldValues>;
6
6
  control: Control<TFieldValues>;
7
7
  readOnly?: boolean;
8
+ labelPosition?: 'left' | 'top';
8
9
  }
9
- export declare function AttributeController<TFieldValues extends FieldValues = FieldValues>({ attribute, attributeName, control, readOnly, }: Readonly<AttributeControllerProps<TFieldValues>>): import("react/jsx-runtime").JSX.Element;
10
+ export declare function AttributeController<TFieldValues extends FieldValues = FieldValues>({ attribute, attributeName, control, readOnly, labelPosition, }: Readonly<AttributeControllerProps<TFieldValues>>): import("react/jsx-runtime").JSX.Element;
10
11
  export {};
@@ -5,13 +5,13 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_hook_form_1 = require("react-hook-form");
6
6
  const SectionControl_1 = require("../DataForm/SectionControl");
7
7
  const StandardControl_1 = require("../PageEntityForm/StandardControl");
8
- function AttributeController({ attribute, attributeName, control, readOnly, }) {
8
+ function AttributeController({ attribute, attributeName, control, readOnly, labelPosition = 'left', }) {
9
9
  return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: attributeName, render: ({ field, fieldState, formState }) => {
10
10
  const isError = (fieldState.isTouched || formState.isSubmitted) &&
11
11
  !!fieldState.error?.message;
12
12
  const errorMessage = fieldState.isTouched || formState.isSubmitted
13
13
  ? fieldState.error?.message
14
14
  : '';
15
- return ((0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelPosition: "left", required: attribute.required, isError: isError, errorMessage: errorMessage, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur, errorMessage: errorMessage, isError: isError, readOnly: readOnly || attribute.readonly }) }));
15
+ return ((0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelPosition: labelPosition, required: attribute.required, isError: isError, errorMessage: errorMessage, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur, errorMessage: errorMessage, isError: isError, readOnly: readOnly || attribute.readonly }) }));
16
16
  } }));
17
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-adminapp/fluent",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -50,5 +50,5 @@
50
50
  "uuid": "11.0.3",
51
51
  "yup": "^1.4.0"
52
52
  },
53
- "gitHead": "e88cae2cc31abaf6852549e3fbc3235eec84cc8c"
53
+ "gitHead": "ead918f1f609c2a260ceae498368ddc2c4980725"
54
54
  }