@headless-adminapp/fluent 1.4.15 → 1.4.16

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.
@@ -12,6 +12,7 @@ const hooks_2 = require("@headless-adminapp/app/hooks");
12
12
  const locale_1 = require("@headless-adminapp/app/locale");
13
13
  const mutable_1 = require("@headless-adminapp/app/mutable");
14
14
  const route_1 = require("@headless-adminapp/app/route");
15
+ const color_1 = require("@headless-adminapp/app/utils/color");
15
16
  const icons_1 = require("@headless-adminapp/icons");
16
17
  const react_1 = require("react");
17
18
  const AppLogo_1 = require("./AppLogo");
@@ -50,7 +51,7 @@ const NavTitle = () => {
50
51
  display: 'flex',
51
52
  alignItems: 'center',
52
53
  cursor: 'pointer',
53
- color: 'white',
54
+ color: 'inherit',
54
55
  }, children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', paddingLeft: 4, paddingRight: 6 }, children: (0, jsx_runtime_1.jsx)(AppLogo_1.AppLogo, { logo: app.logo, title: app.title }) }), (0, jsx_runtime_1.jsx)(react_components_1.Subtitle2, { style: { paddingLeft: 4 }, children: app.title })] }));
55
56
  };
56
57
  const NavActions = () => {
@@ -110,31 +111,47 @@ const NavActions = () => {
110
111
  };
111
112
  const AppDesktopHeader = ({ onNavToggle }) => {
112
113
  const isTablet = (0, hooks_2.useIsTablet)();
114
+ const { appExperience: app } = (0, app_1.useAppContext)();
115
+ const background = app.headerColor ?? react_components_1.tokens.colorBrandBackground;
116
+ const color = (0, react_1.useMemo)(() => {
117
+ if (!background) {
118
+ return;
119
+ }
120
+ return (0, color_1.isColorDark)(background) ? '#FFFFFF' : '#000000';
121
+ }, [background]);
113
122
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
114
123
  display: 'flex',
115
124
  alignItems: 'center',
116
125
  height: 50,
117
126
  minHeight: 50,
118
- background: react_components_1.tokens.colorBrandBackground,
127
+ background,
119
128
  paddingInline: 8,
120
129
  gap: 8,
121
- color: 'white',
130
+ color,
122
131
  }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flex: 1, alignItems: 'center', gap: 8 }, children: [isTablet && (0, jsx_runtime_1.jsx)(NavHamburger, { onNavToggle: onNavToggle }), (0, jsx_runtime_1.jsx)(NavTitle, {})] }), (0, jsx_runtime_1.jsx)(NavActions, {})] }));
123
132
  };
124
133
  const AppMobileHeader = ({ onNavToggle }) => {
125
134
  const showCustomHeader = (0, mutable_1.useContextSelector)(header_1.HeaderContext, (state) => state.showBackButton.length > 0);
135
+ const { appExperience: app } = (0, app_1.useAppContext)();
126
136
  const headerTitle = (0, header_1.useHeaderValue)('title');
127
137
  const rightComponent = (0, header_1.useHeaderValue)('rightComponent');
128
138
  const showBackButton = (0, header_1.useHeaderValue)('showBackButton');
139
+ const background = app.headerColor ?? react_components_1.tokens.colorBrandBackground;
140
+ const color = (0, react_1.useMemo)(() => {
141
+ if (!background) {
142
+ return;
143
+ }
144
+ return (0, color_1.isColorDark)(background) ? '#FFFFFF' : '#000000';
145
+ }, [background]);
129
146
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
130
147
  display: 'flex',
131
148
  alignItems: 'center',
132
149
  height: 50,
133
150
  minHeight: 50,
134
- background: react_components_1.tokens.colorBrandBackground,
151
+ background,
135
152
  paddingInline: 8,
136
153
  gap: 8,
137
- color: 'white',
154
+ color,
138
155
  zIndex: 10,
139
156
  }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
