@webiny/app-admin 6.5.0-beta.4 → 6.5.0-beta.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/base/Base/FieldRenderers/HorizontalTabsRenderer.d.ts +2 -2
- package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.d.ts +2 -2
- package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone/MultiValueDynamicZone.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.d.ts +8 -4
- package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.d.ts +2 -2
- package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/{TemplatePicker.d.ts → TemplatePicker/AddTemplateButton.d.ts} +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.js +24 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/AddTemplateButton.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.d.ts +13 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.js +21 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/SelectableTemplate.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.d.ts +3 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.js +35 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateCard.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.d.ts +8 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.js +22 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGallery.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.d.ts +10 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.js +46 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateGalleryToolbar.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.d.ts +8 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.js +16 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateIcon.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.d.ts +10 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.js +22 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateList.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.d.ts +3 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.js +35 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/TemplateListItem.js.map +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/index.d.ts +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/index.js +1 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/types.d.ts +6 -0
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker/types.js +0 -0
- package/base/Base/FieldRenderers/VerticalTabsRenderer.d.ts +2 -2
- package/components/IconPicker/IconPickerComponent.d.ts +2 -2
- package/components/IconPicker/IconPickerComponent.js +1 -1
- package/components/IconPicker/IconPickerComponent.js.map +1 -1
- package/components/ListView/ListViewBulkActions.d.ts +2 -2
- package/components/ListView/ListViewContent.d.ts +2 -2
- package/components/ListView/ListViewFilters.d.ts +2 -2
- package/components/ListView/index.d.ts +6 -6
- package/components/RolesMultiAutocomplete/index.js +1 -1
- package/components/RolesMultiAutocomplete/index.js.map +1 -1
- package/components/Table/components/Table/TableInner.d.ts +2 -2
- package/components/TeamsMultiAutocomplete/index.js +1 -1
- package/components/TeamsMultiAutocomplete/index.js.map +1 -1
- package/domain/Identity.js +1 -1
- package/domain/Identity.js.map +1 -1
- package/features/debugger/Debugger.d.ts +2 -2
- package/features/debugger/DebuggerIndicator.d.ts +2 -2
- package/features/debugger/DebuggerView.d.ts +2 -2
- package/features/formModel/FieldBuilder.test.js +13 -0
- package/features/formModel/FieldBuilder.test.js.map +1 -1
- package/features/formModel/FormErrors.d.ts +2 -2
- package/features/formModel/FormModel.test.js +205 -2
- package/features/formModel/FormModel.test.js.map +1 -1
- package/features/formModel/FormView.d.ts +8 -4
- package/features/formModel/ObjectField.d.ts +2 -0
- package/features/formModel/ObjectField.js +19 -3
- package/features/formModel/ObjectField.js.map +1 -1
- package/features/formModel/PresenterErrors.d.ts +2 -2
- package/features/formModel/abstractions.d.ts +16 -0
- package/features/formModel/abstractions.js.map +1 -1
- package/features/formModel/demo/FormModelDemo.d.ts +2 -2
- package/features/formModel/fieldTypes/DateTimeFieldType.js +5 -4
- package/features/formModel/fieldTypes/DateTimeFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/ObjectFieldType.d.ts +3 -1
- package/features/formModel/fieldTypes/ObjectFieldType.js +23 -1
- package/features/formModel/fieldTypes/ObjectFieldType.js.map +1 -1
- package/features/notifications/NotificationsRenderer.d.ts +2 -2
- package/hooks/useSnackbar.js.map +1 -1
- package/package.json +34 -34
- package/presentation/accessManagement/apiKeys/ApiKeysPresenter.js +1 -2
- package/presentation/accessManagement/apiKeys/ApiKeysPresenter.js.map +1 -1
- package/presentation/accessManagement/apiKeys/components/ApiKeysView.d.ts +2 -2
- package/presentation/accessManagement/roles/RolesPresenter.js +1 -2
- package/presentation/accessManagement/roles/RolesPresenter.js.map +1 -1
- package/presentation/accessManagement/roles/components/RolesView.d.ts +2 -2
- package/presentation/accessManagement/teams/TeamsPresenter.js +1 -2
- package/presentation/accessManagement/teams/TeamsPresenter.js.map +1 -1
- package/presentation/accessManagement/teams/components/TeamsView.d.ts +2 -2
- package/presentation/installation/components/SystemInstaller/SystemInstaller.d.ts +2 -2
- package/presentation/listPresenter/QueryMatcher.js +3 -3
- package/presentation/listPresenter/QueryMatcher.js.map +1 -1
- package/presentation/trashBin/components/BulkActions/DeleteItems.d.ts +2 -2
- package/presentation/trashBin/components/BulkActions/RestoreItems.d.ts +2 -2
- package/presentation/trashBin/components/TrashBinOverlay.d.ts +2 -2
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js +0 -68
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AddTemplateButton, type AddTemplateButtonProps } from "./AddTemplateButton.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AddTemplateButton } from "./AddTemplateButton.js";
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { TabsNodeRendererProps } from "../../../features/formModel/FormView.js";
|
|
3
|
-
export declare const VerticalTabsRenderer: (({ node }: TabsNodeRendererProps) => React.JSX.Element) & {
|
|
4
|
-
|
|
3
|
+
export declare const VerticalTabsRenderer: (({ node }: TabsNodeRendererProps) => React.JSX.Element) & React.NamedExoticComponent<TabsNodeRendererProps> & {
|
|
4
|
+
readonly type: ({ node }: TabsNodeRendererProps) => React.JSX.Element;
|
|
5
5
|
};
|
|
@@ -12,6 +12,6 @@ export interface IconPickerProps extends FormComponentProps {
|
|
|
12
12
|
export interface IconPickerComponentProps extends IconPickerProps {
|
|
13
13
|
presenter: IconPickerPresenter;
|
|
14
14
|
}
|
|
15
|
-
export declare const IconPickerComponent: (({ presenter, label, description, removable, required, disabled, ...props }: IconPickerComponentProps) => React.JSX.Element) & {
|
|
16
|
-
|
|
15
|
+
export declare const IconPickerComponent: (({ presenter, label, description, removable, required, disabled, ...props }: IconPickerComponentProps) => React.JSX.Element) & React.NamedExoticComponent<IconPickerComponentProps> & {
|
|
16
|
+
readonly type: ({ presenter, label, description, removable, required, disabled, ...props }: IconPickerComponentProps) => React.JSX.Element;
|
|
17
17
|
};
|
|
@@ -27,7 +27,7 @@ const IconPickerComponent = observer(({ presenter, label, description, removable
|
|
|
27
27
|
]);
|
|
28
28
|
const handleOnOpenChange = useCallback((open)=>{
|
|
29
29
|
if (open) return presenter.openMenu();
|
|
30
|
-
return presenter.closeMenu();
|
|
30
|
+
else return presenter.closeMenu();
|
|
31
31
|
}, [
|
|
32
32
|
presenter.openMenu,
|
|
33
33
|
presenter.closeMenu
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/IconPicker/IconPickerComponent.js","sources":["../../../src/components/IconPicker/IconPickerComponent.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useMemo } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport isEqual from \"lodash/isEqual.js\";\nimport type { FormComponentProps } from \"@webiny/admin-ui\";\nimport {\n FormComponentDescription,\n FormComponentErrorMessage,\n FormComponentLabel,\n PopoverPrimitive\n} from \"@webiny/admin-ui\";\nimport { IconPickerContent, IconPickerTrigger } from \"./components/index.js\";\nimport type { IconPickerPresenter } from \"./IconPickerPresenter.js\";\nimport { IconPickerPresenterProvider } from \"./IconPickerPresenterProvider.js\";\nimport type { Icon } from \"./types.js\";\nimport { ICON_PICKER_SIZE } from \"./types.js\";\n\nexport interface IconPickerProps extends FormComponentProps {\n size?: ICON_PICKER_SIZE;\n removable?: boolean;\n value?: Icon;\n onChange?: (value: Icon | undefined) => void;\n}\n\nexport interface IconPickerComponentProps extends IconPickerProps {\n presenter: IconPickerPresenter;\n}\n\nexport const IconPickerComponent = observer(\n ({\n presenter,\n label,\n description,\n removable,\n required,\n disabled,\n ...props\n }: IconPickerComponentProps) => {\n const { value, onChange } = props;\n const { isValid: validationIsValid, message: validationMessage } = props.validation || {};\n const invalid = useMemo(() => validationIsValid === false, [validationIsValid]);\n const { activeTab, isMenuOpened, isLoading, iconTypes, selectedIcon, size } = presenter.vm;\n\n useEffect(() => {\n if (onChange && selectedIcon && !isEqual(selectedIcon, value)) {\n onChange(selectedIcon);\n }\n }, [JSON.stringify(selectedIcon)]);\n\n const removeIcon = useCallback(() => {\n if (onChange) {\n presenter.setIcon(null);\n onChange(undefined);\n }\n }, [onChange]);\n\n const handleOnOpenChange = useCallback(\n (open: boolean) => {\n if (open) {\n return presenter.openMenu();\n } else {\n return presenter.closeMenu();\n }\n },\n [presenter.openMenu, presenter.closeMenu]\n );\n\n return (\n <IconPickerPresenterProvider presenter={presenter}>\n <FormComponentLabel text={label} required={required} disabled={disabled} />\n <FormComponentDescription text={description} />\n <PopoverPrimitive open={isMenuOpened} onOpenChange={handleOnOpenChange}>\n <PopoverPrimitive.Trigger>\n <IconPickerTrigger icon={selectedIcon} />\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Content\n style={{ width: size === ICON_PICKER_SIZE.SMALL ? \"248px\" : \"328px\" }}\n >\n <IconPickerContent\n loading={isLoading}\n removable={value && removable}\n iconTypes={iconTypes}\n activeTab={activeTab}\n removeIcon={removeIcon}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n <FormComponentErrorMessage text={validationMessage} invalid={invalid} />\n </IconPickerPresenterProvider>\n );\n }\n);\n"],"names":["IconPickerComponent","observer","presenter","label","description","removable","required","disabled","props","value","onChange","validationIsValid","validationMessage","invalid","useMemo","activeTab","isMenuOpened","isLoading","iconTypes","selectedIcon","size","useEffect","isEqual","JSON","removeIcon","useCallback","undefined","handleOnOpenChange","open","IconPickerPresenterProvider","FormComponentLabel","FormComponentDescription","PopoverPrimitive","IconPickerTrigger","ICON_PICKER_SIZE","IconPickerContent","FormComponentErrorMessage"],"mappings":";;;;;;;AA2BO,MAAMA,sBAAsBC,SAC/B,CAAC,EACGC,SAAS,EACTC,KAAK,EACLC,WAAW,EACXC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACR,GAAGC,OACoB;IACvB,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IAC5B,MAAM,EAAE,SAASG,iBAAiB,EAAE,SAASC,iBAAiB,EAAE,GAAGJ,MAAM,UAAU,IAAI,CAAC;IACxF,MAAMK,UAAUC,QAAQ,IAAMH,AAAsB,UAAtBA,mBAA6B;QAACA;KAAkB;IAC9E,MAAM,EAAEI,SAAS,EAAEC,YAAY,EAAEC,SAAS,EAAEC,SAAS,EAAEC,YAAY,EAAEC,IAAI,EAAE,GAAGlB,UAAU,EAAE;IAE1FmB,UAAU;QACN,IAAIX,YAAYS,gBAAgB,CAACG,QAAQH,cAAcV,QACnDC,SAASS;IAEjB,GAAG;QAACI,KAAK,SAAS,CAACJ;KAAc;IAEjC,MAAMK,aAAaC,YAAY;QAC3B,IAAIf,UAAU;YACVR,UAAU,OAAO,CAAC;YAClBQ,SAASgB;QACb;IACJ,GAAG;QAAChB;KAAS;IAEb,MAAMiB,qBAAqBF,YACvB,CAACG;QACG,IAAIA,MACA,OAAO1B,UAAU,QAAQ;
|
|
1
|
+
{"version":3,"file":"components/IconPicker/IconPickerComponent.js","sources":["../../../src/components/IconPicker/IconPickerComponent.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useMemo } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport isEqual from \"lodash/isEqual.js\";\nimport type { FormComponentProps } from \"@webiny/admin-ui\";\nimport {\n FormComponentDescription,\n FormComponentErrorMessage,\n FormComponentLabel,\n PopoverPrimitive\n} from \"@webiny/admin-ui\";\nimport { IconPickerContent, IconPickerTrigger } from \"./components/index.js\";\nimport type { IconPickerPresenter } from \"./IconPickerPresenter.js\";\nimport { IconPickerPresenterProvider } from \"./IconPickerPresenterProvider.js\";\nimport type { Icon } from \"./types.js\";\nimport { ICON_PICKER_SIZE } from \"./types.js\";\n\nexport interface IconPickerProps extends FormComponentProps {\n size?: ICON_PICKER_SIZE;\n removable?: boolean;\n value?: Icon;\n onChange?: (value: Icon | undefined) => void;\n}\n\nexport interface IconPickerComponentProps extends IconPickerProps {\n presenter: IconPickerPresenter;\n}\n\nexport const IconPickerComponent = observer(\n ({\n presenter,\n label,\n description,\n removable,\n required,\n disabled,\n ...props\n }: IconPickerComponentProps) => {\n const { value, onChange } = props;\n const { isValid: validationIsValid, message: validationMessage } = props.validation || {};\n const invalid = useMemo(() => validationIsValid === false, [validationIsValid]);\n const { activeTab, isMenuOpened, isLoading, iconTypes, selectedIcon, size } = presenter.vm;\n\n useEffect(() => {\n if (onChange && selectedIcon && !isEqual(selectedIcon, value)) {\n onChange(selectedIcon);\n }\n }, [JSON.stringify(selectedIcon)]);\n\n const removeIcon = useCallback(() => {\n if (onChange) {\n presenter.setIcon(null);\n onChange(undefined);\n }\n }, [onChange]);\n\n const handleOnOpenChange = useCallback(\n (open: boolean) => {\n if (open) {\n return presenter.openMenu();\n } else {\n return presenter.closeMenu();\n }\n },\n [presenter.openMenu, presenter.closeMenu]\n );\n\n return (\n <IconPickerPresenterProvider presenter={presenter}>\n <FormComponentLabel text={label} required={required} disabled={disabled} />\n <FormComponentDescription text={description} />\n <PopoverPrimitive open={isMenuOpened} onOpenChange={handleOnOpenChange}>\n <PopoverPrimitive.Trigger>\n <IconPickerTrigger icon={selectedIcon} />\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Content\n style={{ width: size === ICON_PICKER_SIZE.SMALL ? \"248px\" : \"328px\" }}\n >\n <IconPickerContent\n loading={isLoading}\n removable={value && removable}\n iconTypes={iconTypes}\n activeTab={activeTab}\n removeIcon={removeIcon}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n <FormComponentErrorMessage text={validationMessage} invalid={invalid} />\n </IconPickerPresenterProvider>\n );\n }\n);\n"],"names":["IconPickerComponent","observer","presenter","label","description","removable","required","disabled","props","value","onChange","validationIsValid","validationMessage","invalid","useMemo","activeTab","isMenuOpened","isLoading","iconTypes","selectedIcon","size","useEffect","isEqual","JSON","removeIcon","useCallback","undefined","handleOnOpenChange","open","IconPickerPresenterProvider","FormComponentLabel","FormComponentDescription","PopoverPrimitive","IconPickerTrigger","ICON_PICKER_SIZE","IconPickerContent","FormComponentErrorMessage"],"mappings":";;;;;;;AA2BO,MAAMA,sBAAsBC,SAC/B,CAAC,EACGC,SAAS,EACTC,KAAK,EACLC,WAAW,EACXC,SAAS,EACTC,QAAQ,EACRC,QAAQ,EACR,GAAGC,OACoB;IACvB,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IAC5B,MAAM,EAAE,SAASG,iBAAiB,EAAE,SAASC,iBAAiB,EAAE,GAAGJ,MAAM,UAAU,IAAI,CAAC;IACxF,MAAMK,UAAUC,QAAQ,IAAMH,AAAsB,UAAtBA,mBAA6B;QAACA;KAAkB;IAC9E,MAAM,EAAEI,SAAS,EAAEC,YAAY,EAAEC,SAAS,EAAEC,SAAS,EAAEC,YAAY,EAAEC,IAAI,EAAE,GAAGlB,UAAU,EAAE;IAE1FmB,UAAU;QACN,IAAIX,YAAYS,gBAAgB,CAACG,QAAQH,cAAcV,QACnDC,SAASS;IAEjB,GAAG;QAACI,KAAK,SAAS,CAACJ;KAAc;IAEjC,MAAMK,aAAaC,YAAY;QAC3B,IAAIf,UAAU;YACVR,UAAU,OAAO,CAAC;YAClBQ,SAASgB;QACb;IACJ,GAAG;QAAChB;KAAS;IAEb,MAAMiB,qBAAqBF,YACvB,CAACG;QACG,IAAIA,MACA,OAAO1B,UAAU,QAAQ;aAEzB,OAAOA,UAAU,SAAS;IAElC,GACA;QAACA,UAAU,QAAQ;QAAEA,UAAU,SAAS;KAAC;IAG7C,OAAO,WAAP,GACI,oBAAC2B,6BAA2BA;QAAC,WAAW3B;qBACpC,oBAAC4B,oBAAkBA;QAAC,MAAM3B;QAAO,UAAUG;QAAU,UAAUC;sBAC/D,oBAACwB,0BAAwBA;QAAC,MAAM3B;sBAChC,oBAAC4B,kBAAgBA;QAAC,MAAMhB;QAAc,cAAcW;qBAChD,oBAACK,iBAAiB,OAAO,sBACrB,oBAACC,mBAAiBA;QAAC,MAAMd;uBAE7B,oBAACa,iBAAiB,OAAO;QACrB,OAAO;YAAE,OAAOZ,SAASc,iBAAiB,KAAK,GAAG,UAAU;QAAQ;qBAEpE,oBAACC,mBAAiBA;QACd,SAASlB;QACT,WAAWR,SAASJ;QACpB,WAAWa;QACX,WAAWH;QACX,YAAYS;wBAIxB,oBAACY,2BAAyBA;QAAC,MAAMxB;QAAmB,SAASC;;AAGzE"}
|
|
@@ -5,7 +5,7 @@ export interface ListViewBulkActionsProps {
|
|
|
5
5
|
itemLabelPlural?: string;
|
|
6
6
|
actions: React.ComponentProps<typeof Buttons>["actions"];
|
|
7
7
|
}
|
|
8
|
-
declare const ListViewBulkActions: (({ itemLabel, itemLabelPlural, actions: bulkActions }: ListViewBulkActionsProps) => React.JSX.Element) & {
|
|
9
|
-
|
|
8
|
+
declare const ListViewBulkActions: (({ itemLabel, itemLabelPlural, actions: bulkActions }: ListViewBulkActionsProps) => React.JSX.Element) & React.NamedExoticComponent<ListViewBulkActionsProps> & {
|
|
9
|
+
readonly type: ({ itemLabel, itemLabelPlural, actions: bulkActions }: ListViewBulkActionsProps) => React.JSX.Element;
|
|
10
10
|
};
|
|
11
11
|
export { ListViewBulkActions };
|
|
@@ -6,7 +6,7 @@ export interface ListViewContentProps {
|
|
|
6
6
|
searchEmpty?: React.ReactNode;
|
|
7
7
|
children: React.ReactNode;
|
|
8
8
|
}
|
|
9
|
-
declare const ListViewContent: (({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: ListViewContentProps) => React.JSX.Element) & {
|
|
10
|
-
|
|
9
|
+
declare const ListViewContent: (({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: ListViewContentProps) => React.JSX.Element) & React.NamedExoticComponent<ListViewContentProps> & {
|
|
10
|
+
readonly type: ({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: ListViewContentProps) => React.JSX.Element;
|
|
11
11
|
};
|
|
12
12
|
export { ListViewContent };
|
|
@@ -9,7 +9,7 @@ export interface ListViewFiltersProps {
|
|
|
9
9
|
filtersToWhere?: FiltersToWhereConverter[];
|
|
10
10
|
children?: React.ReactNode;
|
|
11
11
|
}
|
|
12
|
-
declare const ListViewFilters: (({ filters, filtersToWhere, children }: ListViewFiltersProps) => React.JSX.Element) & {
|
|
13
|
-
|
|
12
|
+
declare const ListViewFilters: (({ filters, filtersToWhere, children }: ListViewFiltersProps) => React.JSX.Element) & React.NamedExoticComponent<ListViewFiltersProps> & {
|
|
13
|
+
readonly type: ({ filters, filtersToWhere, children }: ListViewFiltersProps) => React.JSX.Element;
|
|
14
14
|
};
|
|
15
15
|
export { ListViewFilters };
|
|
@@ -8,14 +8,14 @@ export declare const ListView: typeof ListViewBase & {
|
|
|
8
8
|
};
|
|
9
9
|
Header: typeof ListViewHeader;
|
|
10
10
|
BottomBar: typeof ListViewBottomBar;
|
|
11
|
-
BulkActions: (({ itemLabel, itemLabelPlural, actions: bulkActions }: import("./ListViewBulkActions.js").ListViewBulkActionsProps) => import("react").JSX.Element) & {
|
|
12
|
-
|
|
11
|
+
BulkActions: (({ itemLabel, itemLabelPlural, actions: bulkActions }: import("./ListViewBulkActions.js").ListViewBulkActionsProps) => import("react").JSX.Element) & import("react").NamedExoticComponent<import("./ListViewBulkActions.js").ListViewBulkActionsProps> & {
|
|
12
|
+
readonly type: ({ itemLabel, itemLabelPlural, actions: bulkActions }: import("./ListViewBulkActions.js").ListViewBulkActionsProps) => import("react").JSX.Element;
|
|
13
13
|
};
|
|
14
|
-
Filters: (({ filters, filtersToWhere, children }: import("./ListViewFilters.js").ListViewFiltersProps) => import("react").JSX.Element) & {
|
|
15
|
-
|
|
14
|
+
Filters: (({ filters, filtersToWhere, children }: import("./ListViewFilters.js").ListViewFiltersProps) => import("react").JSX.Element) & import("react").NamedExoticComponent<import("./ListViewFilters.js").ListViewFiltersProps> & {
|
|
15
|
+
readonly type: ({ filters, filtersToWhere, children }: import("./ListViewFilters.js").ListViewFiltersProps) => import("react").JSX.Element;
|
|
16
16
|
};
|
|
17
|
-
Content: (({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: import("./ListViewContent.js").ListViewContentProps) => import("react").JSX.Element) & {
|
|
18
|
-
|
|
17
|
+
Content: (({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: import("./ListViewContent.js").ListViewContentProps) => import("react").JSX.Element) & import("react").NamedExoticComponent<import("./ListViewContent.js").ListViewContentProps> & {
|
|
18
|
+
readonly type: ({ loadMoreThreshold, loadMoreDebounceMs, empty, searchEmpty, children }: import("./ListViewContent.js").ListViewContentProps) => import("react").JSX.Element;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
export { useListView } from "./context.js";
|
|
@@ -18,7 +18,7 @@ const RolesMultiAutocomplete = ({ onChange, ...props })=>{
|
|
|
18
18
|
const selected = Array.isArray(props.values) ? props.values : Array.isArray(props.value) ? props.value : [];
|
|
19
19
|
return selected.map((s)=>{
|
|
20
20
|
if ("string" == typeof s) return s;
|
|
21
|
-
if ("object" == typeof s) return s?.id;
|
|
21
|
+
else if ("object" == typeof s) return s?.id;
|
|
22
22
|
return null;
|
|
23
23
|
}).filter((s)=>!!s);
|
|
24
24
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/RolesMultiAutocomplete/index.js","sources":["../../../src/components/RolesMultiAutocomplete/index.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { MultiAutoComplete } from \"@webiny/admin-ui\";\nimport { LIST_ROLES } from \"./graphql.js\";\nimport { useQuery } from \"@apollo/react-hooks\";\n\ntype RolesMultiAutocompleteProps = Omit<\n React.ComponentProps<typeof MultiAutoComplete>,\n \"options\" | \"onValuesChange\"\n> & {\n onChange?: (values: string[]) => void;\n};\n\nexport const RolesMultiAutocomplete = ({ onChange, ...props }: RolesMultiAutocompleteProps) => {\n const { data, loading } = useQuery(LIST_ROLES);\n const rawOptions = loading || !data ? [] : data.security.roles.data;\n\n const options = useMemo(\n () => rawOptions.map((role: any) => ({ label: role.name, value: role.id })),\n [rawOptions]\n );\n\n const onValuesChange = useCallback((ids: string[]) => onChange?.(ids), [onChange]);\n\n /**\n * This is required because the Bind, which currently wraps this component passes \"values\" as \"value\" prop, not \"values\".\n * \"values\" is added to safeguard for future changes. When we move to new forms, remove this part.\n */\n const values = useMemo(() => {\n const selected = Array.isArray(props.values)\n ? props.values\n : Array.isArray(props.value)\n ? props.value\n : [];\n\n return selected\n .map(s => {\n if (typeof s === \"string\") {\n return s;\n } else if (typeof s === \"object\") {\n return s?.id;\n }\n return null;\n })\n .filter((s): s is string => !!s);\n }, [props.values, props.value]);\n\n return (\n <MultiAutoComplete\n {...props}\n options={options}\n values={loading ? undefined : (values as string[] | undefined)}\n onValuesChange={onValuesChange}\n />\n );\n};\n"],"names":["RolesMultiAutocomplete","onChange","props","data","loading","useQuery","LIST_ROLES","rawOptions","options","useMemo","role","onValuesChange","useCallback","ids","values","selected","Array","s","MultiAutoComplete","undefined"],"mappings":";;;;AAYO,MAAMA,yBAAyB,CAAC,EAAEC,QAAQ,EAAE,GAAGC,OAAoC;IACtF,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAE,GAAGC,SAASC;IACnC,MAAMC,aAAaH,WAAW,CAACD,OAAO,EAAE,GAAGA,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI;IAEnE,MAAMK,UAAUC,QACZ,IAAMF,WAAW,GAAG,CAAC,CAACG,OAAe;gBAAE,OAAOA,KAAK,IAAI;gBAAE,OAAOA,KAAK,EAAE;YAAC,KACxE;QAACH;KAAW;IAGhB,MAAMI,iBAAiBC,YAAY,CAACC,MAAkBZ,WAAWY,MAAM;QAACZ;KAAS;IAMjF,MAAMa,SAASL,QAAQ;QACnB,MAAMM,WAAWC,MAAM,OAAO,CAACd,MAAM,MAAM,IACrCA,MAAM,MAAM,GACZc,MAAM,OAAO,CAACd,MAAM,KAAK,IACvBA,MAAM,KAAK,GACX,EAAE;QAEV,OAAOa,SACF,GAAG,CAACE,CAAAA;YACD,IAAI,AAAa,YAAb,OAAOA,GACP,OAAOA;
|
|
1
|
+
{"version":3,"file":"components/RolesMultiAutocomplete/index.js","sources":["../../../src/components/RolesMultiAutocomplete/index.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { MultiAutoComplete } from \"@webiny/admin-ui\";\nimport { LIST_ROLES } from \"./graphql.js\";\nimport { useQuery } from \"@apollo/react-hooks\";\n\ntype RolesMultiAutocompleteProps = Omit<\n React.ComponentProps<typeof MultiAutoComplete>,\n \"options\" | \"onValuesChange\"\n> & {\n onChange?: (values: string[]) => void;\n};\n\nexport const RolesMultiAutocomplete = ({ onChange, ...props }: RolesMultiAutocompleteProps) => {\n const { data, loading } = useQuery(LIST_ROLES);\n const rawOptions = loading || !data ? [] : data.security.roles.data;\n\n const options = useMemo(\n () => rawOptions.map((role: any) => ({ label: role.name, value: role.id })),\n [rawOptions]\n );\n\n const onValuesChange = useCallback((ids: string[]) => onChange?.(ids), [onChange]);\n\n /**\n * This is required because the Bind, which currently wraps this component passes \"values\" as \"value\" prop, not \"values\".\n * \"values\" is added to safeguard for future changes. When we move to new forms, remove this part.\n */\n const values = useMemo(() => {\n const selected = Array.isArray(props.values)\n ? props.values\n : Array.isArray(props.value)\n ? props.value\n : [];\n\n return selected\n .map(s => {\n if (typeof s === \"string\") {\n return s;\n } else if (typeof s === \"object\") {\n return s?.id;\n }\n return null;\n })\n .filter((s): s is string => !!s);\n }, [props.values, props.value]);\n\n return (\n <MultiAutoComplete\n {...props}\n options={options}\n values={loading ? undefined : (values as string[] | undefined)}\n onValuesChange={onValuesChange}\n />\n );\n};\n"],"names":["RolesMultiAutocomplete","onChange","props","data","loading","useQuery","LIST_ROLES","rawOptions","options","useMemo","role","onValuesChange","useCallback","ids","values","selected","Array","s","MultiAutoComplete","undefined"],"mappings":";;;;AAYO,MAAMA,yBAAyB,CAAC,EAAEC,QAAQ,EAAE,GAAGC,OAAoC;IACtF,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAE,GAAGC,SAASC;IACnC,MAAMC,aAAaH,WAAW,CAACD,OAAO,EAAE,GAAGA,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI;IAEnE,MAAMK,UAAUC,QACZ,IAAMF,WAAW,GAAG,CAAC,CAACG,OAAe;gBAAE,OAAOA,KAAK,IAAI;gBAAE,OAAOA,KAAK,EAAE;YAAC,KACxE;QAACH;KAAW;IAGhB,MAAMI,iBAAiBC,YAAY,CAACC,MAAkBZ,WAAWY,MAAM;QAACZ;KAAS;IAMjF,MAAMa,SAASL,QAAQ;QACnB,MAAMM,WAAWC,MAAM,OAAO,CAACd,MAAM,MAAM,IACrCA,MAAM,MAAM,GACZc,MAAM,OAAO,CAACd,MAAM,KAAK,IACvBA,MAAM,KAAK,GACX,EAAE;QAEV,OAAOa,SACF,GAAG,CAACE,CAAAA;YACD,IAAI,AAAa,YAAb,OAAOA,GACP,OAAOA;iBACJ,IAAI,AAAa,YAAb,OAAOA,GACd,OAAOA,GAAG;YAEd,OAAO;QACX,GACC,MAAM,CAAC,CAACA,IAAmB,CAAC,CAACA;IACtC,GAAG;QAACf,MAAM,MAAM;QAAEA,MAAM,KAAK;KAAC;IAE9B,OAAO,WAAP,GACI,oBAACgB,mBAAiBA;QACb,GAAGhB,KAAK;QACT,SAASM;QACT,QAAQJ,UAAUe,SAAaL;QAC/B,gBAAgBH;;AAG5B"}
|
|
@@ -19,6 +19,6 @@ export interface TableInnerProps<T extends TableRow> {
|
|
|
19
19
|
sorting: DataTableSorting;
|
|
20
20
|
tablePresenter: TablePresenter;
|
|
21
21
|
}
|
|
22
|
-
export declare const TableInner: (<T extends TableRow>(props: TableInnerProps<T>) => React.JSX.Element) & {
|
|
23
|
-
|
|
22
|
+
export declare const TableInner: (<T extends TableRow>(props: TableInnerProps<T>) => React.JSX.Element) & React.NamedExoticComponent<TableInnerProps<TableRow<unknown>>> & {
|
|
23
|
+
readonly type: <T extends TableRow>(props: TableInnerProps<T>) => React.JSX.Element;
|
|
24
24
|
};
|
|
@@ -18,7 +18,7 @@ const TeamsMultiAutocomplete = ({ onChange, ...props })=>{
|
|
|
18
18
|
const selected = Array.isArray(props.values) ? props.values : Array.isArray(props.value) ? props.value : [];
|
|
19
19
|
return selected.map((s)=>{
|
|
20
20
|
if ("string" == typeof s) return s;
|
|
21
|
-
if ("object" == typeof s) return s?.id;
|
|
21
|
+
else if ("object" == typeof s) return s?.id;
|
|
22
22
|
return null;
|
|
23
23
|
}).filter((s)=>!!s);
|
|
24
24
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/TeamsMultiAutocomplete/index.js","sources":["../../../src/components/TeamsMultiAutocomplete/index.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { MultiAutoComplete } from \"@webiny/admin-ui\";\nimport { LIST_TEAMS } from \"./graphql.js\";\nimport { useQuery } from \"@apollo/react-hooks\";\n\ntype TeamsMultiAutocompleteProps = Omit<\n React.ComponentProps<typeof MultiAutoComplete>,\n \"options\" | \"onValuesChange\"\n> & {\n onChange?: (values: string[]) => void;\n};\n\nexport const TeamsMultiAutocomplete = ({ onChange, ...props }: TeamsMultiAutocompleteProps) => {\n const { data, loading } = useQuery(LIST_TEAMS);\n const rawOptions = loading || !data?.security?.teams?.data ? [] : data.security.teams.data;\n\n const options = useMemo(\n () => rawOptions.map((team: any) => ({ label: team.name, value: team.id })),\n [rawOptions]\n );\n\n const onValuesChange = useCallback((ids: string[]) => onChange?.(ids), [onChange]);\n /**\n * This is required because the Bind, which currently wraps this component passes \"values\" as \"value\" prop, not \"values\".\n * \"values\" is added to safeguard for future changes. When we move to new forms, remove this part.\n */\n const values = useMemo(() => {\n const selected = Array.isArray(props.values)\n ? props.values\n : Array.isArray(props.value)\n ? props.value\n : [];\n\n return selected\n .map(s => {\n if (typeof s === \"string\") {\n return s;\n } else if (typeof s === \"object\") {\n return s?.id;\n }\n return null;\n })\n .filter((s): s is string => !!s);\n }, [props.values, props.value]);\n\n return (\n <MultiAutoComplete\n uniqueValues\n {...props}\n options={options}\n values={loading ? undefined : (values as string[] | undefined)}\n onValuesChange={onValuesChange}\n />\n );\n};\n"],"names":["TeamsMultiAutocomplete","onChange","props","data","loading","useQuery","LIST_TEAMS","rawOptions","options","useMemo","team","onValuesChange","useCallback","ids","values","selected","Array","s","MultiAutoComplete","undefined"],"mappings":";;;;AAYO,MAAMA,yBAAyB,CAAC,EAAEC,QAAQ,EAAE,GAAGC,OAAoC;IACtF,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAE,GAAGC,SAASC;IACnC,MAAMC,aAAaH,WAAW,CAACD,MAAM,UAAU,OAAO,OAAO,EAAE,GAAGA,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI;IAE1F,MAAMK,UAAUC,QACZ,IAAMF,WAAW,GAAG,CAAC,CAACG,OAAe;gBAAE,OAAOA,KAAK,IAAI;gBAAE,OAAOA,KAAK,EAAE;YAAC,KACxE;QAACH;KAAW;IAGhB,MAAMI,iBAAiBC,YAAY,CAACC,MAAkBZ,WAAWY,MAAM;QAACZ;KAAS;IAKjF,MAAMa,SAASL,QAAQ;QACnB,MAAMM,WAAWC,MAAM,OAAO,CAACd,MAAM,MAAM,IACrCA,MAAM,MAAM,GACZc,MAAM,OAAO,CAACd,MAAM,KAAK,IACvBA,MAAM,KAAK,GACX,EAAE;QAEV,OAAOa,SACF,GAAG,CAACE,CAAAA;YACD,IAAI,AAAa,YAAb,OAAOA,GACP,OAAOA;
|
|
1
|
+
{"version":3,"file":"components/TeamsMultiAutocomplete/index.js","sources":["../../../src/components/TeamsMultiAutocomplete/index.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { MultiAutoComplete } from \"@webiny/admin-ui\";\nimport { LIST_TEAMS } from \"./graphql.js\";\nimport { useQuery } from \"@apollo/react-hooks\";\n\ntype TeamsMultiAutocompleteProps = Omit<\n React.ComponentProps<typeof MultiAutoComplete>,\n \"options\" | \"onValuesChange\"\n> & {\n onChange?: (values: string[]) => void;\n};\n\nexport const TeamsMultiAutocomplete = ({ onChange, ...props }: TeamsMultiAutocompleteProps) => {\n const { data, loading } = useQuery(LIST_TEAMS);\n const rawOptions = loading || !data?.security?.teams?.data ? [] : data.security.teams.data;\n\n const options = useMemo(\n () => rawOptions.map((team: any) => ({ label: team.name, value: team.id })),\n [rawOptions]\n );\n\n const onValuesChange = useCallback((ids: string[]) => onChange?.(ids), [onChange]);\n /**\n * This is required because the Bind, which currently wraps this component passes \"values\" as \"value\" prop, not \"values\".\n * \"values\" is added to safeguard for future changes. When we move to new forms, remove this part.\n */\n const values = useMemo(() => {\n const selected = Array.isArray(props.values)\n ? props.values\n : Array.isArray(props.value)\n ? props.value\n : [];\n\n return selected\n .map(s => {\n if (typeof s === \"string\") {\n return s;\n } else if (typeof s === \"object\") {\n return s?.id;\n }\n return null;\n })\n .filter((s): s is string => !!s);\n }, [props.values, props.value]);\n\n return (\n <MultiAutoComplete\n uniqueValues\n {...props}\n options={options}\n values={loading ? undefined : (values as string[] | undefined)}\n onValuesChange={onValuesChange}\n />\n );\n};\n"],"names":["TeamsMultiAutocomplete","onChange","props","data","loading","useQuery","LIST_TEAMS","rawOptions","options","useMemo","team","onValuesChange","useCallback","ids","values","selected","Array","s","MultiAutoComplete","undefined"],"mappings":";;;;AAYO,MAAMA,yBAAyB,CAAC,EAAEC,QAAQ,EAAE,GAAGC,OAAoC;IACtF,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAE,GAAGC,SAASC;IACnC,MAAMC,aAAaH,WAAW,CAACD,MAAM,UAAU,OAAO,OAAO,EAAE,GAAGA,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI;IAE1F,MAAMK,UAAUC,QACZ,IAAMF,WAAW,GAAG,CAAC,CAACG,OAAe;gBAAE,OAAOA,KAAK,IAAI;gBAAE,OAAOA,KAAK,EAAE;YAAC,KACxE;QAACH;KAAW;IAGhB,MAAMI,iBAAiBC,YAAY,CAACC,MAAkBZ,WAAWY,MAAM;QAACZ;KAAS;IAKjF,MAAMa,SAASL,QAAQ;QACnB,MAAMM,WAAWC,MAAM,OAAO,CAACd,MAAM,MAAM,IACrCA,MAAM,MAAM,GACZc,MAAM,OAAO,CAACd,MAAM,KAAK,IACvBA,MAAM,KAAK,GACX,EAAE;QAEV,OAAOa,SACF,GAAG,CAACE,CAAAA;YACD,IAAI,AAAa,YAAb,OAAOA,GACP,OAAOA;iBACJ,IAAI,AAAa,YAAb,OAAOA,GACd,OAAOA,GAAG;YAEd,OAAO;QACX,GACC,MAAM,CAAC,CAACA,IAAmB,CAAC,CAACA;IACtC,GAAG;QAACf,MAAM,MAAM;QAAEA,MAAM,KAAK;KAAC;IAE9B,OAAO,WAAP,GACI,oBAACgB,mBAAiBA;QACd;QACC,GAAGhB,KAAK;QACT,SAASM;QACT,QAAQJ,UAAUe,SAAaL;QAC/B,gBAAgBH;;AAG5B"}
|
package/domain/Identity.js
CHANGED
|
@@ -62,7 +62,7 @@ class Identity {
|
|
|
62
62
|
const perms = this.data.permissions || [];
|
|
63
63
|
const exactMatch = perms.find((p)=>p.name === name);
|
|
64
64
|
if (exactMatch) return exactMatch;
|
|
65
|
-
if (exact) return null;
|
|
65
|
+
else if (exact) return null;
|
|
66
66
|
return perms.find((p)=>minimatch(name, p.name)) || null;
|
|
67
67
|
}
|
|
68
68
|
getPermissions(name) {
|
package/domain/Identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/Identity.js","sources":["../../src/domain/Identity.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from \"mobx\";\nimport { minimatch } from \"minimatch\";\nimport type { Tenant } from \"~/features/tenancy/abstractions.js\";\n\nexport interface IPermission {\n name: string;\n [key: string]: any;\n}\n\nexport interface IRole {\n id: string;\n slug: string;\n name: string;\n}\n\nexport interface ITeam {\n id: string;\n slug: string;\n name: string;\n}\n\nexport interface IProfile {\n external: boolean;\n email?: string;\n firstName?: string;\n lastName?: string;\n avatar?: {\n src?: string;\n };\n}\n\nexport interface IdentityData {\n id: string;\n type: string;\n displayName: string;\n roles: IRole[];\n teams: ITeam[];\n permissions: Identity.Permission[];\n profile: Identity.Profile;\n currentTenant: Tenant;\n defaultTenant: Tenant;\n}\n\nconst anonymousData: IdentityData = {\n id: \"anonymous\",\n displayName: \"Anonymous\",\n type: \"admin\",\n roles: [],\n teams: [],\n permissions: [],\n profile: {\n external: false\n },\n currentTenant: {\n id: \"root\",\n name: \"Root\"\n },\n defaultTenant: {\n id: \"root\",\n name: \"Root\"\n }\n};\n\nexport class Identity {\n private constructor(\n private data: Identity.Data,\n private identityType: \"anonymous\" | \"authenticated\"\n ) {\n makeAutoObservable(this);\n }\n\n static createAuthenticated(data: Identity.Data) {\n return new Identity(data, \"authenticated\");\n }\n\n static createAnonymous() {\n return new Identity(anonymousData, \"anonymous\");\n }\n\n get isAuthenticated(): boolean {\n return this.identityType === \"authenticated\";\n }\n\n get id() {\n return this.data.id;\n }\n\n get type() {\n return this.data.type;\n }\n\n get displayName() {\n return this.data.displayName;\n }\n\n get roles() {\n return this.data.roles ?? [];\n }\n\n get teams() {\n return this.data.teams ?? [];\n }\n\n get profile() {\n return this.data.profile;\n }\n\n get currentTenant() {\n return this.data.currentTenant;\n }\n\n get defaultTenant() {\n return this.data.defaultTenant;\n }\n\n getPermission<T extends Identity.Permission = Identity.Permission>(\n name: string,\n exact?: boolean\n ): T | null {\n const perms = (this.data.permissions || []) as T[];\n const exactMatch = perms.find(p => p.name === name);\n if (exactMatch) {\n return exactMatch as T;\n } else if (exact) {\n return null;\n }\n\n // Try matching using patterns\n return perms.find(p => minimatch(name, p.name)) || null;\n }\n\n getPermissions<T extends Identity.Permission = Identity.Permission>(name?: string): Array<T> {\n const permissions = this.data.permissions || [];\n if (!name) {\n return permissions as T[];\n }\n\n return permissions.filter(current => {\n const exactMatch = current.name === name;\n if (exactMatch) {\n return true;\n }\n\n // Try matching using patterns.\n return minimatch(name, current.name);\n }) as T[];\n }\n\n update(updates: Partial<Pick<Identity.Data, \"displayName\" | \"profile\">>) {\n runInAction(() => {\n this.data.displayName = updates.displayName || this.data.displayName;\n this.data.profile = updates.profile || this.data.profile;\n });\n }\n}\n\nexport namespace Identity {\n export type Data = IdentityData;\n export type Permission = IPermission;\n export type Profile = IProfile;\n}\n"],"names":["anonymousData","Identity","data","identityType","makeAutoObservable","name","exact","perms","exactMatch","p","minimatch","permissions","current","updates","runInAction"],"mappings":";;AA2CA,MAAMA,gBAA8B;IAChC,IAAI;IACJ,aAAa;IACb,MAAM;IACN,OAAO,EAAE;IACT,OAAO,EAAE;IACT,aAAa,EAAE;IACf,SAAS;QACL,UAAU;IACd;IACA,eAAe;QACX,IAAI;QACJ,MAAM;IACV;IACA,eAAe;QACX,IAAI;QACJ,MAAM;IACV;AACJ;AAEO,MAAMC;IACT,YACYC,IAAmB,EACnBC,YAA2C,CACrD;aAFUD,IAAI,GAAJA;aACAC,YAAY,GAAZA;QAERC,mBAAmB,IAAI;IAC3B;IAEA,OAAO,oBAAoBF,IAAmB,EAAE;QAC5C,OAAO,IAAID,SAASC,MAAM;IAC9B;IAEA,OAAO,kBAAkB;QACrB,OAAO,IAAID,SAASD,eAAe;IACvC;IAEA,IAAI,kBAA2B;QAC3B,OAAO,AAAsB,oBAAtB,IAAI,CAAC,YAAY;IAC5B;IAEA,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE;IACvB;IAEA,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI;IACzB;IAEA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW;IAChC;IAEA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;IAChC;IAEA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;IAChC;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;IAC5B;IAEA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa;IAClC;IAEA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa;IAClC;IAEA,cACIK,IAAY,EACZC,KAAe,EACP;QACR,MAAMC,QAAS,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE;QAC1C,MAAMC,aAAaD,MAAM,IAAI,CAACE,CAAAA,IAAKA,EAAE,IAAI,KAAKJ;QAC9C,IAAIG,YACA,OAAOA;
|
|
1
|
+
{"version":3,"file":"domain/Identity.js","sources":["../../src/domain/Identity.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from \"mobx\";\nimport { minimatch } from \"minimatch\";\nimport type { Tenant } from \"~/features/tenancy/abstractions.js\";\n\nexport interface IPermission {\n name: string;\n [key: string]: any;\n}\n\nexport interface IRole {\n id: string;\n slug: string;\n name: string;\n}\n\nexport interface ITeam {\n id: string;\n slug: string;\n name: string;\n}\n\nexport interface IProfile {\n external: boolean;\n email?: string;\n firstName?: string;\n lastName?: string;\n avatar?: {\n src?: string;\n };\n}\n\nexport interface IdentityData {\n id: string;\n type: string;\n displayName: string;\n roles: IRole[];\n teams: ITeam[];\n permissions: Identity.Permission[];\n profile: Identity.Profile;\n currentTenant: Tenant;\n defaultTenant: Tenant;\n}\n\nconst anonymousData: IdentityData = {\n id: \"anonymous\",\n displayName: \"Anonymous\",\n type: \"admin\",\n roles: [],\n teams: [],\n permissions: [],\n profile: {\n external: false\n },\n currentTenant: {\n id: \"root\",\n name: \"Root\"\n },\n defaultTenant: {\n id: \"root\",\n name: \"Root\"\n }\n};\n\nexport class Identity {\n private constructor(\n private data: Identity.Data,\n private identityType: \"anonymous\" | \"authenticated\"\n ) {\n makeAutoObservable(this);\n }\n\n static createAuthenticated(data: Identity.Data) {\n return new Identity(data, \"authenticated\");\n }\n\n static createAnonymous() {\n return new Identity(anonymousData, \"anonymous\");\n }\n\n get isAuthenticated(): boolean {\n return this.identityType === \"authenticated\";\n }\n\n get id() {\n return this.data.id;\n }\n\n get type() {\n return this.data.type;\n }\n\n get displayName() {\n return this.data.displayName;\n }\n\n get roles() {\n return this.data.roles ?? [];\n }\n\n get teams() {\n return this.data.teams ?? [];\n }\n\n get profile() {\n return this.data.profile;\n }\n\n get currentTenant() {\n return this.data.currentTenant;\n }\n\n get defaultTenant() {\n return this.data.defaultTenant;\n }\n\n getPermission<T extends Identity.Permission = Identity.Permission>(\n name: string,\n exact?: boolean\n ): T | null {\n const perms = (this.data.permissions || []) as T[];\n const exactMatch = perms.find(p => p.name === name);\n if (exactMatch) {\n return exactMatch as T;\n } else if (exact) {\n return null;\n }\n\n // Try matching using patterns\n return perms.find(p => minimatch(name, p.name)) || null;\n }\n\n getPermissions<T extends Identity.Permission = Identity.Permission>(name?: string): Array<T> {\n const permissions = this.data.permissions || [];\n if (!name) {\n return permissions as T[];\n }\n\n return permissions.filter(current => {\n const exactMatch = current.name === name;\n if (exactMatch) {\n return true;\n }\n\n // Try matching using patterns.\n return minimatch(name, current.name);\n }) as T[];\n }\n\n update(updates: Partial<Pick<Identity.Data, \"displayName\" | \"profile\">>) {\n runInAction(() => {\n this.data.displayName = updates.displayName || this.data.displayName;\n this.data.profile = updates.profile || this.data.profile;\n });\n }\n}\n\nexport namespace Identity {\n export type Data = IdentityData;\n export type Permission = IPermission;\n export type Profile = IProfile;\n}\n"],"names":["anonymousData","Identity","data","identityType","makeAutoObservable","name","exact","perms","exactMatch","p","minimatch","permissions","current","updates","runInAction"],"mappings":";;AA2CA,MAAMA,gBAA8B;IAChC,IAAI;IACJ,aAAa;IACb,MAAM;IACN,OAAO,EAAE;IACT,OAAO,EAAE;IACT,aAAa,EAAE;IACf,SAAS;QACL,UAAU;IACd;IACA,eAAe;QACX,IAAI;QACJ,MAAM;IACV;IACA,eAAe;QACX,IAAI;QACJ,MAAM;IACV;AACJ;AAEO,MAAMC;IACT,YACYC,IAAmB,EACnBC,YAA2C,CACrD;aAFUD,IAAI,GAAJA;aACAC,YAAY,GAAZA;QAERC,mBAAmB,IAAI;IAC3B;IAEA,OAAO,oBAAoBF,IAAmB,EAAE;QAC5C,OAAO,IAAID,SAASC,MAAM;IAC9B;IAEA,OAAO,kBAAkB;QACrB,OAAO,IAAID,SAASD,eAAe;IACvC;IAEA,IAAI,kBAA2B;QAC3B,OAAO,AAAsB,oBAAtB,IAAI,CAAC,YAAY;IAC5B;IAEA,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE;IACvB;IAEA,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI;IACzB;IAEA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW;IAChC;IAEA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;IAChC;IAEA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;IAChC;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;IAC5B;IAEA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa;IAClC;IAEA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa;IAClC;IAEA,cACIK,IAAY,EACZC,KAAe,EACP;QACR,MAAMC,QAAS,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE;QAC1C,MAAMC,aAAaD,MAAM,IAAI,CAACE,CAAAA,IAAKA,EAAE,IAAI,KAAKJ;QAC9C,IAAIG,YACA,OAAOA;aACJ,IAAIF,OACP,OAAO;QAIX,OAAOC,MAAM,IAAI,CAACE,CAAAA,IAAKC,UAAUL,MAAMI,EAAE,IAAI,MAAM;IACvD;IAEA,eAAoEJ,IAAa,EAAY;QACzF,MAAMM,cAAc,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE;QAC/C,IAAI,CAACN,MACD,OAAOM;QAGX,OAAOA,YAAY,MAAM,CAACC,CAAAA;YACtB,MAAMJ,aAAaI,QAAQ,IAAI,KAAKP;YACpC,IAAIG,YACA,OAAO;YAIX,OAAOE,UAAUL,MAAMO,QAAQ,IAAI;QACvC;IACJ;IAEA,OAAOC,OAAgE,EAAE;QACrEC,YAAY;YACR,IAAI,CAAC,IAAI,CAAC,WAAW,GAAGD,QAAQ,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW;YACpE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAGA,QAAQ,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;QAC5D;IACJ;AACJ"}
|
|
@@ -3,6 +3,6 @@ import React from "react";
|
|
|
3
3
|
* No menu entry: the header indicator is the way in, and it downloads the report directly. The
|
|
4
4
|
* panel remains reachable by URL for anyone who wants the namespace filter or the session list.
|
|
5
5
|
*/
|
|
6
|
-
export declare const Debugger: (() => React.JSX.Element) & {
|
|
7
|
-
|
|
6
|
+
export declare const Debugger: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
7
|
+
readonly type: () => React.JSX.Element;
|
|
8
8
|
};
|
|
@@ -11,6 +11,6 @@ import React from "react";
|
|
|
11
11
|
* held is in memory and lands in the next report whether or not it is relevant to the problem being
|
|
12
12
|
* reproduced.
|
|
13
13
|
*/
|
|
14
|
-
export declare const DebuggerIndicator: (() => React.JSX.Element | null) & {
|
|
15
|
-
|
|
14
|
+
export declare const DebuggerIndicator: (() => React.JSX.Element | null) & React.NamedExoticComponent<unknown> & {
|
|
15
|
+
readonly type: () => React.JSX.Element | null;
|
|
16
16
|
};
|
|
@@ -166,6 +166,19 @@ describe("DateTimeFieldBuilder", ()=>{
|
|
|
166
166
|
expect(subtype(new DateTimeFieldBuilder()).build("d").renderer).toBe("dateTimeInput");
|
|
167
167
|
}
|
|
168
168
|
});
|
|
169
|
+
it("normalizes withTimezone values", ()=>{
|
|
170
|
+
const builder = new DateTimeFieldBuilder().withTimezone();
|
|
171
|
+
expect(builder.normalizeValue("2026-05-01T14:30:00+02:00")).toBe("2026-05-01T14:30:00+02:00");
|
|
172
|
+
expect(builder.normalizeValue("2026-05-01T14:30-05:30")).toBe("2026-05-01T14:30:00-05:30");
|
|
173
|
+
expect(builder.normalizeValue("2026-05-01T09:00:00.000Z")).toBe("2026-05-01T09:00:00.000+00:00");
|
|
174
|
+
expect(builder.normalizeValue("2026-05-01T14:30:00")).toBe("2026-05-01T14:30:00");
|
|
175
|
+
});
|
|
176
|
+
it("normalizes withoutTimezone values to a stable UTC instant", ()=>{
|
|
177
|
+
const builder = new DateTimeFieldBuilder().withoutTimezone();
|
|
178
|
+
const value = "2026-05-01T12:30:00.000Z";
|
|
179
|
+
expect(builder.normalizeValue(value)).toBe(value);
|
|
180
|
+
expect(builder.normalizeValue(builder.normalizeValue(value))).toBe(value);
|
|
181
|
+
});
|
|
169
182
|
});
|
|
170
183
|
describe("FieldBuilderRegistry", ()=>{
|
|
171
184
|
it("should create text builders via registry.text()", ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/formModel/FieldBuilder.test.js","sources":["../../../src/features/formModel/FieldBuilder.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { z } from \"zod\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"./feature.js\";\nimport { IdentityContextFeature } from \"~/features/security/IdentityContext/feature.js\";\nimport { FieldBuilderRegistry, type IFieldBuilderRegistry } from \"./abstractions.js\";\nimport { TextFieldBuilder } from \"./fieldTypes/TextFieldType.js\";\nimport { NumberFieldBuilder } from \"./fieldTypes/NumberFieldType.js\";\nimport { BooleanFieldBuilder } from \"./fieldTypes/BooleanFieldType.js\";\nimport { DateTimeFieldBuilder } from \"./fieldTypes/DateTimeFieldType.js\";\n\nfunction createRegistry(): IFieldBuilderRegistry {\n const container = new Container();\n IdentityContextFeature.register(container);\n FormModelFeature.register(container);\n return container.resolve(FieldBuilderRegistry);\n}\n\ndescribe(\"TextFieldBuilder\", () => {\n it(\"should build a text field config with all fluent methods\", () => {\n const builder = new TextFieldBuilder()\n .label(\"Title\")\n .placeholder(\"Enter title\")\n .required(\"Title is required\")\n .defaultValue(\"Untitled\")\n .renderer(\"custom-text\")\n .schema(z.string().min(1));\n\n const config = builder.build(\"title\");\n\n expect(config.name).toBe(\"title\");\n expect(config.type).toBe(\"text\");\n expect(config.label).toBe(\"Title\");\n expect(config.placeholder).toBe(\"Enter title\");\n expect(config.required).toBe(true);\n expect(config.requiredMessage).toBe(\"Title is required\");\n expect(config.defaultValue).toBe(\"Untitled\");\n expect(config.renderer).toBe(\"custom-text\");\n expect(config.hidden).toBe(false);\n expect(config.disabled).toBe(false);\n expect(config.schema).toBeDefined();\n });\n\n it(\"should support hidden() method\", () => {\n const config = new TextFieldBuilder().hidden().build(\"secret\");\n expect(config.hidden).toBe(true);\n });\n\n it(\"should support disabled() method\", () => {\n const config = new TextFieldBuilder().disabled().build(\"readonly\");\n expect(config.disabled).toBe(true);\n });\n\n it(\"should default disabled to false\", () => {\n const config = new TextFieldBuilder().build(\"field\");\n expect(config.disabled).toBe(false);\n });\n});\n\ndescribe(\"TextFieldBuilder - beforeChange / afterChange\", () => {\n it(\"should store beforeChange callbacks in config\", () => {\n const cb1 = (value: unknown) => value;\n const cb2 = (value: unknown) => value;\n\n const config = new TextFieldBuilder().beforeChange(cb1).beforeChange(cb2).build(\"field\");\n\n expect(config.beforeChangeCallbacks).toHaveLength(2);\n expect(config.beforeChangeCallbacks![0]).toBe(cb1);\n expect(config.beforeChangeCallbacks![1]).toBe(cb2);\n });\n\n it(\"should store afterChange callbacks in config\", () => {\n const cb = () => {};\n const config = new TextFieldBuilder().afterChange(cb).build(\"field\");\n\n expect(config.afterChangeCallbacks).toHaveLength(1);\n expect(config.afterChangeCallbacks![0]).toBe(cb);\n });\n\n it(\"should not have callback arrays when none are added\", () => {\n const config = new TextFieldBuilder().build(\"field\");\n expect(config.beforeChangeCallbacks).toBeUndefined();\n expect(config.afterChangeCallbacks).toBeUndefined();\n });\n\n it(\"should support chaining callbacks with other builder methods\", () => {\n const config = new TextFieldBuilder()\n .label(\"Title\")\n .beforeChange(value => value)\n .required(\"Required\")\n .afterChange(() => {})\n .build(\"title\");\n\n expect(config.label).toBe(\"Title\");\n expect(config.required).toBe(true);\n expect(config.beforeChangeCallbacks).toHaveLength(1);\n expect(config.afterChangeCallbacks).toHaveLength(1);\n });\n});\n\ndescribe(\"TextFieldBuilder - options\", () => {\n it(\"should build a text field config with static options\", () => {\n const options = [\n { label: \"English\", value: \"en\" },\n { label: \"German\", value: \"de\" }\n ];\n\n const config = new TextFieldBuilder()\n .label(\"Language\")\n .options(options)\n .required()\n .build(\"language\");\n\n expect(config.name).toBe(\"language\");\n expect(config.type).toBe(\"text\");\n expect(config.label).toBe(\"Language\");\n expect(config.required).toBe(true);\n expect(config.options).toEqual(options);\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should support reactive options function\", () => {\n const optionsFn = () => [{ label: \"A\", value: \"a\" }];\n const config = new TextFieldBuilder().options(optionsFn).build(\"dynamic\");\n expect(typeof config.options).toBe(\"function\");\n });\n\n it(\"should auto-switch renderer to dropdown when options are set\", () => {\n const config = new TextFieldBuilder().options([{ label: \"A\", value: \"a\" }]).build(\"field\");\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should not override an explicitly set renderer\", () => {\n const config = new TextFieldBuilder()\n .renderer(\"radioButtons\")\n .options([{ label: \"A\", value: \"a\" }])\n .build(\"field\");\n expect(config.renderer).toBe(\"radioButtons\");\n });\n});\n\ndescribe(\"NumberFieldBuilder - options\", () => {\n it(\"should build a number field config with options\", () => {\n const options = [\n { label: \"One\", value: \"1\" },\n { label: \"Two\", value: \"2\" }\n ];\n\n const config = new NumberFieldBuilder().label(\"Count\").options(options).build(\"count\");\n\n expect(config.type).toBe(\"number\");\n expect(config.options).toEqual(options);\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should not override an explicitly set renderer\", () => {\n const config = new NumberFieldBuilder()\n .renderer(\"radioButtons\")\n .options([{ label: \"1\", value: \"1\" }])\n .build(\"field\");\n expect(config.renderer).toBe(\"radioButtons\");\n });\n});\n\ndescribe(\"DateTimeFieldBuilder\", () => {\n it(\"should build a datetime field with default renderer\", () => {\n const config = new DateTimeFieldBuilder().label(\"Created\").build(\"created\");\n expect(config.type).toBe(\"datetime\");\n expect(config.renderer).toBe(\"dateTimeInput\");\n expect(config.label).toBe(\"Created\");\n });\n\n it(\"keeps the list renderer when a subtype is set after list()\", () => {\n const subtypes = [\n (b: DateTimeFieldBuilder) => b.dateOnly(),\n (b: DateTimeFieldBuilder) => b.timeOnly(),\n (b: DateTimeFieldBuilder) => b.withTimezone(),\n (b: DateTimeFieldBuilder) => b.withoutTimezone()\n ];\n for (const subtype of subtypes) {\n expect(subtype(new DateTimeFieldBuilder().list()).build(\"d\").renderer).toBe(\n \"dateTimeInputs\"\n );\n expect(subtype(new DateTimeFieldBuilder()).build(\"d\").renderer).toBe(\"dateTimeInput\");\n }\n });\n});\n\ndescribe(\"FieldBuilderRegistry\", () => {\n it(\"should create text builders via registry.text()\", () => {\n const registry = createRegistry();\n const builder = registry.text();\n expect(builder).toBeInstanceOf(TextFieldBuilder);\n });\n\n it(\"should create number builders via registry.number()\", () => {\n const registry = createRegistry();\n const builder = registry.number();\n expect(builder).toBeInstanceOf(NumberFieldBuilder);\n });\n\n it(\"should create boolean builders via registry.boolean()\", () => {\n const registry = createRegistry();\n const builder = registry.boolean();\n expect(builder).toBeInstanceOf(BooleanFieldBuilder);\n });\n\n it(\"should create datetime builders via registry.datetime()\", () => {\n const registry = createRegistry();\n const builder = registry.datetime();\n expect(builder).toBeInstanceOf(DateTimeFieldBuilder);\n });\n\n it(\"should support chaining on registry-created builders\", () => {\n const registry = createRegistry();\n const config = registry.text().label(\"Name\").required().build(\"name\");\n expect(config.label).toBe(\"Name\");\n expect(config.required).toBe(true);\n });\n\n it(\"should support options on text builders from registry\", () => {\n const registry = createRegistry();\n const config = registry\n .text()\n .options([{ label: \"A\", value: \"a\" }])\n .build(\"field\");\n expect(config.options).toHaveLength(1);\n expect(config.renderer).toBe(\"select\");\n });\n});\n\ndescribe(\"normalizeValue\", () => {\n it(\"should be identity for TextFieldBuilder\", () => {\n const builder = new TextFieldBuilder();\n expect(builder.normalizeValue(\"hello\")).toBe(\"hello\");\n expect(builder.normalizeValue(42)).toBe(42);\n expect(builder.normalizeValue(null)).toBe(null);\n });\n\n it(\"should coerce string to number for NumberFieldBuilder\", () => {\n const builder = new NumberFieldBuilder();\n expect(builder.normalizeValue(\"42\")).toBe(42);\n expect(builder.normalizeValue(\"3.14\")).toBe(3.14);\n expect(builder.normalizeValue(\"0\")).toBe(0);\n });\n\n it(\"should return null for non-numeric values in NumberFieldBuilder\", () => {\n const builder = new NumberFieldBuilder();\n expect(builder.normalizeValue(null)).toBe(null);\n expect(builder.normalizeValue(undefined)).toBe(null);\n expect(builder.normalizeValue(\"\")).toBe(null);\n expect(builder.normalizeValue(\"abc\")).toBe(null);\n });\n\n it(\"should coerce to boolean for BooleanFieldBuilder\", () => {\n const builder = new BooleanFieldBuilder();\n expect(builder.normalizeValue(1)).toBe(true);\n expect(builder.normalizeValue(0)).toBe(false);\n expect(builder.normalizeValue(\"\")).toBe(false);\n expect(builder.normalizeValue(\"yes\")).toBe(true);\n expect(builder.normalizeValue(null)).toBe(false);\n });\n\n it(\"should be identity for DateTimeFieldBuilder\", () => {\n const builder = new DateTimeFieldBuilder();\n expect(builder.normalizeValue(\"2024-01-01\")).toBe(\"2024-01-01\");\n expect(builder.normalizeValue(null)).toBe(null);\n });\n\n it(\"should capture normalizeValue into config at build time\", () => {\n const config = new NumberFieldBuilder().label(\"Count\").build(\"count\");\n expect(config.normalizeValue).toBeDefined();\n expect(config.normalizeValue!(\"42\")).toBe(42);\n expect(config.normalizeValue!(null)).toBe(null);\n });\n});\n"],"names":["createRegistry","container","Container","IdentityContextFeature","FormModelFeature","FieldBuilderRegistry","describe","it","builder","TextFieldBuilder","z","config","expect","cb1","value","cb2","cb","options","optionsFn","NumberFieldBuilder","DateTimeFieldBuilder","subtypes","b","subtype","registry","BooleanFieldBuilder","undefined"],"mappings":";;;;;;;;;;AAWA,SAASA;IACL,MAAMC,YAAY,IAAIC;IACtBC,uBAAuB,QAAQ,CAACF;IAChCG,iBAAiB,QAAQ,CAACH;IAC1B,OAAOA,UAAU,OAAO,CAACI;AAC7B;AAEAC,SAAS,oBAAoB;IACzBC,GAAG,4DAA4D;QAC3D,MAAMC,UAAU,IAAIC,mBACf,KAAK,CAAC,SACN,WAAW,CAAC,eACZ,QAAQ,CAAC,qBACT,YAAY,CAAC,YACb,QAAQ,CAAC,eACT,MAAM,CAACC,EAAE,MAAM,GAAG,GAAG,CAAC;QAE3B,MAAMC,SAASH,QAAQ,KAAK,CAAC;QAE7BI,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,KAAK,EAAE,IAAI,CAAC;QAC1BC,OAAOD,OAAO,WAAW,EAAE,IAAI,CAAC;QAChCC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,eAAe,EAAE,IAAI,CAAC;QACpCC,OAAOD,OAAO,YAAY,EAAE,IAAI,CAAC;QACjCC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,MAAM,EAAE,IAAI,CAAC;QAC3BC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,MAAM,EAAE,WAAW;IACrC;IAEAJ,GAAG,kCAAkC;QACjC,MAAMI,SAAS,IAAIF,mBAAmB,MAAM,GAAG,KAAK,CAAC;QACrDG,OAAOD,OAAO,MAAM,EAAE,IAAI,CAAC;IAC/B;IAEAJ,GAAG,oCAAoC;QACnC,MAAMI,SAAS,IAAIF,mBAAmB,QAAQ,GAAG,KAAK,CAAC;QACvDG,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;IAEAJ,GAAG,oCAAoC;QACnC,MAAMI,SAAS,IAAIF,mBAAmB,KAAK,CAAC;QAC5CG,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;AACJ;AAEAL,SAAS,iDAAiD;IACtDC,GAAG,iDAAiD;QAChD,MAAMM,MAAM,CAACC,QAAmBA;QAChC,MAAMC,MAAM,CAACD,QAAmBA;QAEhC,MAAMH,SAAS,IAAIF,mBAAmB,YAAY,CAACI,KAAK,YAAY,CAACE,KAAK,KAAK,CAAC;QAEhFH,OAAOD,OAAO,qBAAqB,EAAE,YAAY,CAAC;QAClDC,OAAOD,OAAO,qBAAsB,CAAC,EAAE,EAAE,IAAI,CAACE;QAC9CD,OAAOD,OAAO,qBAAsB,CAAC,EAAE,EAAE,IAAI,CAACI;IAClD;IAEAR,GAAG,gDAAgD;QAC/C,MAAMS,KAAK,KAAO;QAClB,MAAML,SAAS,IAAIF,mBAAmB,WAAW,CAACO,IAAI,KAAK,CAAC;QAE5DJ,OAAOD,OAAO,oBAAoB,EAAE,YAAY,CAAC;QACjDC,OAAOD,OAAO,oBAAqB,CAAC,EAAE,EAAE,IAAI,CAACK;IACjD;IAEAT,GAAG,uDAAuD;QACtD,MAAMI,SAAS,IAAIF,mBAAmB,KAAK,CAAC;QAC5CG,OAAOD,OAAO,qBAAqB,EAAE,aAAa;QAClDC,OAAOD,OAAO,oBAAoB,EAAE,aAAa;IACrD;IAEAJ,GAAG,gEAAgE;QAC/D,MAAMI,SAAS,IAAIF,mBACd,KAAK,CAAC,SACN,YAAY,CAACK,CAAAA,QAASA,OACtB,QAAQ,CAAC,YACT,WAAW,CAAC,KAAO,GACnB,KAAK,CAAC;QAEXF,OAAOD,OAAO,KAAK,EAAE,IAAI,CAAC;QAC1BC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,qBAAqB,EAAE,YAAY,CAAC;QAClDC,OAAOD,OAAO,oBAAoB,EAAE,YAAY,CAAC;IACrD;AACJ;AAEAL,SAAS,8BAA8B;IACnCC,GAAG,wDAAwD;QACvD,MAAMU,UAAU;YACZ;gBAAE,OAAO;gBAAW,OAAO;YAAK;YAChC;gBAAE,OAAO;gBAAU,OAAO;YAAK;SAClC;QAED,MAAMN,SAAS,IAAIF,mBACd,KAAK,CAAC,YACN,OAAO,CAACQ,SACR,QAAQ,GACR,KAAK,CAAC;QAEXL,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,KAAK,EAAE,IAAI,CAAC;QAC1BC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,OAAO,EAAE,OAAO,CAACM;QAC/BL,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;IAEAJ,GAAG,4CAA4C;QAC3C,MAAMW,YAAY,IAAM;gBAAC;oBAAE,OAAO;oBAAK,OAAO;gBAAI;aAAE;QACpD,MAAMP,SAAS,IAAIF,mBAAmB,OAAO,CAACS,WAAW,KAAK,CAAC;QAC/DN,OAAO,OAAOD,OAAO,OAAO,EAAE,IAAI,CAAC;IACvC;IAEAJ,GAAG,gEAAgE;QAC/D,MAAMI,SAAS,IAAIF,mBAAmB,OAAO,CAAC;YAAC;gBAAE,OAAO;gBAAK,OAAO;YAAI;SAAE,EAAE,KAAK,CAAC;QAClFG,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;IAEAJ,GAAG,kDAAkD;QACjD,MAAMI,SAAS,IAAIF,mBACd,QAAQ,CAAC,gBACT,OAAO,CAAC;YAAC;gBAAE,OAAO;gBAAK,OAAO;YAAI;SAAE,EACpC,KAAK,CAAC;QACXG,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;AACJ;AAEAL,SAAS,gCAAgC;IACrCC,GAAG,mDAAmD;QAClD,MAAMU,UAAU;YACZ;gBAAE,OAAO;gBAAO,OAAO;YAAI;YAC3B;gBAAE,OAAO;gBAAO,OAAO;YAAI;SAC9B;QAED,MAAMN,SAAS,IAAIQ,qBAAqB,KAAK,CAAC,SAAS,OAAO,CAACF,SAAS,KAAK,CAAC;QAE9EL,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,OAAO,EAAE,OAAO,CAACM;QAC/BL,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;IAEAJ,GAAG,kDAAkD;QACjD,MAAMI,SAAS,IAAIQ,qBACd,QAAQ,CAAC,gBACT,OAAO,CAAC;YAAC;gBAAE,OAAO;gBAAK,OAAO;YAAI;SAAE,EACpC,KAAK,CAAC;QACXP,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;AACJ;AAEAL,SAAS,wBAAwB;IAC7BC,GAAG,uDAAuD;QACtD,MAAMI,SAAS,IAAIS,uBAAuB,KAAK,CAAC,WAAW,KAAK,CAAC;QACjER,OAAOD,OAAO,IAAI,EAAE,IAAI,CAAC;QACzBC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;QAC7BC,OAAOD,OAAO,KAAK,EAAE,IAAI,CAAC;IAC9B;IAEAJ,GAAG,8DAA8D;QAC7D,MAAMc,WAAW;YACb,CAACC,IAA4BA,EAAE,QAAQ;YACvC,CAACA,IAA4BA,EAAE,QAAQ;YACvC,CAACA,IAA4BA,EAAE,YAAY;YAC3C,CAACA,IAA4BA,EAAE,eAAe;SACjD;QACD,KAAK,MAAMC,WAAWF,SAAU;YAC5BT,OAAOW,QAAQ,IAAIH,uBAAuB,IAAI,IAAI,KAAK,CAAC,KAAK,QAAQ,EAAE,IAAI,CACvE;YAEJR,OAAOW,QAAQ,IAAIH,wBAAwB,KAAK,CAAC,KAAK,QAAQ,EAAE,IAAI,CAAC;QACzE;IACJ;AACJ;AAEAd,SAAS,wBAAwB;IAC7BC,GAAG,mDAAmD;QAClD,MAAMiB,WAAWxB;QACjB,MAAMQ,UAAUgB,SAAS,IAAI;QAC7BZ,OAAOJ,SAAS,cAAc,CAACC;IACnC;IAEAF,GAAG,uDAAuD;QACtD,MAAMiB,WAAWxB;QACjB,MAAMQ,UAAUgB,SAAS,MAAM;QAC/BZ,OAAOJ,SAAS,cAAc,CAACW;IACnC;IAEAZ,GAAG,yDAAyD;QACxD,MAAMiB,WAAWxB;QACjB,MAAMQ,UAAUgB,SAAS,OAAO;QAChCZ,OAAOJ,SAAS,cAAc,CAACiB;IACnC;IAEAlB,GAAG,2DAA2D;QAC1D,MAAMiB,WAAWxB;QACjB,MAAMQ,UAAUgB,SAAS,QAAQ;QACjCZ,OAAOJ,SAAS,cAAc,CAACY;IACnC;IAEAb,GAAG,wDAAwD;QACvD,MAAMiB,WAAWxB;QACjB,MAAMW,SAASa,SAAS,IAAI,GAAG,KAAK,CAAC,QAAQ,QAAQ,GAAG,KAAK,CAAC;QAC9DZ,OAAOD,OAAO,KAAK,EAAE,IAAI,CAAC;QAC1BC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;IAEAJ,GAAG,yDAAyD;QACxD,MAAMiB,WAAWxB;QACjB,MAAMW,SAASa,SACV,IAAI,GACJ,OAAO,CAAC;YAAC;gBAAE,OAAO;gBAAK,OAAO;YAAI;SAAE,EACpC,KAAK,CAAC;QACXZ,OAAOD,OAAO,OAAO,EAAE,YAAY,CAAC;QACpCC,OAAOD,OAAO,QAAQ,EAAE,IAAI,CAAC;IACjC;AACJ;AAEAL,SAAS,kBAAkB;IACvBC,GAAG,2CAA2C;QAC1C,MAAMC,UAAU,IAAIC;QACpBG,OAAOJ,QAAQ,cAAc,CAAC,UAAU,IAAI,CAAC;QAC7CI,OAAOJ,QAAQ,cAAc,CAAC,KAAK,IAAI,CAAC;QACxCI,OAAOJ,QAAQ,cAAc,CAAC,OAAO,IAAI,CAAC;IAC9C;IAEAD,GAAG,yDAAyD;QACxD,MAAMC,UAAU,IAAIW;QACpBP,OAAOJ,QAAQ,cAAc,CAAC,OAAO,IAAI,CAAC;QAC1CI,OAAOJ,QAAQ,cAAc,CAAC,SAAS,IAAI,CAAC;QAC5CI,OAAOJ,QAAQ,cAAc,CAAC,MAAM,IAAI,CAAC;IAC7C;IAEAD,GAAG,mEAAmE;QAClE,MAAMC,UAAU,IAAIW;QACpBP,OAAOJ,QAAQ,cAAc,CAAC,OAAO,IAAI,CAAC;QAC1CI,OAAOJ,QAAQ,cAAc,CAACkB,SAAY,IAAI,CAAC;QAC/Cd,OAAOJ,QAAQ,cAAc,CAAC,KAAK,IAAI,CAAC;QACxCI,OAAOJ,QAAQ,cAAc,CAAC,QAAQ,IAAI,CAAC;IAC/C;IAEAD,GAAG,oDAAoD;QACnD,MAAMC,UAAU,IAAIiB;QACpBb,OAAOJ,QAAQ,cAAc,CAAC,IAAI,IAAI,CAAC;QACvCI,OAAOJ,QAAQ,cAAc,CAAC,IAAI,IAAI,CAAC;QACvCI,OAAOJ,QAAQ,cAAc,CAAC,KAAK,IAAI,CAAC;QACxCI,OAAOJ,QAAQ,cAAc,CAAC,QAAQ,IAAI,CAAC;QAC3CI,OAAOJ,QAAQ,cAAc,CAAC,OAAO,IAAI,CAAC;IAC9C;IAEAD,GAAG,+CAA+C;QAC9C,MAAMC,UAAU,IAAIY;QACpBR,OAAOJ,QAAQ,cAAc,CAAC,eAAe,IAAI,CAAC;QAClDI,OAAOJ,QAAQ,cAAc,CAAC,OAAO,IAAI,CAAC;IAC9C;IAEAD,GAAG,2DAA2D;QAC1D,MAAMI,SAAS,IAAIQ,qBAAqB,KAAK,CAAC,SAAS,KAAK,CAAC;QAC7DP,OAAOD,OAAO,cAAc,EAAE,WAAW;QACzCC,OAAOD,OAAO,cAAc,CAAE,OAAO,IAAI,CAAC;QAC1CC,OAAOD,OAAO,cAAc,CAAE,OAAO,IAAI,CAAC;IAC9C;AACJ"}
|
|
1
|
+
{"version":3,"file":"features/formModel/FieldBuilder.test.js","sources":["../../../src/features/formModel/FieldBuilder.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { z } from \"zod\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"./feature.js\";\nimport { IdentityContextFeature } from \"~/features/security/IdentityContext/feature.js\";\nimport { FieldBuilderRegistry, type IFieldBuilderRegistry } from \"./abstractions.js\";\nimport { TextFieldBuilder } from \"./fieldTypes/TextFieldType.js\";\nimport { NumberFieldBuilder } from \"./fieldTypes/NumberFieldType.js\";\nimport { BooleanFieldBuilder } from \"./fieldTypes/BooleanFieldType.js\";\nimport { DateTimeFieldBuilder } from \"./fieldTypes/DateTimeFieldType.js\";\n\nfunction createRegistry(): IFieldBuilderRegistry {\n const container = new Container();\n IdentityContextFeature.register(container);\n FormModelFeature.register(container);\n return container.resolve(FieldBuilderRegistry);\n}\n\ndescribe(\"TextFieldBuilder\", () => {\n it(\"should build a text field config with all fluent methods\", () => {\n const builder = new TextFieldBuilder()\n .label(\"Title\")\n .placeholder(\"Enter title\")\n .required(\"Title is required\")\n .defaultValue(\"Untitled\")\n .renderer(\"custom-text\")\n .schema(z.string().min(1));\n\n const config = builder.build(\"title\");\n\n expect(config.name).toBe(\"title\");\n expect(config.type).toBe(\"text\");\n expect(config.label).toBe(\"Title\");\n expect(config.placeholder).toBe(\"Enter title\");\n expect(config.required).toBe(true);\n expect(config.requiredMessage).toBe(\"Title is required\");\n expect(config.defaultValue).toBe(\"Untitled\");\n expect(config.renderer).toBe(\"custom-text\");\n expect(config.hidden).toBe(false);\n expect(config.disabled).toBe(false);\n expect(config.schema).toBeDefined();\n });\n\n it(\"should support hidden() method\", () => {\n const config = new TextFieldBuilder().hidden().build(\"secret\");\n expect(config.hidden).toBe(true);\n });\n\n it(\"should support disabled() method\", () => {\n const config = new TextFieldBuilder().disabled().build(\"readonly\");\n expect(config.disabled).toBe(true);\n });\n\n it(\"should default disabled to false\", () => {\n const config = new TextFieldBuilder().build(\"field\");\n expect(config.disabled).toBe(false);\n });\n});\n\ndescribe(\"TextFieldBuilder - beforeChange / afterChange\", () => {\n it(\"should store beforeChange callbacks in config\", () => {\n const cb1 = (value: unknown) => value;\n const cb2 = (value: unknown) => value;\n\n const config = new TextFieldBuilder().beforeChange(cb1).beforeChange(cb2).build(\"field\");\n\n expect(config.beforeChangeCallbacks).toHaveLength(2);\n expect(config.beforeChangeCallbacks![0]).toBe(cb1);\n expect(config.beforeChangeCallbacks![1]).toBe(cb2);\n });\n\n it(\"should store afterChange callbacks in config\", () => {\n const cb = () => {};\n const config = new TextFieldBuilder().afterChange(cb).build(\"field\");\n\n expect(config.afterChangeCallbacks).toHaveLength(1);\n expect(config.afterChangeCallbacks![0]).toBe(cb);\n });\n\n it(\"should not have callback arrays when none are added\", () => {\n const config = new TextFieldBuilder().build(\"field\");\n expect(config.beforeChangeCallbacks).toBeUndefined();\n expect(config.afterChangeCallbacks).toBeUndefined();\n });\n\n it(\"should support chaining callbacks with other builder methods\", () => {\n const config = new TextFieldBuilder()\n .label(\"Title\")\n .beforeChange(value => value)\n .required(\"Required\")\n .afterChange(() => {})\n .build(\"title\");\n\n expect(config.label).toBe(\"Title\");\n expect(config.required).toBe(true);\n expect(config.beforeChangeCallbacks).toHaveLength(1);\n expect(config.afterChangeCallbacks).toHaveLength(1);\n });\n});\n\ndescribe(\"TextFieldBuilder - options\", () => {\n it(\"should build a text field config with static options\", () => {\n const options = [\n { label: \"English\", value: \"en\" },\n { label: \"German\", value: \"de\" }\n ];\n\n const config = new TextFieldBuilder()\n .label(\"Language\")\n .options(options)\n .required()\n .build(\"language\");\n\n expect(config.name).toBe(\"language\");\n expect(config.type).toBe(\"text\");\n expect(config.label).toBe(\"Language\");\n expect(config.required).toBe(true);\n expect(config.options).toEqual(options);\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should support reactive options function\", () => {\n const optionsFn = () => [{ label: \"A\", value: \"a\" }];\n const config = new TextFieldBuilder().options(optionsFn).build(\"dynamic\");\n expect(typeof config.options).toBe(\"function\");\n });\n\n it(\"should auto-switch renderer to dropdown when options are set\", () => {\n const config = new TextFieldBuilder().options([{ label: \"A\", value: \"a\" }]).build(\"field\");\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should not override an explicitly set renderer\", () => {\n const config = new TextFieldBuilder()\n .renderer(\"radioButtons\")\n .options([{ label: \"A\", value: \"a\" }])\n .build(\"field\");\n expect(config.renderer).toBe(\"radioButtons\");\n });\n});\n\ndescribe(\"NumberFieldBuilder - options\", () => {\n it(\"should build a number field config with options\", () => {\n const options = [\n { label: \"One\", value: \"1\" },\n { label: \"Two\", value: \"2\" }\n ];\n\n const config = new NumberFieldBuilder().label(\"Count\").options(options).build(\"count\");\n\n expect(config.type).toBe(\"number\");\n expect(config.options).toEqual(options);\n expect(config.renderer).toBe(\"select\");\n });\n\n it(\"should not override an explicitly set renderer\", () => {\n const config = new NumberFieldBuilder()\n .renderer(\"radioButtons\")\n .options([{ label: \"1\", value: \"1\" }])\n .build(\"field\");\n expect(config.renderer).toBe(\"radioButtons\");\n });\n});\n\ndescribe(\"DateTimeFieldBuilder\", () => {\n it(\"should build a datetime field with default renderer\", () => {\n const config = new DateTimeFieldBuilder().label(\"Created\").build(\"created\");\n expect(config.type).toBe(\"datetime\");\n expect(config.renderer).toBe(\"dateTimeInput\");\n expect(config.label).toBe(\"Created\");\n });\n\n it(\"keeps the list renderer when a subtype is set after list()\", () => {\n const subtypes = [\n (b: DateTimeFieldBuilder) => b.dateOnly(),\n (b: DateTimeFieldBuilder) => b.timeOnly(),\n (b: DateTimeFieldBuilder) => b.withTimezone(),\n (b: DateTimeFieldBuilder) => b.withoutTimezone()\n ];\n for (const subtype of subtypes) {\n expect(subtype(new DateTimeFieldBuilder().list()).build(\"d\").renderer).toBe(\n \"dateTimeInputs\"\n );\n expect(subtype(new DateTimeFieldBuilder()).build(\"d\").renderer).toBe(\"dateTimeInput\");\n }\n });\n\n it(\"normalizes withTimezone values\", () => {\n const builder = new DateTimeFieldBuilder().withTimezone();\n expect(builder.normalizeValue(\"2026-05-01T14:30:00+02:00\")).toBe(\n \"2026-05-01T14:30:00+02:00\"\n );\n expect(builder.normalizeValue(\"2026-05-01T14:30-05:30\")).toBe(\"2026-05-01T14:30:00-05:30\");\n expect(builder.normalizeValue(\"2026-05-01T09:00:00.000Z\")).toBe(\n \"2026-05-01T09:00:00.000+00:00\"\n );\n expect(builder.normalizeValue(\"2026-05-01T14:30:00\")).toBe(\"2026-05-01T14:30:00\");\n });\n\n it(\"normalizes withoutTimezone values to a stable UTC instant\", () => {\n const builder = new DateTimeFieldBuilder().withoutTimezone();\n const value = \"2026-05-01T12:30:00.000Z\";\n expect(builder.normalizeValue(value)).toBe(value);\n expect(builder.normalizeValue(builder.normalizeValue(value))).toBe(value);\n });\n});\n\ndescribe(\"FieldBuilderRegistry\", () => {\n it(\"should create text builders via registry.text()\", () => {\n const registry = createRegistry();\n const builder = registry.text();\n expect(builder).toBeInstanceOf(TextFieldBuilder);\n });\n\n it(\"should create number builders via registry.number()\", () => {\n const registry = createRegistry();\n const builder = registry.number();\n expect(builder).toBeInstanceOf(NumberFieldBuilder);\n });\n\n it(\"should create boolean builders via registry.boolean()\", () => {\n const registry = createRegistry();\n const builder = registry.boolean();\n expect(builder).toBeInstanceOf(BooleanFieldBuilder);\n });\n\n it(\"should create datetime builders via registry.datetime()\", () => {\n const registry = createRegistry();\n const builder = registry.datetime();\n expect(builder).toBeInstanceOf(DateTimeFieldBuilder);\n });\n\n it(\"should support chaining on registry-created builders\", () => {\n const registry = createRegistry();\n const config = registry.text().label(\"Name\").required().build(\"name\");\n expect(config.label).toBe(\"Name\");\n expect(config.required).toBe(true);\n });\n\n it(\"should support options on text builders from registry\", () => {\n const registry = createRegistry();\n const config = registry\n .text()\n .options([{ label: \"A\", value: \"a\" }])\n .build(\"field\");\n expect(config.options).toHaveLength(1);\n expect(config.renderer).toBe(\"select\");\n });\n});\n\ndescribe(\"normalizeValue\", () => {\n it(\"should be identity for TextFieldBuilder\", () => {\n const builder = new TextFieldBuilder();\n expect(builder.normalizeValue(\"hello\")).toBe(\"hello\");\n expect(builder.normalizeValue(42)).toBe(42);\n expect(builder.normalizeValue(null)).toBe(null);\n });\n\n it(\"should coerce string to number for NumberFieldBuilder\", () => {\n const builder = new NumberFieldBuilder();\n expect(builder.normalizeValue(\"42\")).toBe(42);\n expect(builder.normalizeValue(\"3.14\")).toBe(3.14);\n expect(builder.normalizeValue(\"0\")).toBe(0);\n });\n\n it(\"should return null for non-numeric values in NumberFieldBuilder\", () => {\n const builder = new NumberFieldBuilder();\n expect(builder.normalizeValue(null)).toBe(null);\n expect(builder.normalizeValue(undefined)).toBe(null);\n expect(builder.normalizeValue(\"\")).toBe(null);\n expect(builder.normalizeValue(\"abc\")).toBe(null);\n });\n\n it(\"should coerce to boolean for BooleanFieldBuilder\", () => {\n const builder = new BooleanFieldBuilder();\n expect(builder.normalizeValue(1)).toBe(true);\n expect(builder.normalizeValue(0)).toBe(false);\n expect(builder.normalizeValue(\"\")).toBe(false);\n expect(builder.normalizeValue(\"yes\")).toBe(true);\n expect(builder.normalizeValue(null)).toBe(false);\n });\n\n it(\"should be identity for DateTimeFieldBuilder\", () => {\n const builder = new DateTimeFieldBuilder();\n expect(builder.normalizeValue(\"2024-01-01\")).toBe(\"2024-01-01\");\n expect(builder.normalizeValue(null)).toBe(null);\n });\n\n it(\"should capture normalizeValue into config at build time\", () => {\n const config = new NumberFieldBuilder().label(\"Count\").build(\"count\");\n expect(config.normalizeValue).toBeDefined();\n expect(config.normalizeValue!(\"42\")).toBe(42);\n expect(config.normalizeValue!(null)).toBe(null);\n });\n});\n"],"names":["createRegistry","container","Container","IdentityContextFeature","FormModelFeature","FieldBuilderRegistry","describe","it","builder","TextFieldBuilder","z","config","expect","cb1","value","cb2","cb","options","optionsFn","NumberFieldBuilder","DateTimeFieldBuilder","subtypes","b","subtype","registry","BooleanFieldBuilder","undefined"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ interface FormErrorsProps {
|
|
|
4
4
|
form: IFormVM;
|
|
5
5
|
className?: string;
|
|
6
6
|
}
|
|
7
|
-
export declare const FormErrors: (({ form, className }: FormErrorsProps) => React.JSX.Element | null) & {
|
|
8
|
-
|
|
7
|
+
export declare const FormErrors: (({ form, className }: FormErrorsProps) => React.JSX.Element | null) & React.NamedExoticComponent<FormErrorsProps> & {
|
|
8
|
+
readonly type: ({ form, className }: FormErrorsProps) => React.JSX.Element | null;
|
|
9
9
|
};
|
|
10
10
|
export {};
|