@headless-adminapp/fluent 1.4.29 → 1.4.31
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/DataGrid/GridColumnHeader/TableHeaderFilterCell.js +4 -1
- package/DataGrid/useTableColumns.js +10 -8
- package/Insights/Header.js +1 -1
- package/Insights/WidgetDataGridContainer.d.ts +0 -1
- package/Insights/WidgetDataGridContainer.js +2 -2
- package/PageBoard/HeaderQuickFilter.js +1 -1
- package/PageCalendar/Header.js +1 -1
- package/PageEntityForm/EditableGridControl/CardUi.js +1 -1
- package/PageEntityForm/EditableGridControl/TableUi.js +1 -1
- package/PageEntityForm/StandardControl.js +1 -0
- package/PageInsight/PageInsight.js +18 -2
- package/components/fluent/Dropdown.js +13 -2
- package/form/controls/DateRangeControl/DateRangeControl.d.ts +2 -1
- package/form/controls/DateRangeControl/DateRangeControl.js +2 -2
- package/form/controls/DateRangeControl/PopoverContent.js +136 -3
- package/form/controls/GroupedSelectControl.d.ts +15 -0
- package/form/controls/GroupedSelectControl.js +43 -0
- package/form/controls/SelectControl.d.ts +5 -3
- package/form/controls/SelectControl.js +2 -2
- package/package.json +2 -2
|
@@ -59,6 +59,9 @@ const TableHeaderFilterCell = ({ children, sortDirection, onChangeSortDirection,
|
|
|
59
59
|
const strings = (0, PageEntityViewStringContext_1.usePageEntityViewStrings)();
|
|
60
60
|
const attribute = (0, react_1.useMemo)(() => {
|
|
61
61
|
const _attribute = schema.attributes[column.name];
|
|
62
|
+
if (!_attribute) {
|
|
63
|
+
throw new Error(`Attribute not found: ${column.name} in ${schema.logicalName}`);
|
|
64
|
+
}
|
|
62
65
|
if (!column.expandedKey) {
|
|
63
66
|
return _attribute;
|
|
64
67
|
}
|
|
@@ -101,7 +104,7 @@ const TableHeaderFilterCell = ({ children, sortDirection, onChangeSortDirection,
|
|
|
101
104
|
if (!disableFilter) {
|
|
102
105
|
menuItems.push(filterMenuItems);
|
|
103
106
|
}
|
|
104
|
-
const headerCell = ((0, jsx_runtime_1.jsxs)(react_components_1.TableHeaderCell, { as: "
|
|
107
|
+
const headerCell = ((0, jsx_runtime_1.jsxs)(react_components_1.TableHeaderCell, { as: "th", className: (0, react_components_1.mergeClasses)(styles.root, align === 'right' && styles.right), style: {
|
|
105
108
|
textAlign: align,
|
|
106
109
|
width: minWidth,
|
|
107
110
|
minWidth: minWidth,
|
|
@@ -66,17 +66,19 @@ function useTableColumns({ disableSelection, disableContextMenu, disableColumnRe
|
|
|
66
66
|
columns: columns.map((column) => {
|
|
67
67
|
const attribute = schema.attributes[column.name];
|
|
68
68
|
let defaultMaxWidth = 1000;
|
|
69
|
-
if (attribute
|
|
70
|
-
if (attribute.
|
|
71
|
-
|
|
69
|
+
if (attribute) {
|
|
70
|
+
if (attribute.type === 'date') {
|
|
71
|
+
if (attribute.format === 'datetime') {
|
|
72
|
+
defaultMaxWidth = 200;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
defaultMaxWidth = 100;
|
|
76
|
+
}
|
|
72
77
|
}
|
|
73
|
-
else {
|
|
74
|
-
defaultMaxWidth =
|
|
78
|
+
else if (attribute.type === 'money') {
|
|
79
|
+
defaultMaxWidth = 150;
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
|
-
else if (attribute.type === 'money') {
|
|
78
|
-
defaultMaxWidth = 150;
|
|
79
|
-
}
|
|
80
82
|
return {
|
|
81
83
|
width: column.width ?? 100,
|
|
82
84
|
maxWidth: column.maxWidth ?? defaultMaxWidth,
|
package/Insights/Header.js
CHANGED
|
@@ -48,7 +48,7 @@ const Header = () => {
|
|
|
48
48
|
eventManager.emit('INSIGHT_REFRESH_TRIGGER');
|
|
49
49
|
}, children: "Refresh" }) })] }), !!config.filterAttributes && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: react_components_1.tokens.spacingHorizontalS }, children: Object.entries(config.filterAttributes).map(([attributeName, attribute]) => {
|
|
50
50
|
return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: filterForm.control, name: attributeName, render: ({ field }) => {
|
|
51
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: { width: 210, minWidth: 210 }, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur }) }));
|
|
51
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: { width: 210, minWidth: 210 }, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur, required: attribute.required }) }));
|
|
52
52
|
} }, attributeName));
|
|
53
53
|
}) })] }))] }));
|
|
54
54
|
};
|
|
@@ -11,6 +11,5 @@ interface WidgetDataGridContainerProps {
|
|
|
11
11
|
viewId?: string;
|
|
12
12
|
allowContextMenu?: boolean;
|
|
13
13
|
}
|
|
14
|
-
/*** @deprecated Need refactoring */
|
|
15
14
|
export declare function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, view, viewId, allowContextMenu, }: Readonly<WidgetDataGridContainerProps>): import("react/jsx-runtime").JSX.Element;
|
|
16
15
|
export {};
|
|
@@ -6,6 +6,7 @@ const command_1 = require("@headless-adminapp/app/command");
|
|
|
6
6
|
const hooks_1 = require("@headless-adminapp/app/command/hooks");
|
|
7
7
|
const DataGridProvider_1 = require("@headless-adminapp/app/datagrid/DataGridProvider");
|
|
8
8
|
const hooks_2 = require("@headless-adminapp/app/datagrid/hooks");
|
|
9
|
+
const historystate_1 = require("@headless-adminapp/app/historystate");
|
|
9
10
|
const hooks_3 = require("@headless-adminapp/app/hooks");
|
|
10
11
|
const hooks_4 = require("@headless-adminapp/app/metadata/hooks");
|
|
11
12
|
const BodyLoading_1 = require("../components/BodyLoading");
|
|
@@ -13,7 +14,6 @@ const DataGrid_1 = require("../DataGrid");
|
|
|
13
14
|
const GridListContainer_1 = require("../DataGrid/GridListContainer");
|
|
14
15
|
const WidgetSection_1 = require("./WidgetSection");
|
|
15
16
|
const WidgetTitleBar_1 = require("./WidgetTitleBar");
|
|
16
|
-
/*** @deprecated Need refactoring */
|
|
17
17
|
function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, title, view, viewId, allowContextMenu, }) {
|
|
18
18
|
const schema = (0, hooks_4.useSchema)(logicalName);
|
|
19
19
|
const { view: _view, isLoadingView } = (0, hooks_4.useExperienceView)(logicalName, viewId);
|
|
@@ -28,7 +28,7 @@ function WidgetDataGridContainer({ logicalName, maxRecords, filter, commands, ti
|
|
|
28
28
|
if (!schema) {
|
|
29
29
|
return ((0, jsx_runtime_1.jsx)(WidgetSection_1.WidgetSection, { children: (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flex: 1, position: 'relative' }, children: "Schema not found" }) }));
|
|
30
30
|
}
|
|
31
|
-
return ((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 }) }));
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(historystate_1.HistoryStateKeyProvider, { historyKey: "~", 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
32
|
}
|
|
33
33
|
const FormSubgridContainer = ({ title, commands, allowContextMenu, }) => {
|
|
34
34
|
const isMobile = (0, hooks_3.useIsMobile)();
|
|
@@ -15,7 +15,7 @@ const HeaderQuickFilter = () => {
|
|
|
15
15
|
display: 'flex',
|
|
16
16
|
gap: react_components_1.tokens.spacingHorizontalS,
|
|
17
17
|
}, children: Object.entries(quickFilter.attributes).map(([key, attribute]) => {
|
|
18
|
-
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelHidden: true, labelPosition: "top", children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: key, value: values[key] ?? null, onChange: (value) => setValue(key, value) }) }) }, key));
|
|
18
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelHidden: true, labelPosition: "top", children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: key, value: values[key] ?? null, onChange: (value) => setValue(key, value), required: attribute.required }) }) }, key));
|
|
19
19
|
}) }));
|
|
20
20
|
};
|
|
21
21
|
exports.HeaderQuickFilter = HeaderQuickFilter;
|
package/PageCalendar/Header.js
CHANGED
|
@@ -38,7 +38,7 @@ function Header({ filterForm, onCreateButtonClick, }) {
|
|
|
38
38
|
} })] })] }), !!config.filterAttributes &&
|
|
39
39
|
Object.keys(config.filterAttributes).length > 0 && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: react_components_1.tokens.spacingHorizontalS }, children: Object.entries(config.filterAttributes).map(([attributeName, attribute]) => {
|
|
40
40
|
return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: filterForm.control, name: attributeName, render: ({ field }) => {
|
|
41
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: { width: 210, minWidth: 210 }, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur }) }));
|
|
41
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: { width: 210, minWidth: 210 }, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur, required: attribute.required }) }));
|
|
42
42
|
} }, attributeName));
|
|
43
43
|
}) })] }))] }));
|
|
44
44
|
}
|
|
@@ -66,7 +66,7 @@ const CardUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, ali
|
|
|
66
66
|
const previousValue = field.value;
|
|
67
67
|
field.onChange(value);
|
|
68
68
|
eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, field.name, value, previousValue);
|
|
69
|
-
}, onBlur: field.onBlur, placeholder: "" }) }));
|
|
69
|
+
}, onBlur: field.onBlur, placeholder: "", allowNewRecord: true, allowNavigation: true, allowQuickCreate: true }) }));
|
|
70
70
|
} }) }, attributeName));
|
|
71
71
|
}) }), (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }), !readOnly && ((0, jsx_runtime_1.jsx)(fluent_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Delete, { size: 16 }), appearance: "primary", onClick: () => onRemoveRow?.(index), style: {
|
|
72
72
|
alignSelf: 'flex-start',
|
|
@@ -70,7 +70,7 @@ const TableUi = ({ schema, control, formControl, onAddRow, onRemoveRow, rows, al
|
|
|
70
70
|
const previousValue = field.value;
|
|
71
71
|
field.onChange(value);
|
|
72
72
|
eventManager.emit(constants_1.EVENT_KEY_ON_FIELD_CHANGE, field.name, value, previousValue);
|
|
73
|
-
}, onBlur: field.onBlur, placeholder: "" }) }));
|
|
73
|
+
}, onBlur: field.onBlur, placeholder: "", allowNewRecord: true, allowNavigation: true, allowQuickCreate: true }) }));
|
|
74
74
|
} }) }, attributeName));
|
|
75
75
|
}), !readOnly && ((0, jsx_runtime_1.jsx)(react_components_1.TableCell, { children: (0, jsx_runtime_1.jsx)(fluent_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Delete, { size: 16 }), appearance: "subtle", onClick: () => onRemoveRow?.(index) }) }))] }, item.__key))) })] }));
|
|
76
76
|
};
|
|
@@ -166,6 +166,7 @@ const StandardControl = (props) => {
|
|
|
166
166
|
disabled: isDisabled,
|
|
167
167
|
readOnly,
|
|
168
168
|
skeleton,
|
|
169
|
+
required,
|
|
169
170
|
};
|
|
170
171
|
const Control = componentStore_1.componentStore.getComponent('Form.DateRangeControl') ?? DateRangeControl_1.DateRangeControl;
|
|
171
172
|
return (0, jsx_runtime_1.jsx)(Control, { ...controlProps });
|
|
@@ -2,16 +2,27 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PageInsight = PageInsight;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const historystate_1 = require("@headless-adminapp/app/historystate");
|
|
5
6
|
const insights_1 = require("@headless-adminapp/app/insights");
|
|
6
7
|
const mutable_1 = require("@headless-adminapp/app/mutable");
|
|
8
|
+
const route_1 = require("@headless-adminapp/app/route");
|
|
7
9
|
const store_1 = require("@headless-adminapp/app/store");
|
|
8
10
|
const react_1 = require("react");
|
|
9
11
|
const react_hook_form_1 = require("react-hook-form");
|
|
10
12
|
const InsightsContainer_1 = require("../Insights/InsightsContainer");
|
|
13
|
+
const historyKey = 'page-insight';
|
|
14
|
+
function mergeInitialStateWithHistory(initialValue, historyState) {
|
|
15
|
+
return {
|
|
16
|
+
...initialValue,
|
|
17
|
+
...historyState,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
11
20
|
function PageInsight({ config, }) {
|
|
21
|
+
const router = (0, route_1.useRouter)();
|
|
12
22
|
const filterForm = (0, react_hook_form_1.useForm)({
|
|
13
23
|
mode: 'all',
|
|
14
|
-
defaultValues: config.defaultFilter,
|
|
24
|
+
defaultValues: mergeInitialStateWithHistory(config.defaultFilter, router.getState(historyKey)
|
|
25
|
+
?.filter),
|
|
15
26
|
shouldUnregister: false,
|
|
16
27
|
});
|
|
17
28
|
const filterValues = filterForm.watch();
|
|
@@ -27,5 +38,10 @@ function PageInsight({ config, }) {
|
|
|
27
38
|
filterValues,
|
|
28
39
|
});
|
|
29
40
|
}, [config, filterValues, insightsValues]);
|
|
30
|
-
|
|
41
|
+
(0, react_1.useEffect)(() => {
|
|
42
|
+
router.setState(historyKey, {
|
|
43
|
+
filter: filterValues,
|
|
44
|
+
});
|
|
45
|
+
}, [filterValues, router]);
|
|
46
|
+
return ((0, jsx_runtime_1.jsx)(historystate_1.HistoryStateKeyProvider, { historyKey: historyKey, children: (0, jsx_runtime_1.jsx)(insights_1.InsightsContext.Provider, { value: insightsValues, children: (0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...filterForm, children: (0, jsx_runtime_1.jsx)(InsightsContainer_1.InsightsContainer, {}) }) }) }));
|
|
31
47
|
}
|
|
@@ -5,10 +5,20 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
const react_components_1 = require("@fluentui/react-components");
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const tokens_1 = require("./tokens");
|
|
8
|
+
const useSizeStyles = (0, react_components_1.makeStyles)({
|
|
9
|
+
small: {
|
|
10
|
+
minHeight: tokens_1.extendedTokens.controlMinHeightS,
|
|
11
|
+
},
|
|
12
|
+
medium: {
|
|
13
|
+
minHeight: tokens_1.extendedTokens.controlMinHeightM,
|
|
14
|
+
},
|
|
15
|
+
large: {
|
|
16
|
+
minHeight: tokens_1.extendedTokens.controlMinHeightL,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
8
19
|
const useStyles = (0, react_components_1.makeStyles)({
|
|
9
20
|
root: {
|
|
10
21
|
borderRadius: tokens_1.extendedTokens.controlBorderRadius,
|
|
11
|
-
minHeight: tokens_1.extendedTokens.controlMinHeightM,
|
|
12
22
|
'&::after': {
|
|
13
23
|
borderBottomLeftRadius: tokens_1.extendedTokens.controlBorderRadius,
|
|
14
24
|
borderBottomRightRadius: tokens_1.extendedTokens.controlBorderRadius,
|
|
@@ -34,7 +44,8 @@ const useStyles = (0, react_components_1.makeStyles)({
|
|
|
34
44
|
});
|
|
35
45
|
exports.Dropdown = (0, react_1.forwardRef)(function Dropdown({ className, ...rest }, ref) {
|
|
36
46
|
const styles = useStyles();
|
|
37
|
-
|
|
47
|
+
const sizeStyles = useSizeStyles();
|
|
48
|
+
return ((0, jsx_runtime_1.jsx)(react_components_1.Dropdown, { ...rest, className: (0, react_components_1.mergeClasses)(styles.root, sizeStyles[rest.size || 'medium'], (rest.appearance === 'outline' || !rest.appearance) &&
|
|
38
49
|
styles.outlined, className), ref: ref, listbox: {
|
|
39
50
|
className: styles.listbox,
|
|
40
51
|
} }));
|
|
@@ -2,5 +2,6 @@ import { ControlProps } from '../types';
|
|
|
2
2
|
export interface DateRangeControlProps extends ControlProps<[string, string]> {
|
|
3
3
|
maxDate?: Date;
|
|
4
4
|
minDate?: Date;
|
|
5
|
+
required?: boolean;
|
|
5
6
|
}
|
|
6
|
-
export declare function DateRangeControl({ value, onChange, onBlur, onFocus, disabled, maxDate, minDate, readOnly, skeleton, }: Readonly<DateRangeControlProps>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function DateRangeControl({ value, onChange, onBlur, onFocus, disabled, maxDate, minDate, readOnly, skeleton, required, }: Readonly<DateRangeControlProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,7 +16,7 @@ const useStyles = (0, react_components_1.makeStyles)({
|
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
|
-
function DateRangeControl({ value, onChange, onBlur, onFocus, disabled, maxDate, minDate, readOnly, skeleton, }) {
|
|
19
|
+
function DateRangeControl({ value, onChange, onBlur, onFocus, disabled, maxDate, minDate, readOnly, skeleton, required, }) {
|
|
20
20
|
const [open, setOpen] = (0, react_1.useState)(false);
|
|
21
21
|
const styles = useStyles();
|
|
22
22
|
const { dateRangeFormats } = (0, locale_1.useLocale)();
|
|
@@ -34,7 +34,7 @@ function DateRangeControl({ value, onChange, onBlur, onFocus, disabled, maxDate,
|
|
|
34
34
|
setOpen(data.open);
|
|
35
35
|
}, positioning: "below-start", children: [(0, jsx_runtime_1.jsx)(react_components_1.PopoverTrigger, { disableButtonEnhancement: true, children: (0, jsx_runtime_1.jsx)(fluent_1.Input, { appearance: "filled-darker", readOnly: true, className: styles.input, value: formattedValue, onChange: () => { }, style: {
|
|
36
36
|
width: '100%',
|
|
37
|
-
} }) }), (0, jsx_runtime_1.jsx)(fluent_1.PopoverSurface, { style: { padding: 0 }, children: (0, jsx_runtime_1.jsx)(PopoverContent_1.PopoverContent, { value: value, minDate: minDate, maxDate: maxDate, onChange: (value) => {
|
|
37
|
+
} }) }), (0, jsx_runtime_1.jsx)(fluent_1.PopoverSurface, { style: { padding: 0 }, children: (0, jsx_runtime_1.jsx)(PopoverContent_1.PopoverContent, { value: value, minDate: minDate, maxDate: maxDate, required: required, onChange: (value) => {
|
|
38
38
|
setOpen(false);
|
|
39
39
|
onChange?.(value);
|
|
40
40
|
onBlur?.();
|
|
@@ -7,10 +7,118 @@ exports.PopoverContent = void 0;
|
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const react_components_1 = require("@fluentui/react-components");
|
|
9
9
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
10
|
+
const isoWeek_1 = __importDefault(require("dayjs/plugin/isoWeek"));
|
|
10
11
|
const react_1 = require("react");
|
|
12
|
+
const AppStringContext_1 = require("../../../App/AppStringContext");
|
|
11
13
|
const fluent_1 = require("../../../components/fluent");
|
|
14
|
+
const GroupedSelectControl_1 = __importDefault(require("../GroupedSelectControl"));
|
|
12
15
|
const CalendarItem_1 = require("./CalendarItem");
|
|
13
16
|
const utils_1 = require("./utils");
|
|
17
|
+
dayjs_1.default.extend(isoWeek_1.default);
|
|
18
|
+
const DATE_FORMAT = 'YYYY-MM-DD';
|
|
19
|
+
function createOption(label, values) {
|
|
20
|
+
return {
|
|
21
|
+
label,
|
|
22
|
+
value: `${values[0]}_${values[1]}`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getFiscalYear(date) {
|
|
26
|
+
if (date.month() < 3) {
|
|
27
|
+
return date.year() - 1;
|
|
28
|
+
}
|
|
29
|
+
return date.year();
|
|
30
|
+
}
|
|
31
|
+
function startOfFiscalYear(year) {
|
|
32
|
+
return (0, dayjs_1.default)(`${year}-04-01`).startOf('day');
|
|
33
|
+
}
|
|
34
|
+
function endOfFiscalYear(year) {
|
|
35
|
+
return (0, dayjs_1.default)(`${year + 1}-03-31`).endOf('day');
|
|
36
|
+
}
|
|
37
|
+
function relativeStartOfFiscalyear(offset) {
|
|
38
|
+
const currentFY = getFiscalYear((0, dayjs_1.default)());
|
|
39
|
+
const targetFY = currentFY + offset;
|
|
40
|
+
return startOfFiscalYear(targetFY);
|
|
41
|
+
}
|
|
42
|
+
function relativeEndOfFiscalyear(offset) {
|
|
43
|
+
const currentFY = getFiscalYear((0, dayjs_1.default)());
|
|
44
|
+
const targetFY = currentFY + offset;
|
|
45
|
+
return endOfFiscalYear(targetFY);
|
|
46
|
+
}
|
|
47
|
+
function useQuickOptionGroups() {
|
|
48
|
+
const { operatorStrings } = (0, AppStringContext_1.useAppStrings)();
|
|
49
|
+
return (0, react_1.useMemo)(() => {
|
|
50
|
+
const options = [];
|
|
51
|
+
options.push({
|
|
52
|
+
label: 'Week',
|
|
53
|
+
options: [
|
|
54
|
+
createOption(operatorStrings.thisWeek, [
|
|
55
|
+
(0, dayjs_1.default)().startOf('isoWeek').format(DATE_FORMAT),
|
|
56
|
+
(0, dayjs_1.default)().endOf('isoWeek').format(DATE_FORMAT),
|
|
57
|
+
]),
|
|
58
|
+
createOption(operatorStrings.nextWeek, [
|
|
59
|
+
(0, dayjs_1.default)().add(1, 'week').startOf('isoWeek').format(DATE_FORMAT),
|
|
60
|
+
(0, dayjs_1.default)().add(1, 'week').endOf('isoWeek').format(DATE_FORMAT),
|
|
61
|
+
]),
|
|
62
|
+
createOption(operatorStrings.lastWeek, [
|
|
63
|
+
(0, dayjs_1.default)().subtract(1, 'week').startOf('isoWeek').format(DATE_FORMAT),
|
|
64
|
+
(0, dayjs_1.default)().subtract(1, 'week').endOf('isoWeek').format(DATE_FORMAT),
|
|
65
|
+
]),
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
options.push({
|
|
69
|
+
label: 'Month',
|
|
70
|
+
options: [
|
|
71
|
+
createOption(operatorStrings.thisMonth, [
|
|
72
|
+
(0, dayjs_1.default)().startOf('month').format(DATE_FORMAT),
|
|
73
|
+
(0, dayjs_1.default)().endOf('month').format(DATE_FORMAT),
|
|
74
|
+
]),
|
|
75
|
+
createOption(operatorStrings.nextMonth, [
|
|
76
|
+
(0, dayjs_1.default)().add(1, 'month').startOf('month').format(DATE_FORMAT),
|
|
77
|
+
(0, dayjs_1.default)().add(1, 'month').endOf('month').format(DATE_FORMAT),
|
|
78
|
+
]),
|
|
79
|
+
createOption(operatorStrings.lastMonth, [
|
|
80
|
+
(0, dayjs_1.default)().subtract(1, 'month').startOf('month').format(DATE_FORMAT),
|
|
81
|
+
(0, dayjs_1.default)().subtract(1, 'month').endOf('month').format(DATE_FORMAT),
|
|
82
|
+
]),
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
options.push({
|
|
86
|
+
label: 'Year',
|
|
87
|
+
options: [
|
|
88
|
+
createOption(operatorStrings.thisYear, [
|
|
89
|
+
(0, dayjs_1.default)().startOf('year').format(DATE_FORMAT),
|
|
90
|
+
(0, dayjs_1.default)().endOf('year').format(DATE_FORMAT),
|
|
91
|
+
]),
|
|
92
|
+
createOption(operatorStrings.nextYear, [
|
|
93
|
+
(0, dayjs_1.default)().add(1, 'year').startOf('year').format(DATE_FORMAT),
|
|
94
|
+
(0, dayjs_1.default)().add(1, 'year').endOf('year').format(DATE_FORMAT),
|
|
95
|
+
]),
|
|
96
|
+
createOption(operatorStrings.lastYear, [
|
|
97
|
+
(0, dayjs_1.default)().subtract(1, 'year').startOf('year').format(DATE_FORMAT),
|
|
98
|
+
(0, dayjs_1.default)().subtract(1, 'year').endOf('year').format(DATE_FORMAT),
|
|
99
|
+
]),
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
options.push({
|
|
103
|
+
label: 'Fiscal Year',
|
|
104
|
+
options: [
|
|
105
|
+
createOption(operatorStrings.thisFiscalYear, [
|
|
106
|
+
relativeStartOfFiscalyear(0).format(DATE_FORMAT),
|
|
107
|
+
relativeEndOfFiscalyear(0).format(DATE_FORMAT),
|
|
108
|
+
]),
|
|
109
|
+
createOption(operatorStrings.nextFiscalYear, [
|
|
110
|
+
relativeStartOfFiscalyear(1).format(DATE_FORMAT),
|
|
111
|
+
relativeEndOfFiscalyear(1).format(DATE_FORMAT),
|
|
112
|
+
]),
|
|
113
|
+
createOption(operatorStrings.lastFiscalYear, [
|
|
114
|
+
relativeStartOfFiscalyear(-1).format(DATE_FORMAT),
|
|
115
|
+
relativeEndOfFiscalyear(-1).format(DATE_FORMAT),
|
|
116
|
+
]),
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
return options;
|
|
120
|
+
}, [operatorStrings]);
|
|
121
|
+
}
|
|
14
122
|
const PopoverContent = ({ value, minDate, maxDate, onChange, required, showApplyButton, }) => {
|
|
15
123
|
const [internalValue, setInternalValue] = (0, react_1.useState)([value ? (0, dayjs_1.default)(value[0]) : null, value ? (0, dayjs_1.default)(value[1]) : null]);
|
|
16
124
|
const [navigationDate1, setNavigationDate1] = (0, react_1.useState)(value ? (0, dayjs_1.default)(value[0]) : (0, dayjs_1.default)());
|
|
@@ -63,6 +171,7 @@ const PopoverContent = ({ value, minDate, maxDate, onChange, required, showApply
|
|
|
63
171
|
]);
|
|
64
172
|
}, children: "Apply" }, "apply"));
|
|
65
173
|
}
|
|
174
|
+
const optionGroups = useQuickOptionGroups();
|
|
66
175
|
return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex' }, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex' }, children: [(0, jsx_runtime_1.jsx)(CalendarItem_1.CalendarItem, { date1: date1, date2: date2, navigatedDate: navigationDate1, maxDate: leftMaxDate ?? maxDate, minDate: minDate, onSelectDate: (date) => {
|
|
67
176
|
handleCalendarChange(date, true);
|
|
68
177
|
}, onNavigateDate: (date) => {
|
|
@@ -71,11 +180,35 @@ const PopoverContent = ({ value, minDate, maxDate, onChange, required, showApply
|
|
|
71
180
|
handleCalendarChange(date, false);
|
|
72
181
|
}, onNavigateDate: (date) => {
|
|
73
182
|
setNavigationDate2((0, dayjs_1.default)(date));
|
|
74
|
-
} })] }), (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.5 } }), (0, jsx_runtime_1.
|
|
183
|
+
} })] }), (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.5 } }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
75
184
|
display: 'flex',
|
|
76
185
|
gap: react_components_1.tokens.spacingHorizontalS,
|
|
77
186
|
padding: react_components_1.tokens.spacingVerticalS,
|
|
78
|
-
|
|
79
|
-
}, children:
|
|
187
|
+
alignItems: 'center',
|
|
188
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { style: { minWidth: 120 }, children: (0, jsx_runtime_1.jsx)(GroupedSelectControl_1.default, { placeholder: "Custom range", value: `${date1?.format(DATE_FORMAT) ?? ''}_${date2?.format(DATE_FORMAT) ?? ''}`, size: "small", onChange: (value) => {
|
|
189
|
+
if (!value) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const parts = value.split('_');
|
|
193
|
+
const date1 = (0, dayjs_1.default)(parts[0]);
|
|
194
|
+
const date2 = (0, dayjs_1.default)(parts[1]);
|
|
195
|
+
setNavigationDate1((0, dayjs_1.default)(parts[0]));
|
|
196
|
+
if (date1.year() === date2.year() &&
|
|
197
|
+
date1.month() === date2.month()) {
|
|
198
|
+
setNavigationDate2((0, dayjs_1.default)(parts[0]).add(1, 'month'));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
setNavigationDate2(date2);
|
|
202
|
+
}
|
|
203
|
+
setInternalValue([(0, dayjs_1.default)(parts[0]), (0, dayjs_1.default)(parts[1])]);
|
|
204
|
+
if (!showApplyButton) {
|
|
205
|
+
onChange?.(parts);
|
|
206
|
+
}
|
|
207
|
+
}, optionGroups: optionGroups }) }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
208
|
+
display: 'flex',
|
|
209
|
+
flex: 1,
|
|
210
|
+
gap: react_components_1.tokens.spacingHorizontalS,
|
|
211
|
+
justifyContent: 'flex-end',
|
|
212
|
+
}, children: actions })] })] }) }));
|
|
80
213
|
};
|
|
81
214
|
exports.PopoverContent = PopoverContent;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DropdownProps } from '@fluentui/react-components';
|
|
2
|
+
import { ControlProps } from './types';
|
|
3
|
+
export interface Lookup<T = string> {
|
|
4
|
+
label: string;
|
|
5
|
+
value: T;
|
|
6
|
+
}
|
|
7
|
+
export type GroupedSelectControlProps<T> = ControlProps<T> & {
|
|
8
|
+
optionGroups: Array<{
|
|
9
|
+
label: string;
|
|
10
|
+
options: Lookup<T>[];
|
|
11
|
+
}>;
|
|
12
|
+
clearable?: boolean;
|
|
13
|
+
size?: DropdownProps['size'];
|
|
14
|
+
};
|
|
15
|
+
export default function GroupedSelectControl<T extends string | number>({ value, onChange, optionGroups, id, name, disabled, onBlur, onFocus, placeholder, skeleton, clearable, size, }: Readonly<GroupedSelectControlProps<T>>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = GroupedSelectControl;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const fluent_1 = require("../../components/fluent");
|
|
8
|
+
const Option_1 = require("../../components/fluent/Option");
|
|
9
|
+
const SkeletonControl_1 = require("./SkeletonControl");
|
|
10
|
+
function GroupedSelectControl({ value, onChange, optionGroups, id, name, disabled, onBlur, onFocus, placeholder, skeleton, clearable, size, }) {
|
|
11
|
+
const handleChange = (value) => {
|
|
12
|
+
const option = optionGroups
|
|
13
|
+
.flatMap((group) => group.options)
|
|
14
|
+
.find((x) => String(x.value) === String(value));
|
|
15
|
+
if (option) {
|
|
16
|
+
onChange?.(option.value);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
onChange?.(null);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const selectedOption = (0, react_1.useMemo)(() => optionGroups
|
|
23
|
+
.flatMap((group) => group.options)
|
|
24
|
+
.find((x) => x.value === value), [optionGroups, value]);
|
|
25
|
+
if (skeleton) {
|
|
26
|
+
return (0, jsx_runtime_1.jsx)(SkeletonControl_1.SkeletonControl, {});
|
|
27
|
+
}
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)(fluent_1.Dropdown, { placeholder: placeholder, id: id, name: name, appearance: "filled-darker", size: size, value: selectedOption?.label ?? '', selectedOptions: value ? [String(value)] : [], onOptionSelect: (event, data) => {
|
|
29
|
+
handleChange(data.optionValue);
|
|
30
|
+
}, onBlur: () => onBlur?.(), onFocus: () => onFocus?.(), style: {
|
|
31
|
+
pointerEvents: disabled ? 'none' : undefined,
|
|
32
|
+
width: '100%',
|
|
33
|
+
minWidth: 'unset',
|
|
34
|
+
}, clearable: clearable, clearButton: {
|
|
35
|
+
style: {
|
|
36
|
+
marginRight: react_components_1.tokens.spacingHorizontalXS,
|
|
37
|
+
},
|
|
38
|
+
}, expandIcon: {
|
|
39
|
+
style: {
|
|
40
|
+
marginRight: -6,
|
|
41
|
+
},
|
|
42
|
+
}, children: optionGroups.map((group) => ((0, jsx_runtime_1.jsx)(react_components_1.OptionGroup, { label: group.label, children: group.options.map((option) => ((0, jsx_runtime_1.jsx)(Option_1.Option, { value: String(option.value), children: option.label }, option.value))) }, group.label))) }));
|
|
43
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { DropdownProps } from '@fluentui/react-components';
|
|
1
2
|
import { ControlProps } from './types';
|
|
2
3
|
export interface Lookup<T = string> {
|
|
3
4
|
label: string;
|
|
4
5
|
value: T;
|
|
5
6
|
}
|
|
6
|
-
export
|
|
7
|
+
export type SelectControlProps<T> = ControlProps<T> & {
|
|
7
8
|
options: Lookup<T>[];
|
|
8
9
|
clearable?: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
size?: DropdownProps['size'];
|
|
11
|
+
};
|
|
12
|
+
export default function SelectControl<T extends string | number>({ value, onChange, options, id, name, disabled, onBlur, onFocus, placeholder, skeleton, clearable, size, }: Readonly<SelectControlProps<T>>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,7 +7,7 @@ const react_1 = require("react");
|
|
|
7
7
|
const fluent_1 = require("../../components/fluent");
|
|
8
8
|
const Option_1 = require("../../components/fluent/Option");
|
|
9
9
|
const SkeletonControl_1 = require("./SkeletonControl");
|
|
10
|
-
function SelectControl({ value, onChange, options, id, name, disabled, onBlur, onFocus, placeholder, skeleton, clearable, }) {
|
|
10
|
+
function SelectControl({ value, onChange, options, id, name, disabled, onBlur, onFocus, placeholder, skeleton, clearable, size, }) {
|
|
11
11
|
const transformedOptions = (0, react_1.useMemo)(() => options.map((x) => ({ label: x.label, value: String(x.value) })), [options]);
|
|
12
12
|
const handleChange = (value) => {
|
|
13
13
|
const option = options.find((x) => String(x.value) === value);
|
|
@@ -22,7 +22,7 @@ function SelectControl({ value, onChange, options, id, name, disabled, onBlur, o
|
|
|
22
22
|
if (skeleton) {
|
|
23
23
|
return (0, jsx_runtime_1.jsx)(SkeletonControl_1.SkeletonControl, {});
|
|
24
24
|
}
|
|
25
|
-
return ((0, jsx_runtime_1.jsx)(fluent_1.Dropdown, { placeholder: placeholder, id: id, name: name, appearance: "filled-darker",
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(fluent_1.Dropdown, { placeholder: placeholder, id: id, name: name, appearance: "filled-darker", size: size,
|
|
26
26
|
// data={transformedOptions}
|
|
27
27
|
value: selectedOption?.label ?? '',
|
|
28
28
|
// onChange={(e, v) => handleChange(v as string)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@headless-adminapp/fluent",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.31",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/lodash": "4.17.20"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "3c6a0b0fc245e8d9c6a4cb6811cbba079dfa5146"
|
|
58
58
|
}
|