140
157
  display: 'flex',
@@ -6,19 +6,19 @@ const react_components_1 = require("@fluentui/react-components");
6
6
  const route_1 = require("@headless-adminapp/app/route");
7
7
  const useStyles = (0, react_components_1.makeStyles)({
8
8
  root: {
9
- color: 'rgba(255, 255, 255, 1) !important',
9
+ color: 'inherit !important',
10
10
  background: 'rgba(0, 0, 0, 0)',
11
11
  transition: 'background 0.3s',
12
12
  '&:hover': {
13
- color: 'rgba(255, 255, 255, 1)',
13
+ color: 'inherit',
14
14
  background: 'rgba(0, 0, 0, 0.1)',
15
15
  },
16
16
  '&:active': {
17
- color: 'rgba(255, 255, 255, 1)',
17
+ color: 'inherit',
18
18
  background: 'rgba(0, 0, 0, 0.2)',
19
19
  },
20
20
  '&:focus': {
21
- color: 'rgba(255, 255, 255, 1)',
21
+ color: 'inherit',
22
22
  background: 'rgba(0, 0, 0, 0.2)',
23
23
  },
24
24
  },
@@ -251,6 +251,8 @@ const GridTableContainer = ({ noPadding, disableColumnFilter, disableColumnSort,
251
251
  height: `${virtualRow.size}px`,
252
252
  minWidth: `calc(100% - ${hPadding * 2}px)`,
253
253
  position: 'absolute',
254
+ left: 0,
255
+ right: 0,
254
256
  transform: `translateY(${virtualRow.start}px)`,
255
257
  }, onClick: () => {
256
258
  setSelectedIdsRef.current(() => {
@@ -1,3 +1,5 @@
1
+ import { View } from '@headless-adminapp/core/experience/view';
2
+ import { SchemaAttributes } from '@headless-adminapp/core/schema';
1
3
  import { Filter } from '@headless-adminapp/core/transport';
2
4
  interface WidgetDataGridContainerProps {
3
5
  title: string;
@@ -5,7 +7,10 @@ interface WidgetDataGridContainerProps {
5
7
  maxRecords?: number;
6
8
  filter?: Filter;
7
9
  commands?: any[][];
10
+ view?: View<SchemaAttributes>;
11
+ viewId?: string;
12
+ allowContextMenu?: boolean;
8
13
  }
9
14
  /*** @deprecated Need refactoring */
10
- export declare function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, }: Readonly<WidgetDataGridContainerProps>): import("react/jsx-runtime").JSX.Element;
15
+ export declare function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, view, viewId, allowContextMenu, }: Readonly<WidgetDataGridContainerProps>): import("react/jsx-runtime").JSX.Element;
11
16
  export {};
@@ -11,12 +11,17 @@ const hooks_3 = require("@headless-adminapp/app/metadata/hooks");
11
11
  const DataGrid_1 = require("../DataGrid");
12
12
  const WidgetTitleBar_1 = require("./WidgetTitleBar");
13
13
  /*** @deprecated Need refactoring */
14
- function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, }) {
14
+ function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, view, viewId, allowContextMenu, }) {
15
15
  const schema = (0, hooks_3.useSchema)(logicalName);
16
- const { view } = (0, hooks_3.useExperienceView)(logicalName);
17
- if (!view) {
16
+ const { view: _view, isLoadingView } = (0, hooks_3.useExperienceView)(logicalName, viewId);
17
+ const { commands: contextCommands } = (0, hooks_3.useExperienceViewCommands)(logicalName);
18
+ view ??= _view;
19
+ if (!view && isLoadingView) {
18
20
  return (0, jsx_runtime_1.jsx)("div", { children: "Loading..." });
19
21
  }
22
+ if (!view) {
23
+ return (0, jsx_runtime_1.jsx)("div", { children: "View not found" });
24
+ }
20
25
  if (!schema) {
21
26
  return (0, jsx_runtime_1.jsx)("div", { children: "Schema not found" });
22
27
  }
@@ -28,9 +33,9 @@ function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, ti
28
33
  borderRadius: react_components_1.tokens.borderRadiusMedium,
29
34
  // padding: tokens.spacingHorizontalM,
30
35
  flexDirection: 'column',
31
- }, children: (0, jsx_runtime_1.jsx)(DataGridProvider_1.DataGridProvider, { schema: schema, view: view, views: [], onChangeView: () => { }, commands: [], allowViewSelection: false, maxRecords: maxRecords, extraFilter: filter, children: (0, jsx_runtime_1.jsx)(FormSubgridContainer, { title: title, commands: commands }) }) }));
36
+ }, children: (0, jsx_runtime_1.jsx)(DataGridProvider_1.DataGridProvider, { schema: schema, view: view, views: [], onChangeView: () => { }, commands: contextCommands, allowViewSelection: false, maxRecords: maxRecords, extraFilter: filter, children: (0, jsx_runtime_1.jsx)(FormSubgridContainer, { title: title, commands: commands, allowContextMenu: allowContextMenu }) }) }));
32
37
  }
33
- const FormSubgridContainer = ({ title, commands, }) => {
38
+ const FormSubgridContainer = ({ title, commands, allowContextMenu, }) => {
34
39
  const baseCommandHandleContext = (0, hooks_1.useBaseCommandHandlerContext)();
35
40
  const primaryControl = (0, hooks_2.useGridControlContext)();
36
41
  const transformedCommands = (0, command_1.useCommands)(commands, {
@@ -56,5 +61,5 @@ const FormSubgridContainer = ({ title, commands, }) => {
56
61
  display: 'flex',
57
62
  flexDirection: 'column',
58
63
  flex: 1,
59
- }, children: (0, jsx_runtime_1.jsx)("div", { style: { flex: 1, display: 'flex', minHeight: 300 }, children: (0, jsx_runtime_1.jsx)(DataGrid_1.GridTableContainer, { disableColumnSort: true, disableColumnFilter: true, disableSelection: true, disableContextMenu: true }) }) }) }) })] }));
64
+ }, children: (0, jsx_runtime_1.jsx)("div", { style: { flex: 1, display: 'flex', minHeight: 300 }, children: (0, jsx_runtime_1.jsx)(DataGrid_1.GridTableContainer, { disableColumnSort: true, disableColumnFilter: true, disableSelection: true, disableContextMenu: !allowContextMenu }) }) }) }) })] }));
60
65
  };
@@ -17,5 +17,5 @@ function WidgetTitleBar({ title, commands, rightContent, }) {
17
17
  paddingBlock: 8,
18
18
  height: 40,
19
19
  alignItems: 'center',
20
- }, 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: title }), (0, jsx_runtime_1.jsx)("div", { style: { flex: 1 } }), rightContent, !!commands && commands[0]?.length > 0 && ((0, jsx_runtime_1.jsx)(CommandBar_1.default.Wrapper, { children: commands[0].map((command, index) => (0, OverflowCommandBar_1.renderCommandItem)(index, command, language)) }))] }) }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }) })] }));
20
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', width: '100%' }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Body1Strong, { style: { flexShrink: 0 }, children: title }), (0, jsx_runtime_1.jsx)("div", { style: { flex: 1 } }), rightContent, !!commands && commands[0]?.length > 0 && ((0, jsx_runtime_1.jsx)(CommandBar_1.default.Wrapper, { align: "end", children: commands[0].map((command, index) => (0, OverflowCommandBar_1.renderCommandItem)(index, command, language)) }))] }) }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }) })] }));
21
21
  }
@@ -0,0 +1,16 @@
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 CardUiProps {
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
+ readOnly?: boolean;
14
+ }
15
+ export declare const CardUi: FC<CardUiProps>;
16
+ export {};
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CardUi = void 0;
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 constants_1 = require("@headless-adminapp/app/dataform/constants");
8
+ const hooks_1 = require("@headless-adminapp/app/hooks");
9
+ const useCalculatedAttributeStore_1 = require("@headless-adminapp/app/metadata/hooks/useCalculatedAttributeStore");
10
+ const icons_1 = require("@headless-adminapp/icons");
11
+ const react_hook_form_1 = require("react-hook-form");
12
+ const SectionControl_1 = require("../../DataForm/SectionControl");
13
+ const StandardControl_1 = require("../StandardControl");
14
+ const CardUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, alias, readOnly, }) => {
15
+ const eventManager = (0, dataform_1.useEventManager)();
16
+ const calculatedAttributeStore = (0, useCalculatedAttributeStore_1.useCalculatedAttributeStore)();
17
+ const isMobile = (0, hooks_1.useIsMobile)();
18
+ const isTablet = (0, hooks_1.useIsTablet)();
19
+ let controlsPerRow;
20
+ if (isMobile) {
21
+ controlsPerRow = 1;
22
+ }
23
+ else if (isTablet) {
24
+ controlsPerRow = 3;
25
+ }
26
+ else {
27
+ controlsPerRow = 6;
28
+ }
29
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
30
+ display: 'flex',
31
+ flexDirection: 'column',
32
+ gap: react_components_1.tokens.spacingVerticalM,
33
+ }, children: [rows.map((item, index) => ((0, jsx_runtime_1.jsxs)("div", { style: {
34
+ boxShadow: react_components_1.tokens.shadow4,
35
+ borderRadius: react_components_1.tokens.borderRadiusMedium,
36
+ padding: react_components_1.tokens.spacingVerticalM,
37
+ position: 'relative',
38
+ display: 'flex',
39
+ flexDirection: 'column',
40
+ gap: react_components_1.tokens.spacingVerticalM,
41
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
42
+ display: 'flex',
43
+ flexWrap: 'wrap',
44
+ justifyContent: 'flex-start',
45
+ alignItems: 'stretch',
46
+ margin: -8,
47
+ }, children: control.controls.map((control) => {
48
+ const attributeName = typeof control === 'string' ? control : control.attributeName;
49
+ const attribute = schema.attributes[attributeName];
50
+ if (!attribute) {
51
+ return null;
52
+ }
53
+ const calculatedAttribute = calculatedAttributeStore?.getCalculatedAttributeInfo(schema.logicalName, attributeName);
54
+ const isControlReadonly = readOnly ||
55
+ (calculatedAttribute && !calculatedAttribute.allowUserToEdit);
56
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
57
+ flexShrink: 0,
58
+ flex: `0 0 ${100 / controlsPerRow}%`,
59
+ maxWidth: `${100 / controlsPerRow}%`,
60
+ padding: 8,
61
+ }, children: (0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { name: `${alias}.${index}.${attributeName}`, control: formControl, render: ({ field, fieldState, formState }) => {
62
+ const isError = (fieldState.isTouched || formState.isSubmitted) &&
63
+ !!fieldState.error?.message;
64
+ return ((0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelPosition: "top", isError: isError, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value ?? null, readOnly: isControlReadonly, onChange: (value) => {
65
+ const previousValue = field.value;
66
+ field.onChange(value);
67
+ eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, field.name, value, previousValue);
68
+ }, onBlur: field.onBlur, placeholder: "" }) }));
69
+ } }) }, attributeName));
70
+ }) }), (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }), !readOnly && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Delete, { size: 16 }), appearance: "primary", onClick: () => onRemoveRow?.(index), style: {
71
+ fontWeight: react_components_1.tokens.fontWeightRegular,
72
+ alignSelf: 'flex-start',
73
+ color: react_components_1.tokens.colorStatusDangerForeground1,
74
+ backgroundColor: react_components_1.tokens.colorStatusDangerBackground1,
75
+ minWidth: 0,
76
+ }, size: "small", children: "Remove" }))] }, item.__key))), !readOnly && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Add, { size: 16 }), appearance: "primary", onClick: onAddRow, style: { alignSelf: 'flex-start', minWidth: 0 }, size: "small", children: "Add" }))] }));
77
+ };
78
+ exports.CardUi = CardUi;
@@ -4,9 +4,11 @@ exports.EditableGridControl = EditableGridControl;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
6
  const dataform_1 = require("@headless-adminapp/app/dataform");
7
+ const constants_1 = require("@headless-adminapp/app/dataform/constants");
7
8
  const getRecord_1 = require("@headless-adminapp/app/dataform/DataFormProvider/getRecord");
8
9
  const saveRecord_1 = require("@headless-adminapp/app/dataform/utils/saveRecord");
9
10
  const form_1 = require("@headless-adminapp/app/form");
11
+ const hooks_1 = require("@headless-adminapp/app/hooks");
10
12
  const locale_1 = require("@headless-adminapp/app/locale");
11
13
  const metadata_1 = require("@headless-adminapp/app/metadata");
12
14
  const transport_1 = require("@headless-adminapp/app/transport");
@@ -15,10 +17,12 @@ const react_query_1 = require("@tanstack/react-query");
15
17
  const react_1 = require("react");
16
18
  const react_hook_form_1 = require("react-hook-form");
17
19
  const BodyLoading_1 = require("../../components/BodyLoading");
20
+ const CardUi_1 = require("./CardUi");
18
21
  const TableUi_1 = require("./TableUi");
19
22
  function EditableGridControl({ readOnly, control, }) {
20
23
  const recordId = (0, dataform_1.useRecordId)();
21
24
  const dataService = (0, transport_1.useDataService)();
25
+ const isMobile = (0, hooks_1.useIsMobile)();
22
26
  const { schemaStore } = (0, metadata_1.useMetadata)();
23
27
  const { language, region } = (0, locale_1.useLocale)();
24
28
  const formValidationStrings = (0, form_1.useFormValidationStrings)();
@@ -55,6 +59,7 @@ function EditableGridControl({ readOnly, control, }) {
55
59
  },
56
60
  enabled: !!recordId && !control.alias,
57
61
  });
62
+ const eventManager = (0, dataform_1.useEventManager)();
58
63
  const formInstanceRef = (0, react_1.useRef)(localFormInstance);
59
64
  formInstanceRef.current = localFormInstance;
60
65
  (0, react_1.useEffect)(() => {
@@ -91,6 +96,7 @@ function EditableGridControl({ readOnly, control, }) {
91
96
  }
92
97
  });
93
98
  fieldArray.append(newItem);
99
+ eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, `${alias}.${fieldArray.fields.length}`, newItem, null);
94
100
  };
95
101
  const handleSave = async () => {
96
102
  await localFormInstance.handleSubmit(async (values) => {
@@ -127,7 +133,15 @@ function EditableGridControl({ readOnly, control, }) {
127
133
  alignItems: 'center',
128
134
  }, 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
135
  !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) => {
136
+ !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: !isMobile &&
137
+ control.format === 'grid' &&
138
+ control.controls.length < 10 ? ((0, jsx_runtime_1.jsx)(TableUi_1.TableUi, { schema: schema, control: control, formControl: formControl, alias: alias, onAddRow: handleAddRow, onRemoveRow: (index) => {
139
+ const previousValue = fieldArray.fields[index];
131
140
  fieldArray.remove(index);
132
- }, rows: fieldArray.fields }) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: isFetching || localFormInstance.formState.isSubmitting })] }));
141
+ eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, `${alias}.${index}`, null, previousValue);
142
+ }, rows: fieldArray.fields, readOnly: readOnly })) : ((0, jsx_runtime_1.jsx)(CardUi_1.CardUi, { schema: schema, control: control, formControl: formControl, alias: alias, onAddRow: handleAddRow, onRemoveRow: (index) => {
143
+ const previousValue = fieldArray.fields[index];
144
+ fieldArray.remove(index);
145
+ eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, `${alias}.${index}`, null, previousValue);
146
+ }, rows: fieldArray.fields, readOnly: readOnly })) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: isFetching || localFormInstance.formState.isSubmitting })] }));
133
147
  }
@@ -10,6 +10,7 @@ interface TableUiProps {
10
10
  onRemoveRow?: (index: number) => void;
11
11
  rows: Record<'__key', string>[];
12
12
  alias: string;
13
+ readOnly?: boolean;
13
14
  }
14
15
  export declare const TableUi: FC<TableUiProps>;
15
16
  export {};
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TableUi = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
+ const dataform_1 = require("@headless-adminapp/app/dataform");
7
+ const constants_1 = require("@headless-adminapp/app/dataform/constants");
8
+ const useCalculatedAttributeStore_1 = require("@headless-adminapp/app/metadata/hooks/useCalculatedAttributeStore");
6
9
  const icons_1 = require("@headless-adminapp/icons");
7
10
  const react_hook_form_1 = require("react-hook-form");
8
11
  const SectionControl_1 = require("../../DataForm/SectionControl");
@@ -39,26 +42,35 @@ const useStyles = (0, react_components_1.makeStyles)({
39
42
  },
40
43
  },
41
44
  });
42
- const TableUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, alias, }) => {
45
+ const TableUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, alias, readOnly, }) => {
43
46
  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) => {
47
+ const eventManager = (0, dataform_1.useEventManager)();
48
+ const calculatedAttributeStore = (0, useCalculatedAttributeStore_1.useCalculatedAttributeStore)();
49
+ 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))), !readOnly && (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
50
  const attributeName = typeof control === 'string' ? control : control.attributeName;
46
51
  const attribute = schema.attributes[attributeName];
47
52
  if (!attribute) {
48
53
  return null;
49
54
  }
50
55
  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) => {
56
+ }), !readOnly && ((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
57
  const attributeName = typeof control === 'string' ? control : control.attributeName;
53
58
  const attribute = schema.attributes[attributeName];
54
59
  if (!attribute) {
55
60
  return null;
56
61
  }
62
+ const calculatedAttribute = calculatedAttributeStore?.getCalculatedAttributeInfo(schema.logicalName, attributeName);
63
+ const isControlReadonly = readOnly ||
64
+ (calculatedAttribute && !calculatedAttribute.allowUserToEdit);
57
65
  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
66
  const isError = (fieldState.isTouched || formState.isSubmitted) &&
59
67
  !!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: "" }) }));
68
+ 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, readOnly: isControlReadonly, onChange: (value) => {
69
+ const previousValue = field.value;
70
+ field.onChange(value);
71
+ eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, field.name, value, previousValue);
72
+ }, onBlur: field.onBlur, placeholder: "" }) }));
61
73
  } }) }, 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))) })] }));
74
+ }), !readOnly && ((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
75
  };
64
76
  exports.TableUi = TableUi;
@@ -11,6 +11,7 @@ const historystate_1 = require("@headless-adminapp/app/historystate");
11
11
  const hooks_2 = require("@headless-adminapp/app/hooks");
12
12
  const locale_1 = require("@headless-adminapp/app/locale");
13
13
  const utils_2 = require("@headless-adminapp/app/locale/utils");
14
+ const useCalculatedAttributeStore_1 = require("@headless-adminapp/app/metadata/hooks/useCalculatedAttributeStore");
14
15
  const mutable_1 = require("@headless-adminapp/app/mutable");
15
16
  const react_1 = require("react");
16
17
  const react_hook_form_1 = require("react-hook-form");
@@ -32,6 +33,7 @@ function SectionContainer({ section, skeleton, }) {
32
33
  const hiddenControls = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.hiddenControls);
33
34
  const requiredFields = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.requiredFields);
34
35
  const hiddenSections = (0, mutable_1.useContextSelector)(dataform_1.DataFormContext, (state) => state.hiddenSections);
36
+ const calculatedAttributeStore = (0, useCalculatedAttributeStore_1.useCalculatedAttributeStore)();
35
37
  const visibleControls = (0, react_1.useMemo)(() => section.controls.filter((control) => {
36
38
  return !(0, utils_1.getIsControlHidden)({
37
39
  control,
@@ -66,6 +68,7 @@ function SectionContainer({ section, skeleton, }) {
66
68
  disabledFields: disabledControls,
67
69
  attribute,
68
70
  control,
71
+ calculatedAttribute: calculatedAttributeStore?.getCalculatedAttributeInfo(schema.logicalName, control.attributeName),
69
72
  });
70
73
  const required = (0, utils_1.getIsFieldRequired)({
71
74
  attribute,
@@ -105,6 +108,7 @@ function SectionContainer({ section, skeleton, }) {
105
108
  disabledFields: disabledControls,
106
109
  attribute: null,
107
110
  control,
111
+ calculatedAttribute: undefined,
108
112
  });
109
113
  return ((0, jsx_runtime_1.jsx)(EditableGridControl_1.EditableGridControl, { readOnly: disabled, control: control }));
110
114
  }
@@ -11,6 +11,7 @@ function CurrencyControl({ value, onChange, id, name, onBlur, onFocus,
11
11
  disabled, placeholder, autoFocus,
12
12
  // borderOnFocusOnly,
13
13
  readOnly, skeleton, }) {
14
+ const isReadOnly = readOnly || disabled;
14
15
  const symbol = (0, locale_1.useCurrencySymbol)();
15
16
  const [internalValue, setInternalValue] = (0, react_1.useState)(value ? value.toString() : '');
16
17
  const internalValueRef = (0, react_1.useRef)(internalValue);
@@ -49,7 +50,11 @@ readOnly, skeleton, }) {
49
50
  if (skeleton) {
50
51
  return (0, jsx_runtime_1.jsx)(SkeletonControl_1.SkeletonControl, {});
51
52
  }
52
- return ((0, jsx_runtime_1.jsx)(react_components_1.Input, { placeholder: placeholder, id: id, autoFocus: autoFocus, name: name, value: internalValue, onChange: handleChange, onBlur: () => onBlur?.(), appearance: "filled-darker", onFocus: () => onFocus?.(), contentBefore: (0, jsx_runtime_1.jsx)("div", { children: symbol }), readOnly: readOnly || disabled, style: {
53
+ return ((0, jsx_runtime_1.jsx)(react_components_1.Input, { placeholder: placeholder, id: id, autoFocus: autoFocus, name: name, value: internalValue, onChange: handleChange, onBlur: () => onBlur?.(), appearance: "filled-darker", onFocus: () => onFocus?.(), contentBefore: (0, jsx_runtime_1.jsx)("div", { children: symbol }), readOnly: isReadOnly, className: (0, react_components_1.mergeClasses)(isReadOnly && 'TextControl_readonly'), style: {
53
54
  width: '100%',
55
+ }, input: {
56
+ style: {
57
+ width: '100%',
58
+ },
54
59
  } }));
55
60
  }
@@ -27,6 +27,10 @@ function DateControl({ value, onChange, id, name, onBlur, onFocus, placeholder,
27
27
  onChange?.(date ? (0, dayjs_1.default)(date).format('YYYY-MM-DD') : null);
28
28
  }, strings: datePickerStrings, style: {
29
29
  width: '100%',
30
+ }, input: {
31
+ style: {
32
+ width: '100%',
33
+ },
30
34
  }, contentAfter: (0, jsx_runtime_1.jsx)("div", { style: {
31
35
  display: 'flex',
32
36
  alignItems: 'center',
@@ -52,5 +52,9 @@ function DecimalControl({ value, onChange, id, name, onBlur, onFocus, error, dis
52
52
  }
53
53
  return ((0, jsx_runtime_1.jsx)(react_components_1.Input, { placeholder: placeholder, id: id, appearance: "filled-darker", name: name, value: internalValue, onChange: handleChange, onBlur: () => onBlur?.(), onFocus: () => onFocus?.(), readOnly: readOnly || disabled, style: {
54
54
  width: '100%',
55
+ }, input: {
56
+ style: {
57
+ width: '100%',
58
+ },
55
59
  } }));
56
60
  }
@@ -11,6 +11,10 @@ function IntegerControl({ value, onChange, id, name, onBlur, onFocus, error, dis
11
11
  }
12
12
  return ((0, jsx_runtime_1.jsx)(react_components_1.SpinButton, { appearance: "filled-darker", placeholder: placeholder, id: id, name: name, value: value ?? null, readOnly: readOnly || disabled, style: {
13
13
  width: '100%',
14
+ }, input: {
15
+ style: {
16
+ width: '100%',
17
+ },
14
18
  }, onChange: (e, data) => {
15
19
  if (data.value !== undefined) {
16
20
  onChange?.(data.value);
@@ -101,7 +101,11 @@ const LookupControlMd = ({ value, onChange, id, name, onBlur, onFocus, placehold
101
101
  if (skeleton) {
102
102
  return (0, jsx_runtime_1.jsx)(SkeletonControl_1.SkeletonControl, {});
103
103
  }
104
- return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', width: '100%' }, children: [(0, jsx_runtime_1.jsxs)(react_components_1.Combobox, { name: name, appearance: "filled-darker", expandIcon: readOnly || disabled ? null : isLoading ? ((0, jsx_runtime_1.jsx)(react_components_1.Spinner, { size: "extra-tiny" })) : ((0, jsx_runtime_1.jsx)(icons_1.Icons.Search, { size: 18 })), placeholder: !value ? placeholder : '', inputMode: "search", style: { width: '100%', minWidth: 'unset' }, autoComplete: "off", readOnly: readOnly || disabled,
104
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative', width: '100%' }, children: [(0, jsx_runtime_1.jsxs)(react_components_1.Combobox, { name: name, appearance: "filled-darker", expandIcon: readOnly || disabled ? null : isLoading ? ((0, jsx_runtime_1.jsx)(react_components_1.Spinner, { size: "extra-tiny" })) : ((0, jsx_runtime_1.jsx)(icons_1.Icons.Search, { size: 18 })), placeholder: !value ? placeholder : '', inputMode: "search", style: { width: '100%', minWidth: 'unset' }, input: {
105
+ style: {
106
+ width: '100%',
107
+ },
108
+ }, autoComplete: "off", readOnly: readOnly || disabled,
105
109
  // disabled={disabled}
106
110
  open: open && !value && !readOnly && !disabled, value: !value ? searchText : '', onOpenChange: (e, data) => setOpen(data.open), onChange: (e) => {
107
111
  setSearchText(e.target.value);
@@ -28,5 +28,9 @@ readOnly, appearance = 'filled-darker', maxLength, skeleton, }) {
28
28
  // readOnly={readOnly || disabled}
29
29
  readOnly: readonly, autoComplete: autoComplete, autoCorrect: autoCorrect, autoCapitalize: autoCapitalize, className: (0, react_components_1.mergeClasses)(readonly && 'TextControl_readonly'), style: {
30
30
  width: '100%',
31
- }, maxLength: maxLength }));
31
+ }, maxLength: maxLength, input: {
32
+ style: {
33
+ width: '100%',
34
+ },
35
+ } }));
32
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-adminapp/fluent",
3
- "version": "1.4.15",
3
+ "version": "1.4.16",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -52,5 +52,5 @@
52
52
  "uuid": "11.0.3",
53
53
  "yup": "^1.4.0"
54
54
  },
55
- "gitHead": "a95b4f3c11bcb78f672fb7299bb461368d70bd48"
55
+ "gitHead": "6a07ecfa5a139983b9b86ceea1acb10ce834d01a"
56
56
  }