@webiny/app-headless-cms-common 0.0.0-unstable.eb196ccd2f → 0.0.0-unstable.f6dc066313
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/Fields/ErrorBoundary.d.ts +1 -1
- package/Fields/ErrorBoundary.js +1 -1
- package/Fields/ErrorBoundary.js.map +1 -1
- package/Fields/FieldElement.d.ts +2 -2
- package/Fields/FieldElement.js +15 -9
- package/Fields/FieldElement.js.map +1 -1
- package/Fields/FieldElementError.js +1 -2
- package/Fields/FieldElementError.js.map +1 -1
- package/Fields/FieldRulesProvider.d.ts +9 -0
- package/Fields/FieldRulesProvider.js +20 -0
- package/Fields/FieldRulesProvider.js.map +1 -0
- package/Fields/Fields.d.ts +1 -1
- package/Fields/Fields.js +137 -16
- package/Fields/Fields.js.map +1 -1
- package/Fields/LayoutDescriptorCell.d.ts +12 -0
- package/Fields/LayoutDescriptorCell.js +47 -0
- package/Fields/LayoutDescriptorCell.js.map +1 -0
- package/Fields/evaluateExpression.d.ts +23 -0
- package/Fields/evaluateExpression.js +102 -0
- package/Fields/evaluateExpression.js.map +1 -0
- package/Fields/fieldOptions.d.ts +36 -0
- package/Fields/fieldOptions.js +113 -0
- package/Fields/fieldOptions.js.map +1 -0
- package/Fields/index.d.ts +8 -3
- package/Fields/index.js +8 -3
- package/Fields/index.js.map +1 -1
- package/Fields/layoutFieldRenderers/AlertFieldRenderer.d.ts +7 -0
- package/Fields/layoutFieldRenderers/AlertFieldRenderer.js +13 -0
- package/Fields/layoutFieldRenderers/AlertFieldRenderer.js.map +1 -0
- package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.d.ts +7 -0
- package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js +18 -0
- package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js.map +1 -0
- package/Fields/layoutFieldRenderers/TabsFieldRenderer.d.ts +12 -0
- package/Fields/layoutFieldRenderers/TabsFieldRenderer.js +72 -0
- package/Fields/layoutFieldRenderers/TabsFieldRenderer.js.map +1 -0
- package/Fields/operatorOptions.d.ts +10 -0
- package/Fields/operatorOptions.js +92 -0
- package/Fields/operatorOptions.js.map +1 -0
- package/Fields/useBind.d.ts +2 -1
- package/Fields/useBind.js +12 -8
- package/Fields/useBind.js.map +1 -1
- package/Fields/useFieldRules.d.ts +32 -0
- package/Fields/useFieldRules.js +153 -0
- package/Fields/useFieldRules.js.map +1 -0
- package/Fields/useRenderPlugins.d.ts +2 -1
- package/Fields/useRenderPlugins.js.map +1 -1
- package/ModelFieldProvider/CanEditField.d.ts +5 -0
- package/ModelFieldProvider/CanEditField.js +13 -0
- package/ModelFieldProvider/CanEditField.js.map +1 -0
- package/ModelFieldProvider/ModelFieldContext.d.ts +16 -13
- package/ModelFieldProvider/ModelFieldContext.js.map +1 -1
- package/ModelFieldProvider/index.d.ts +3 -2
- package/ModelFieldProvider/index.js +3 -2
- package/ModelFieldProvider/index.js.map +1 -1
- package/ModelFieldProvider/useModelField.d.ts +2 -3
- package/ModelFieldProvider/useModelField.js +2 -2
- package/ModelFieldProvider/useModelField.js.map +1 -1
- package/ModelProvider/ModelContext.d.ts +1 -1
- package/ModelProvider/ModelContext.js.map +1 -1
- package/ModelProvider/index.d.ts +2 -2
- package/ModelProvider/index.js +2 -2
- package/ModelProvider/index.js.map +1 -1
- package/ModelProvider/useModel.d.ts +1 -1
- package/ModelProvider/useModel.js +1 -1
- package/ModelProvider/useModel.js.map +1 -1
- package/README.md +6 -13
- package/constants.d.ts +1 -1
- package/constants.js +1 -1
- package/constants.js.map +1 -1
- package/createFieldsList.d.ts +5 -1
- package/createFieldsList.js +4 -0
- package/createFieldsList.js.map +1 -1
- package/createValidationContainer.d.ts +2 -2
- package/createValidationContainer.js +5 -8
- package/createValidationContainer.js.map +1 -1
- package/createValidators.d.ts +2 -2
- package/createValidators.js +1 -1
- package/createValidators.js.map +1 -1
- package/entries.graphql.d.ts +1 -1
- package/entries.graphql.js +39 -16
- package/entries.graphql.js.map +1 -1
- package/exports/admin/cms/model.d.ts +1 -0
- package/exports/admin/cms/model.js +3 -0
- package/exports/admin/cms/model.js.map +1 -0
- package/exports/admin/cms.d.ts +1 -0
- package/exports/admin/cms.js +3 -0
- package/exports/admin/cms.js.map +1 -0
- package/getModelTitleFieldId.d.ts +1 -1
- package/getModelTitleFieldId.js.map +1 -1
- package/index.d.ts +10 -10
- package/index.js +10 -10
- package/index.js.map +1 -1
- package/normalizeIcon.d.ts +3 -0
- package/normalizeIcon.js +10 -0
- package/normalizeIcon.js.map +1 -0
- package/package.json +17 -21
- package/prepareFormData.d.ts +1 -1
- package/prepareFormData.js +1 -1
- package/prepareFormData.js.map +1 -1
- package/types/index.d.ts +89 -37
- package/types/index.js +1 -16
- package/types/index.js.map +1 -1
- package/types/model.d.ts +71 -18
- package/types/model.js +28 -1
- package/types/model.js.map +1 -1
- package/types/validation.d.ts +2 -2
- package/types/validation.js.map +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CmsModelField, CmsEditorFieldsLayout } from "../types/model.js";
|
|
2
|
+
import type { CmsModelLayoutFieldTypePlugin } from "../types/index.js";
|
|
3
|
+
export interface FieldOption {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
fieldType: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Walk a model layout and collect label prefixes for each field ID by delegating
|
|
10
|
+
* to `getFieldLabelPrefixes` on the matching layout-field-type plugin.
|
|
11
|
+
*
|
|
12
|
+
* Returns a map from fieldId to its label prefix string
|
|
13
|
+
* (e.g., `"metaTitle" → "My Tabs › SEO"`).
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildFieldLabelPrefixes(layout: CmsEditorFieldsLayout, plugins: CmsModelLayoutFieldTypePlugin[]): Map<string, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Build a flat list of field options from the model's field tree.
|
|
18
|
+
* Paths are absolute using fieldId segments, with `$` for list-object children
|
|
19
|
+
* (e.g., `panorama.hotspots.$.title`).
|
|
20
|
+
*
|
|
21
|
+
* When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will
|
|
22
|
+
* have the layout hierarchy prepended to their labels
|
|
23
|
+
* (e.g., `"My Tabs › SEO › Meta Title"`).
|
|
24
|
+
*
|
|
25
|
+
* When `layoutPlugins` is provided, nested layouts inside object fields
|
|
26
|
+
* (e.g., tabs inside an object field) are also scanned for label prefixes.
|
|
27
|
+
*
|
|
28
|
+
* Recursion rules:
|
|
29
|
+
* - Leaf field (no settings.fields): emit option
|
|
30
|
+
* - Object field (settings.fields, not list): recurse with prefix
|
|
31
|
+
* - List object field (settings.fields, list: true): emit `.length` pseudo-option,
|
|
32
|
+
* then recurse children with `.$` segment
|
|
33
|
+
* - dynamicZone: skip
|
|
34
|
+
* - ref: emit for isEmpty checks, skip children
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildFieldOptions(fields: CmsModelField[], prefix?: string, labelPrefix?: string, fieldLabelPrefixes?: Map<string, string>, layoutPlugins?: CmsModelLayoutFieldTypePlugin[]): FieldOption[];
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { isLayoutField } from "../types/model.js";
|
|
2
|
+
/**
|
|
3
|
+
* Walk a model layout and collect label prefixes for each field ID by delegating
|
|
4
|
+
* to `getFieldLabelPrefixes` on the matching layout-field-type plugin.
|
|
5
|
+
*
|
|
6
|
+
* Returns a map from fieldId to its label prefix string
|
|
7
|
+
* (e.g., `"metaTitle" → "My Tabs › SEO"`).
|
|
8
|
+
*/
|
|
9
|
+
export function buildFieldLabelPrefixes(layout, plugins) {
|
|
10
|
+
const map = new Map();
|
|
11
|
+
const pluginByType = new Map(plugins.map(p => [p.field.type, p]));
|
|
12
|
+
for (const row of layout) {
|
|
13
|
+
for (const cell of row) {
|
|
14
|
+
if (!isLayoutField(cell)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const plugin = pluginByType.get(cell.type);
|
|
18
|
+
if (!plugin?.field.getFieldLabelPrefixes) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const prefixes = plugin.field.getFieldLabelPrefixes({
|
|
22
|
+
field: cell
|
|
23
|
+
});
|
|
24
|
+
for (const [fieldId, prefix] of Object.entries(prefixes)) {
|
|
25
|
+
map.set(fieldId, prefix);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return map;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Build a flat list of field options from the model's field tree.
|
|
34
|
+
* Paths are absolute using fieldId segments, with `$` for list-object children
|
|
35
|
+
* (e.g., `panorama.hotspots.$.title`).
|
|
36
|
+
*
|
|
37
|
+
* When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will
|
|
38
|
+
* have the layout hierarchy prepended to their labels
|
|
39
|
+
* (e.g., `"My Tabs › SEO › Meta Title"`).
|
|
40
|
+
*
|
|
41
|
+
* When `layoutPlugins` is provided, nested layouts inside object fields
|
|
42
|
+
* (e.g., tabs inside an object field) are also scanned for label prefixes.
|
|
43
|
+
*
|
|
44
|
+
* Recursion rules:
|
|
45
|
+
* - Leaf field (no settings.fields): emit option
|
|
46
|
+
* - Object field (settings.fields, not list): recurse with prefix
|
|
47
|
+
* - List object field (settings.fields, list: true): emit `.length` pseudo-option,
|
|
48
|
+
* then recurse children with `.$` segment
|
|
49
|
+
* - dynamicZone: skip
|
|
50
|
+
* - ref: emit for isEmpty checks, skip children
|
|
51
|
+
*/
|
|
52
|
+
export function buildFieldOptions(fields, prefix = "", labelPrefix = "", fieldLabelPrefixes, layoutPlugins) {
|
|
53
|
+
const options = [];
|
|
54
|
+
for (const field of fields) {
|
|
55
|
+
const path = prefix + field.fieldId;
|
|
56
|
+
const layoutPrefix = fieldLabelPrefixes?.get(field.id);
|
|
57
|
+
const label = layoutPrefix ? `${labelPrefix}${layoutPrefix} › ${field.label}` : labelPrefix + field.label;
|
|
58
|
+
|
|
59
|
+
// Dynamic zone: emit .length pseudo-option only, skip children
|
|
60
|
+
if (field.type === "dynamicZone") {
|
|
61
|
+
options.push({
|
|
62
|
+
label: `${label} › Length`,
|
|
63
|
+
value: `${path}.length`,
|
|
64
|
+
fieldType: "number"
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const childFields = field.settings?.fields;
|
|
69
|
+
|
|
70
|
+
// Ref field: include for isEmpty checks, skip children
|
|
71
|
+
if (field.type === "ref") {
|
|
72
|
+
options.push({
|
|
73
|
+
label,
|
|
74
|
+
value: path,
|
|
75
|
+
fieldType: field.type
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Object with child fields
|
|
81
|
+
if (childFields && childFields.length > 0) {
|
|
82
|
+
// Build label prefixes from the object field's own layout (e.g., tabs inside an object).
|
|
83
|
+
let childPrefixes;
|
|
84
|
+
if (layoutPlugins && field.settings?.layout) {
|
|
85
|
+
childPrefixes = buildFieldLabelPrefixes(field.settings.layout, layoutPlugins);
|
|
86
|
+
}
|
|
87
|
+
if (field.list) {
|
|
88
|
+
// List object: emit .length pseudo-option
|
|
89
|
+
options.push({
|
|
90
|
+
label: `${label} › Length`,
|
|
91
|
+
value: `${path}.length`,
|
|
92
|
+
fieldType: "number"
|
|
93
|
+
});
|
|
94
|
+
// Recurse children with $ segment
|
|
95
|
+
options.push(...buildFieldOptions(childFields, `${path}.$.`, `${label} › `, childPrefixes, layoutPlugins));
|
|
96
|
+
} else {
|
|
97
|
+
// Non-list object: recurse into children
|
|
98
|
+
options.push(...buildFieldOptions(childFields, `${path}.`, `${label} › `, childPrefixes, layoutPlugins));
|
|
99
|
+
}
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Leaf field
|
|
104
|
+
options.push({
|
|
105
|
+
label,
|
|
106
|
+
value: path,
|
|
107
|
+
fieldType: field.type
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return options;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=fieldOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isLayoutField","buildFieldLabelPrefixes","layout","plugins","map","Map","pluginByType","p","field","type","row","cell","plugin","get","getFieldLabelPrefixes","prefixes","fieldId","prefix","Object","entries","set","buildFieldOptions","fields","labelPrefix","fieldLabelPrefixes","layoutPlugins","options","path","layoutPrefix","id","label","push","value","fieldType","childFields","settings","length","childPrefixes","list"],"sources":["fieldOptions.ts"],"sourcesContent":["import type { CmsModelField, CmsEditorFieldsLayout } from \"~/types/model.js\";\nimport type { CmsModelLayoutFieldTypePlugin } from \"~/types/index.js\";\nimport { isLayoutField } from \"~/types/model.js\";\n\nexport interface FieldOption {\n label: string;\n value: string;\n fieldType: string;\n}\n\n/**\n * Walk a model layout and collect label prefixes for each field ID by delegating\n * to `getFieldLabelPrefixes` on the matching layout-field-type plugin.\n *\n * Returns a map from fieldId to its label prefix string\n * (e.g., `\"metaTitle\" → \"My Tabs › SEO\"`).\n */\nexport function buildFieldLabelPrefixes(\n layout: CmsEditorFieldsLayout,\n plugins: CmsModelLayoutFieldTypePlugin[]\n): Map<string, string> {\n const map = new Map<string, string>();\n const pluginByType = new Map(plugins.map(p => [p.field.type, p]));\n\n for (const row of layout) {\n for (const cell of row) {\n if (!isLayoutField(cell)) {\n continue;\n }\n\n const plugin = pluginByType.get(cell.type);\n if (!plugin?.field.getFieldLabelPrefixes) {\n continue;\n }\n\n const prefixes = plugin.field.getFieldLabelPrefixes({ field: cell });\n for (const [fieldId, prefix] of Object.entries(prefixes)) {\n map.set(fieldId, prefix);\n }\n }\n }\n\n return map;\n}\n\n/**\n * Build a flat list of field options from the model's field tree.\n * Paths are absolute using fieldId segments, with `$` for list-object children\n * (e.g., `panorama.hotspots.$.title`).\n *\n * When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will\n * have the layout hierarchy prepended to their labels\n * (e.g., `\"My Tabs › SEO › Meta Title\"`).\n *\n * When `layoutPlugins` is provided, nested layouts inside object fields\n * (e.g., tabs inside an object field) are also scanned for label prefixes.\n *\n * Recursion rules:\n * - Leaf field (no settings.fields): emit option\n * - Object field (settings.fields, not list): recurse with prefix\n * - List object field (settings.fields, list: true): emit `.length` pseudo-option,\n * then recurse children with `.$` segment\n * - dynamicZone: skip\n * - ref: emit for isEmpty checks, skip children\n */\nexport function buildFieldOptions(\n fields: CmsModelField[],\n prefix = \"\",\n labelPrefix = \"\",\n fieldLabelPrefixes?: Map<string, string>,\n layoutPlugins?: CmsModelLayoutFieldTypePlugin[]\n): FieldOption[] {\n const options: FieldOption[] = [];\n\n for (const field of fields) {\n const path = prefix + field.fieldId;\n const layoutPrefix = fieldLabelPrefixes?.get(field.id);\n const label = layoutPrefix\n ? `${labelPrefix}${layoutPrefix} › ${field.label}`\n : labelPrefix + field.label;\n\n // Dynamic zone: emit .length pseudo-option only, skip children\n if (field.type === \"dynamicZone\") {\n options.push({\n label: `${label} › Length`,\n value: `${path}.length`,\n fieldType: \"number\"\n });\n continue;\n }\n\n const childFields = field.settings?.fields;\n\n // Ref field: include for isEmpty checks, skip children\n if (field.type === \"ref\") {\n options.push({ label, value: path, fieldType: field.type });\n continue;\n }\n\n // Object with child fields\n if (childFields && childFields.length > 0) {\n // Build label prefixes from the object field's own layout (e.g., tabs inside an object).\n let childPrefixes: Map<string, string> | undefined;\n if (layoutPlugins && field.settings?.layout) {\n childPrefixes = buildFieldLabelPrefixes(field.settings.layout, layoutPlugins);\n }\n\n if (field.list) {\n // List object: emit .length pseudo-option\n options.push({\n label: `${label} › Length`,\n value: `${path}.length`,\n fieldType: \"number\"\n });\n // Recurse children with $ segment\n options.push(\n ...buildFieldOptions(\n childFields,\n `${path}.$.`,\n `${label} › `,\n childPrefixes,\n layoutPlugins\n )\n );\n } else {\n // Non-list object: recurse into children\n options.push(\n ...buildFieldOptions(\n childFields,\n `${path}.`,\n `${label} › `,\n childPrefixes,\n layoutPlugins\n )\n );\n }\n continue;\n }\n\n // Leaf field\n options.push({ label, value: path, fieldType: field.type });\n }\n\n return options;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/Fields/index.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
export * from "./FieldElement";
|
|
2
|
-
export * from "./Fields";
|
|
3
|
-
export * from "./useBind";
|
|
1
|
+
export * from "./FieldElement.js";
|
|
2
|
+
export * from "./Fields.js";
|
|
3
|
+
export * from "./useBind.js";
|
|
4
|
+
export * from "./FieldRulesProvider.js";
|
|
5
|
+
export * from "./evaluateExpression.js";
|
|
6
|
+
export * from "./useFieldRules.js";
|
|
7
|
+
export * from "./fieldOptions.js";
|
|
8
|
+
export * from "./operatorOptions.js";
|
package/Fields/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
export * from "./FieldElement";
|
|
2
|
-
export * from "./Fields";
|
|
3
|
-
export * from "./useBind";
|
|
1
|
+
export * from "./FieldElement.js";
|
|
2
|
+
export * from "./Fields.js";
|
|
3
|
+
export * from "./useBind.js";
|
|
4
|
+
export * from "./FieldRulesProvider.js";
|
|
5
|
+
export * from "./evaluateExpression.js";
|
|
6
|
+
export * from "./useFieldRules.js";
|
|
7
|
+
export * from "./fieldOptions.js";
|
|
8
|
+
export * from "./operatorOptions.js";
|
|
4
9
|
|
|
5
10
|
//# sourceMappingURL=index.js.map
|
package/Fields/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./FieldElement\";\nexport * from \"./Fields\";\nexport * from \"./useBind\";\n"],"mappings":"AAAA;AACA;AACA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./FieldElement.js\";\nexport * from \"./Fields.js\";\nexport * from \"./useBind.js\";\nexport * from \"./FieldRulesProvider.js\";\nexport * from \"./evaluateExpression.js\";\nexport * from \"./useFieldRules.js\";\nexport * from \"./fieldOptions.js\";\nexport * from \"./operatorOptions.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CmsAlertLayoutField } from "../../types/model.js";
|
|
3
|
+
interface AlertFieldRendererProps {
|
|
4
|
+
field: CmsAlertLayoutField;
|
|
5
|
+
}
|
|
6
|
+
export declare const AlertFieldRenderer: ({ field }: AlertFieldRendererProps) => React.JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Alert, Grid } from "@webiny/admin-ui";
|
|
3
|
+
export const AlertFieldRenderer = ({
|
|
4
|
+
field
|
|
5
|
+
}) => {
|
|
6
|
+
return /*#__PURE__*/React.createElement(Grid.Column, {
|
|
7
|
+
span: 12
|
|
8
|
+
}, /*#__PURE__*/React.createElement(Alert, {
|
|
9
|
+
type: field.alertType
|
|
10
|
+
}, field.label));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=AlertFieldRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Alert","Grid","AlertFieldRenderer","field","createElement","Column","span","type","alertType","label"],"sources":["AlertFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Alert, Grid } from \"@webiny/admin-ui\";\nimport type { CmsAlertLayoutField } from \"~/types/model.js\";\n\ninterface AlertFieldRendererProps {\n field: CmsAlertLayoutField;\n}\n\nexport const AlertFieldRenderer = ({ field }: AlertFieldRendererProps) => {\n return (\n <Grid.Column span={12}>\n <Alert type={field.alertType}>{field.label}</Alert>\n </Grid.Column>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,KAAK,EAAEC,IAAI,QAAQ,kBAAkB;AAO9C,OAAO,MAAMC,kBAAkB,GAAGA,CAAC;EAAEC;AAA+B,CAAC,KAAK;EACtE,oBACIJ,KAAA,CAAAK,aAAA,CAACH,IAAI,CAACI,MAAM;IAACC,IAAI,EAAE;EAAG,gBAClBP,KAAA,CAAAK,aAAA,CAACJ,KAAK;IAACO,IAAI,EAAEJ,KAAK,CAACK;EAAU,GAAEL,KAAK,CAACM,KAAa,CACzC,CAAC;AAEtB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CmsSeparatorLayoutField } from "../../types/model.js";
|
|
3
|
+
interface SeparatorFieldRendererProps {
|
|
4
|
+
field: CmsSeparatorLayoutField;
|
|
5
|
+
}
|
|
6
|
+
export declare const SeparatorFieldRenderer: ({ field }: SeparatorFieldRendererProps) => React.JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Grid, Separator, Text } from "@webiny/admin-ui";
|
|
3
|
+
export const SeparatorFieldRenderer = ({
|
|
4
|
+
field
|
|
5
|
+
}) => {
|
|
6
|
+
return /*#__PURE__*/React.createElement(Grid.Column, {
|
|
7
|
+
span: 12
|
|
8
|
+
}, /*#__PURE__*/React.createElement(Separator, {
|
|
9
|
+
variant: "accent",
|
|
10
|
+
labelPosition: "start"
|
|
11
|
+
}, field.label), field.description && /*#__PURE__*/React.createElement(Text, {
|
|
12
|
+
as: "div",
|
|
13
|
+
size: "sm",
|
|
14
|
+
className: "text-neutral-strong mt-sm"
|
|
15
|
+
}, field.description));
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=SeparatorFieldRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Grid","Separator","Text","SeparatorFieldRenderer","field","createElement","Column","span","variant","labelPosition","label","description","as","size","className"],"sources":["SeparatorFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Grid, Separator, Text } from \"@webiny/admin-ui\";\nimport type { CmsSeparatorLayoutField } from \"~/types/model.js\";\n\ninterface SeparatorFieldRendererProps {\n field: CmsSeparatorLayoutField;\n}\n\nexport const SeparatorFieldRenderer = ({ field }: SeparatorFieldRendererProps) => {\n return (\n <Grid.Column span={12}>\n <Separator variant={\"accent\"} labelPosition={\"start\"}>\n {field.label}\n </Separator>\n {field.description && (\n <Text as={\"div\"} size={\"sm\"} className={\"text-neutral-strong mt-sm\"}>\n {field.description}\n </Text>\n )}\n </Grid.Column>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,SAAS,EAAEC,IAAI,QAAQ,kBAAkB;AAOxD,OAAO,MAAMC,sBAAsB,GAAGA,CAAC;EAAEC;AAAmC,CAAC,KAAK;EAC9E,oBACIL,KAAA,CAAAM,aAAA,CAACL,IAAI,CAACM,MAAM;IAACC,IAAI,EAAE;EAAG,gBAClBR,KAAA,CAAAM,aAAA,CAACJ,SAAS;IAACO,OAAO,EAAE,QAAS;IAACC,aAAa,EAAE;EAAQ,GAChDL,KAAK,CAACM,KACA,CAAC,EACXN,KAAK,CAACO,WAAW,iBACdZ,KAAA,CAAAM,aAAA,CAACH,IAAI;IAACU,EAAE,EAAE,KAAM;IAACC,IAAI,EAAE,IAAK;IAACC,SAAS,EAAE;EAA4B,GAC/DV,KAAK,CAACO,WACL,CAED,CAAC;AAEtB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CmsTabLayoutField } from "../../types/model.js";
|
|
3
|
+
import type { BindComponent, CmsEditorContentModel, CmsModelField } from "../../types/index.js";
|
|
4
|
+
interface TabsFieldRendererProps {
|
|
5
|
+
field: CmsTabLayoutField;
|
|
6
|
+
Bind: BindComponent;
|
|
7
|
+
fields: CmsModelField[];
|
|
8
|
+
contentModel: CmsEditorContentModel;
|
|
9
|
+
gridClassName?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const TabsFieldRenderer: ({ field, Bind, fields, contentModel, gridClassName }: TabsFieldRendererProps) => React.JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Grid, FormComponentLabel, FormComponentDescription, Tabs } from "@webiny/admin-ui";
|
|
3
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
4
|
+
import { normalizeIcon } from "../../normalizeIcon.js";
|
|
5
|
+
import { Fields } from "../index.js";
|
|
6
|
+
import { FieldRulesProvider } from "../FieldRulesProvider.js";
|
|
7
|
+
import { useFieldEffectiveRules } from "../useFieldRules.js";
|
|
8
|
+
const TabPanel = ({
|
|
9
|
+
tab,
|
|
10
|
+
Bind,
|
|
11
|
+
fields,
|
|
12
|
+
contentModel,
|
|
13
|
+
gridClassName
|
|
14
|
+
}) => {
|
|
15
|
+
const rules = useFieldEffectiveRules(tab);
|
|
16
|
+
const icon = normalizeIcon(tab.icon);
|
|
17
|
+
return /*#__PURE__*/React.createElement(Tabs.Tab, {
|
|
18
|
+
disabled: rules.disabled,
|
|
19
|
+
visible: rules.canView && !rules.hidden,
|
|
20
|
+
value: tab.id,
|
|
21
|
+
trigger: tab.label,
|
|
22
|
+
icon: icon ? /*#__PURE__*/React.createElement(FontAwesomeIcon, {
|
|
23
|
+
icon: icon,
|
|
24
|
+
size: "sm"
|
|
25
|
+
}) : undefined,
|
|
26
|
+
content: /*#__PURE__*/React.createElement(FieldRulesProvider, {
|
|
27
|
+
rules: rules
|
|
28
|
+
}, /*#__PURE__*/React.createElement(Fields, {
|
|
29
|
+
Bind: Bind,
|
|
30
|
+
fields: fields,
|
|
31
|
+
layout: tab.layout,
|
|
32
|
+
contentModel: contentModel,
|
|
33
|
+
gridClassName: gridClassName
|
|
34
|
+
}))
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const tabsWrapperClassName = ["bg-white!", "opacity-100!", "border-neutral-muted", "text-neutral-strong", "fill-neutral-xstrong", "w-full", "border-sm", "rounded-md"].join(" ");
|
|
38
|
+
export const TabsFieldRenderer = ({
|
|
39
|
+
field,
|
|
40
|
+
Bind,
|
|
41
|
+
fields,
|
|
42
|
+
contentModel,
|
|
43
|
+
gridClassName
|
|
44
|
+
}) => {
|
|
45
|
+
const tabElements = field.tabs.map(tab => /*#__PURE__*/React.createElement(TabPanel, {
|
|
46
|
+
key: tab.id,
|
|
47
|
+
tab: tab,
|
|
48
|
+
Bind: Bind,
|
|
49
|
+
fields: fields,
|
|
50
|
+
contentModel: contentModel,
|
|
51
|
+
gridClassName: gridClassName
|
|
52
|
+
}));
|
|
53
|
+
const firstTab = field.tabs[0];
|
|
54
|
+
return /*#__PURE__*/React.createElement(Grid.Column, {
|
|
55
|
+
span: 12
|
|
56
|
+
}, field.label ? /*#__PURE__*/React.createElement(FormComponentLabel, {
|
|
57
|
+
text: field.label,
|
|
58
|
+
hint: field.help
|
|
59
|
+
}) : null, field.description ? /*#__PURE__*/React.createElement(FormComponentDescription, {
|
|
60
|
+
text: field.description
|
|
61
|
+
}) : null, /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
className: tabsWrapperClassName
|
|
63
|
+
}, /*#__PURE__*/React.createElement(Tabs, {
|
|
64
|
+
size: "md",
|
|
65
|
+
spacing: "md",
|
|
66
|
+
separator: true,
|
|
67
|
+
tabs: tabElements,
|
|
68
|
+
defaultValue: firstTab?.id
|
|
69
|
+
})));
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=TabsFieldRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Grid","FormComponentLabel","FormComponentDescription","Tabs","FontAwesomeIcon","normalizeIcon","Fields","FieldRulesProvider","useFieldEffectiveRules","TabPanel","tab","Bind","fields","contentModel","gridClassName","rules","icon","createElement","Tab","disabled","visible","canView","hidden","value","id","trigger","label","size","undefined","content","layout","tabsWrapperClassName","join","TabsFieldRenderer","field","tabElements","tabs","map","key","firstTab","Column","span","text","hint","help","description","className","spacing","separator","defaultValue"],"sources":["TabsFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Grid, FormComponentLabel, FormComponentDescription, Tabs } from \"@webiny/admin-ui\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type { CmsTabLayoutField, CmsTabLayoutTab } from \"~/types/model.js\";\nimport type { BindComponent, CmsEditorContentModel, CmsModelField } from \"~/types/index.js\";\nimport { normalizeIcon } from \"~/normalizeIcon.js\";\nimport { Fields } from \"~/Fields/index.js\";\nimport { FieldRulesProvider } from \"~/Fields/FieldRulesProvider.js\";\nimport { useFieldEffectiveRules } from \"~/Fields/useFieldRules.js\";\n\ninterface TabsFieldRendererProps {\n field: CmsTabLayoutField;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\ninterface TabPanelProps {\n tab: CmsTabLayoutTab;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\nconst TabPanel = ({ tab, Bind, fields, contentModel, gridClassName }: TabPanelProps) => {\n const rules = useFieldEffectiveRules(tab);\n\n const icon = normalizeIcon(tab.icon);\n\n return (\n <Tabs.Tab\n disabled={rules.disabled}\n visible={rules.canView && !rules.hidden}\n value={tab.id}\n trigger={tab.label}\n icon={icon ? <FontAwesomeIcon icon={icon} size={\"sm\"} /> : undefined}\n content={\n <FieldRulesProvider rules={rules}>\n <Fields\n Bind={Bind}\n fields={fields}\n layout={tab.layout}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n </FieldRulesProvider>\n }\n />\n );\n};\n\nconst tabsWrapperClassName = [\n \"bg-white!\",\n \"opacity-100!\",\n \"border-neutral-muted\",\n \"text-neutral-strong\",\n \"fill-neutral-xstrong\",\n \"w-full\",\n \"border-sm\",\n \"rounded-md\"\n].join(\" \");\n\nexport const TabsFieldRenderer = ({\n field,\n Bind,\n fields,\n contentModel,\n gridClassName\n}: TabsFieldRendererProps) => {\n const tabElements = field.tabs.map(tab => (\n <TabPanel\n key={tab.id}\n tab={tab}\n Bind={Bind}\n fields={fields}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n ));\n\n const firstTab = field.tabs[0];\n\n return (\n <Grid.Column span={12}>\n {field.label ? <FormComponentLabel text={field.label} hint={field.help} /> : null}\n {field.description ? <FormComponentDescription text={field.description} /> : null}\n <div className={tabsWrapperClassName}>\n <Tabs\n size=\"md\"\n spacing=\"md\"\n separator={true}\n tabs={tabElements}\n defaultValue={firstTab?.id}\n />\n </div>\n </Grid.Column>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,kBAAkB,EAAEC,wBAAwB,EAAEC,IAAI,QAAQ,kBAAkB;AAC3F,SAASC,eAAe,QAAQ,gCAAgC;AAGhE,SAASC,aAAa;AACtB,SAASC,MAAM;AACf,SAASC,kBAAkB;AAC3B,SAASC,sBAAsB;AAkB/B,MAAMC,QAAQ,GAAGA,CAAC;EAAEC,GAAG;EAAEC,IAAI;EAAEC,MAAM;EAAEC,YAAY;EAAEC;AAA6B,CAAC,KAAK;EACpF,MAAMC,KAAK,GAAGP,sBAAsB,CAACE,GAAG,CAAC;EAEzC,MAAMM,IAAI,GAAGX,aAAa,CAACK,GAAG,CAACM,IAAI,CAAC;EAEpC,oBACIjB,KAAA,CAAAkB,aAAA,CAACd,IAAI,CAACe,GAAG;IACLC,QAAQ,EAAEJ,KAAK,CAACI,QAAS;IACzBC,OAAO,EAAEL,KAAK,CAACM,OAAO,IAAI,CAACN,KAAK,CAACO,MAAO;IACxCC,KAAK,EAAEb,GAAG,CAACc,EAAG;IACdC,OAAO,EAAEf,GAAG,CAACgB,KAAM;IACnBV,IAAI,EAAEA,IAAI,gBAAGjB,KAAA,CAAAkB,aAAA,CAACb,eAAe;MAACY,IAAI,EAAEA,IAAK;MAACW,IAAI,EAAE;IAAK,CAAE,CAAC,GAAGC,SAAU;IACrEC,OAAO,eACH9B,KAAA,CAAAkB,aAAA,CAACV,kBAAkB;MAACQ,KAAK,EAAEA;IAAM,gBAC7BhB,KAAA,CAAAkB,aAAA,CAACX,MAAM;MACHK,IAAI,EAAEA,IAAK;MACXC,MAAM,EAAEA,MAAO;MACfkB,MAAM,EAAEpB,GAAG,CAACoB,MAAO;MACnBjB,YAAY,EAAEA,YAAa;MAC3BC,aAAa,EAAEA;IAAc,CAChC,CACe;EACvB,CACJ,CAAC;AAEV,CAAC;AAED,MAAMiB,oBAAoB,GAAG,CACzB,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,EACR,WAAW,EACX,YAAY,CACf,CAACC,IAAI,CAAC,GAAG,CAAC;AAEX,OAAO,MAAMC,iBAAiB,GAAGA,CAAC;EAC9BC,KAAK;EACLvB,IAAI;EACJC,MAAM;EACNC,YAAY;EACZC;AACoB,CAAC,KAAK;EAC1B,MAAMqB,WAAW,GAAGD,KAAK,CAACE,IAAI,CAACC,GAAG,CAAC3B,GAAG,iBAClCX,KAAA,CAAAkB,aAAA,CAACR,QAAQ;IACL6B,GAAG,EAAE5B,GAAG,CAACc,EAAG;IACZd,GAAG,EAAEA,GAAI;IACTC,IAAI,EAAEA,IAAK;IACXC,MAAM,EAAEA,MAAO;IACfC,YAAY,EAAEA,YAAa;IAC3BC,aAAa,EAAEA;EAAc,CAChC,CACJ,CAAC;EAEF,MAAMyB,QAAQ,GAAGL,KAAK,CAACE,IAAI,CAAC,CAAC,CAAC;EAE9B,oBACIrC,KAAA,CAAAkB,aAAA,CAACjB,IAAI,CAACwC,MAAM;IAACC,IAAI,EAAE;EAAG,GACjBP,KAAK,CAACR,KAAK,gBAAG3B,KAAA,CAAAkB,aAAA,CAAChB,kBAAkB;IAACyC,IAAI,EAAER,KAAK,CAACR,KAAM;IAACiB,IAAI,EAAET,KAAK,CAACU;EAAK,CAAE,CAAC,GAAG,IAAI,EAChFV,KAAK,CAACW,WAAW,gBAAG9C,KAAA,CAAAkB,aAAA,CAACf,wBAAwB;IAACwC,IAAI,EAAER,KAAK,CAACW;EAAY,CAAE,CAAC,GAAG,IAAI,eACjF9C,KAAA,CAAAkB,aAAA;IAAK6B,SAAS,EAAEf;EAAqB,gBACjChC,KAAA,CAAAkB,aAAA,CAACd,IAAI;IACDwB,IAAI,EAAC,IAAI;IACToB,OAAO,EAAC,IAAI;IACZC,SAAS,EAAE,IAAK;IAChBZ,IAAI,EAAED,WAAY;IAClBc,YAAY,EAAEV,QAAQ,EAAEf;EAAG,CAC9B,CACA,CACI,CAAC;AAEtB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Operator } from "./evaluateExpression.js";
|
|
2
|
+
export interface OperatorOption {
|
|
3
|
+
value: Operator;
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getOperatorOptions(fieldType: string): OperatorOption[];
|
|
7
|
+
/**
|
|
8
|
+
* Operators that don't need a value input (the value is implicit).
|
|
9
|
+
*/
|
|
10
|
+
export declare const VALUE_HIDDEN_OPERATORS: Set<Operator>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const NUMERIC_OPERATORS = [{
|
|
2
|
+
value: "==",
|
|
3
|
+
label: "Equals"
|
|
4
|
+
}, {
|
|
5
|
+
value: "!=",
|
|
6
|
+
label: "Not equals"
|
|
7
|
+
}, {
|
|
8
|
+
value: ">",
|
|
9
|
+
label: "Greater than"
|
|
10
|
+
}, {
|
|
11
|
+
value: "<",
|
|
12
|
+
label: "Less than"
|
|
13
|
+
}, {
|
|
14
|
+
value: ">=",
|
|
15
|
+
label: "Greater or equal"
|
|
16
|
+
}, {
|
|
17
|
+
value: "<=",
|
|
18
|
+
label: "Less or equal"
|
|
19
|
+
}, {
|
|
20
|
+
value: "isEmpty",
|
|
21
|
+
label: "Is empty"
|
|
22
|
+
}, {
|
|
23
|
+
value: "isNotEmpty",
|
|
24
|
+
label: "Is not empty"
|
|
25
|
+
}];
|
|
26
|
+
const TEXT_OPERATORS = [{
|
|
27
|
+
value: "==",
|
|
28
|
+
label: "Equals"
|
|
29
|
+
}, {
|
|
30
|
+
value: "!=",
|
|
31
|
+
label: "Not equals"
|
|
32
|
+
}, {
|
|
33
|
+
value: "contains",
|
|
34
|
+
label: "Contains"
|
|
35
|
+
}, {
|
|
36
|
+
value: "startsWith",
|
|
37
|
+
label: "Starts with"
|
|
38
|
+
}, {
|
|
39
|
+
value: "endsWith",
|
|
40
|
+
label: "Ends with"
|
|
41
|
+
}, {
|
|
42
|
+
value: "isEmpty",
|
|
43
|
+
label: "Is empty"
|
|
44
|
+
}, {
|
|
45
|
+
value: "isNotEmpty",
|
|
46
|
+
label: "Is not empty"
|
|
47
|
+
}];
|
|
48
|
+
const BOOLEAN_OPERATORS = [{
|
|
49
|
+
value: "==",
|
|
50
|
+
label: "Equals"
|
|
51
|
+
}, {
|
|
52
|
+
value: "!=",
|
|
53
|
+
label: "Not equals"
|
|
54
|
+
}];
|
|
55
|
+
const FILE_OPERATORS = [{
|
|
56
|
+
value: "isEmpty",
|
|
57
|
+
label: "Is empty"
|
|
58
|
+
}, {
|
|
59
|
+
value: "isNotEmpty",
|
|
60
|
+
label: "Is not empty"
|
|
61
|
+
}];
|
|
62
|
+
const DEFAULT_OPERATORS = [{
|
|
63
|
+
value: "==",
|
|
64
|
+
label: "Equals"
|
|
65
|
+
}, {
|
|
66
|
+
value: "!=",
|
|
67
|
+
label: "Not equals"
|
|
68
|
+
}, {
|
|
69
|
+
value: "isEmpty",
|
|
70
|
+
label: "Is empty"
|
|
71
|
+
}, {
|
|
72
|
+
value: "isNotEmpty",
|
|
73
|
+
label: "Is not empty"
|
|
74
|
+
}];
|
|
75
|
+
const OPERATORS_BY_TYPE = {
|
|
76
|
+
number: NUMERIC_OPERATORS,
|
|
77
|
+
datetime: NUMERIC_OPERATORS,
|
|
78
|
+
text: TEXT_OPERATORS,
|
|
79
|
+
"long-text": TEXT_OPERATORS,
|
|
80
|
+
boolean: BOOLEAN_OPERATORS,
|
|
81
|
+
file: FILE_OPERATORS
|
|
82
|
+
};
|
|
83
|
+
export function getOperatorOptions(fieldType) {
|
|
84
|
+
return OPERATORS_BY_TYPE[fieldType] ?? DEFAULT_OPERATORS;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Operators that don't need a value input (the value is implicit).
|
|
89
|
+
*/
|
|
90
|
+
export const VALUE_HIDDEN_OPERATORS = new Set(["isEmpty", "isNotEmpty"]);
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=operatorOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NUMERIC_OPERATORS","value","label","TEXT_OPERATORS","BOOLEAN_OPERATORS","FILE_OPERATORS","DEFAULT_OPERATORS","OPERATORS_BY_TYPE","number","datetime","text","boolean","file","getOperatorOptions","fieldType","VALUE_HIDDEN_OPERATORS","Set"],"sources":["operatorOptions.ts"],"sourcesContent":["import type { Operator } from \"./evaluateExpression.js\";\n\nexport interface OperatorOption {\n value: Operator;\n label: string;\n}\n\nconst NUMERIC_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \">\", label: \"Greater than\" },\n { value: \"<\", label: \"Less than\" },\n { value: \">=\", label: \"Greater or equal\" },\n { value: \"<=\", label: \"Less or equal\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst TEXT_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \"contains\", label: \"Contains\" },\n { value: \"startsWith\", label: \"Starts with\" },\n { value: \"endsWith\", label: \"Ends with\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst BOOLEAN_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" }\n];\n\nconst FILE_OPERATORS: OperatorOption[] = [\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst DEFAULT_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst OPERATORS_BY_TYPE: Record<string, OperatorOption[]> = {\n number: NUMERIC_OPERATORS,\n datetime: NUMERIC_OPERATORS,\n text: TEXT_OPERATORS,\n \"long-text\": TEXT_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n file: FILE_OPERATORS\n};\n\nexport function getOperatorOptions(fieldType: string): OperatorOption[] {\n return OPERATORS_BY_TYPE[fieldType] ?? DEFAULT_OPERATORS;\n}\n\n/**\n * Operators that don't need a value input (the value is implicit).\n */\nexport const VALUE_HIDDEN_OPERATORS: Set<Operator> = new Set([\"isEmpty\", \"isNotEmpty\"]);\n"],"mappings":"AAOA,MAAMA,iBAAmC,GAAG,CACxC;EAAEC,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,GAAG;EAAEC,KAAK,EAAE;AAAe,CAAC,EACrC;EAAED,KAAK,EAAE,GAAG;EAAEC,KAAK,EAAE;AAAY,CAAC,EAClC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAmB,CAAC,EAC1C;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAgB,CAAC,EACvC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMC,cAAgC,GAAG,CACrC;EAAEF,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,UAAU;EAAEC,KAAK,EAAE;AAAW,CAAC,EACxC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAc,CAAC,EAC7C;EAAED,KAAK,EAAE,UAAU;EAAEC,KAAK,EAAE;AAAY,CAAC,EACzC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAME,iBAAmC,GAAG,CACxC;EAAEH,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,CACvC;AAED,MAAMG,cAAgC,GAAG,CACrC;EAAEJ,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMI,iBAAmC,GAAG,CACxC;EAAEL,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMK,iBAAmD,GAAG;EACxDC,MAAM,EAAER,iBAAiB;EACzBS,QAAQ,EAAET,iBAAiB;EAC3BU,IAAI,EAAEP,cAAc;EACpB,WAAW,EAAEA,cAAc;EAC3BQ,OAAO,EAAEP,iBAAiB;EAC1BQ,IAAI,EAAEP;AACV,CAAC;AAED,OAAO,SAASQ,kBAAkBA,CAACC,SAAiB,EAAoB;EACpE,OAAOP,iBAAiB,CAACO,SAAS,CAAC,IAAIR,iBAAiB;AAC5D;;AAEA;AACA;AACA;AACA,OAAO,MAAMS,sBAAqC,GAAG,IAAIC,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC","ignoreList":[]}
|
package/Fields/useBind.d.ts
CHANGED
package/Fields/useBind.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import React, { useRef, cloneElement } from "react";
|
|
1
|
+
import React, { createContext, useContext, useRef, cloneElement } from "react";
|
|
2
2
|
import { useForm } from "@webiny/form";
|
|
3
|
-
import { createValidators } from "../createValidators";
|
|
4
|
-
import { useModelField } from "../ModelFieldProvider";
|
|
5
|
-
import { createValidationContainer } from "../createValidationContainer";
|
|
3
|
+
import { createValidators } from "../createValidators.js";
|
|
4
|
+
import { useModelField } from "../ModelFieldProvider/index.js";
|
|
5
|
+
import { createValidationContainer } from "../createValidationContainer.js";
|
|
6
|
+
const BindParentNameContext = /*#__PURE__*/createContext("");
|
|
7
|
+
export const useBindParentName = () => useContext(BindParentNameContext);
|
|
6
8
|
const createFieldCacheKey = field => {
|
|
7
9
|
return [field.id, field.fieldId, JSON.stringify(field.validation), JSON.stringify(field.listValidation)].join(";");
|
|
8
10
|
};
|
|
@@ -30,7 +32,7 @@ export function useBind({
|
|
|
30
32
|
}
|
|
31
33
|
const validators = createValidators(field, field.validation || emptyValidators);
|
|
32
34
|
const listValidators = createValidators(field, field.listValidation || emptyValidators);
|
|
33
|
-
const isMultipleValues = index === -1 && field.
|
|
35
|
+
const isMultipleValues = index === -1 && field.list;
|
|
34
36
|
const inputValidators = isMultipleValues ? listValidators : validators;
|
|
35
37
|
|
|
36
38
|
// We only use default values for single-value fields.
|
|
@@ -45,7 +47,9 @@ export function useBind({
|
|
|
45
47
|
const {
|
|
46
48
|
field
|
|
47
49
|
} = useModelField();
|
|
48
|
-
return /*#__PURE__*/React.createElement(
|
|
50
|
+
return /*#__PURE__*/React.createElement(BindParentNameContext.Provider, {
|
|
51
|
+
value: name
|
|
52
|
+
}, /*#__PURE__*/React.createElement(Bind, {
|
|
49
53
|
name: childName || name,
|
|
50
54
|
validators: childValidators || inputValidators,
|
|
51
55
|
defaultValue: defaultValue ?? null,
|
|
@@ -57,7 +61,7 @@ export function useBind({
|
|
|
57
61
|
const props = {
|
|
58
62
|
...bind
|
|
59
63
|
};
|
|
60
|
-
if (field.
|
|
64
|
+
if (field.list && index === -1) {
|
|
61
65
|
props.appendValue = (newValue, index) => {
|
|
62
66
|
const currentValue = bind.value || [];
|
|
63
67
|
const newIndex = index ?? currentValue.length;
|
|
@@ -99,7 +103,7 @@ export function useBind({
|
|
|
99
103
|
};
|
|
100
104
|
}
|
|
101
105
|
return typeof children === "function" ? children(props) : /*#__PURE__*/cloneElement(children, props);
|
|
102
|
-
});
|
|
106
|
+
}));
|
|
103
107
|
};
|
|
104
108
|
|
|
105
109
|
// We need to keep track of current field name, to support nested fields.
|
package/Fields/useBind.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useRef","cloneElement","useForm","createValidators","useModelField","createValidationContainer","createFieldCacheKey","field","id","fieldId","JSON","stringify","validation","listValidation","join","emptyValidators","useBind","Bind","memoizedBindComponents","cacheKey","form","index","parentName","name","undefined","filter","v","componentId","current","validators","listValidators","isMultipleValues","multipleValues","inputValidators","defaultValueFromSettings","settings","defaultValue","UseBind","params","childName","childValidators","children","createElement","context","bind","props","appendValue","newValue","currentValue","value","newIndex","length","onChange","slice","prependValue","appendValues","newValues","removeValue","validateInput","moveValueUp","splice","moveValueDown","displayName","ValidationContainer"],"sources":["useBind.tsx"],"sourcesContent":["import React, { useRef, cloneElement } from \"react\";\nimport type { Validator } from \"@webiny/validation/types\";\nimport { useForm } from \"@webiny/form\";\nimport { createValidators } from \"~/createValidators\";\nimport type { BindComponent, CmsModelField } from \"~/types\";\nimport { useModelField } from \"~/ModelFieldProvider\";\nimport { createValidationContainer } from \"~/createValidationContainer\";\n\ninterface UseBindProps {\n Bind: BindComponent;\n}\n\ninterface UseBindParams {\n name?: string;\n validators?: Validator | Validator[];\n children?: any;\n defaultValue?: any;\n}\n\nconst createFieldCacheKey = (field: CmsModelField) => {\n return [\n field.id,\n field.fieldId,\n JSON.stringify(field.validation),\n JSON.stringify(field.listValidation)\n ].join(\";\");\n};\n\nexport interface GetBindCallable {\n (index?: number): BindComponent;\n}\n\nconst emptyValidators: Validator[] = [];\n\nexport function useBind({ Bind }: UseBindProps) {\n const { field } = useModelField();\n const memoizedBindComponents = useRef<Record<string, BindComponent>>({});\n const cacheKey = createFieldCacheKey(field);\n const form = useForm();\n\n return (index = -1) => {\n const { parentName } = Bind;\n\n // If there's a parent name assigned to the given Bind component, we need to include it in the new field \"name\".\n // This allows us to have nested fields (like \"object\" field with nested properties)\n const name = [parentName, field.fieldId, index >= 0 ? index : undefined]\n .filter(v => v !== undefined)\n .join(\".\");\n\n const componentId = `${name};${cacheKey}`;\n\n if (memoizedBindComponents.current[componentId]) {\n return memoizedBindComponents.current[componentId];\n }\n\n const validators = createValidators(field, field.validation || emptyValidators);\n const listValidators = createValidators(field, field.listValidation || emptyValidators);\n const isMultipleValues = index === -1 && field.multipleValues;\n const inputValidators = isMultipleValues ? listValidators : validators;\n\n // We only use default values for single-value fields.\n const defaultValueFromSettings = !isMultipleValues ? field.settings?.defaultValue : null;\n\n memoizedBindComponents.current[componentId] = function UseBind(params: UseBindParams) {\n const {\n name: childName,\n validators: childValidators,\n children,\n defaultValue = defaultValueFromSettings\n } = params;\n\n const { field } = useModelField();\n\n return (\n <Bind\n name={childName || name}\n validators={childValidators || inputValidators}\n defaultValue={defaultValue ?? null}\n context={{ field }}\n >\n {bind => {\n // Multiple-values functions below.\n const props = { ...bind };\n if (field.multipleValues && index === -1) {\n props.appendValue = (newValue: any, index?: number) => {\n const currentValue = bind.value || [];\n const newIndex = index ?? currentValue.length;\n\n bind.onChange([\n ...currentValue.slice(0, newIndex),\n newValue,\n ...currentValue.slice(newIndex)\n ]);\n };\n props.prependValue = (newValue: any) => {\n bind.onChange([newValue, ...(bind.value || [])]);\n };\n props.appendValues = (newValues: any[]) => {\n bind.onChange([...(bind.value || []), ...newValues]);\n };\n\n props.removeValue = (index: number) => {\n if (index < 0) {\n return;\n }\n\n const value = [\n ...bind.value.slice(0, index),\n ...bind.value.slice(index + 1)\n ];\n\n bind.onChange(value.length === 0 ? null : value);\n\n // To make sure the field is still valid, we must trigger validation.\n form.validateInput(field.fieldId);\n };\n\n props.moveValueUp = (index: number) => {\n if (index <= 0) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index - 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n\n props.moveValueDown = (index: number) => {\n if (index >= bind.value.length) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index + 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n }\n\n return typeof children === \"function\"\n ? children(props)\n : cloneElement(children, props);\n }}\n </Bind>\n );\n } as BindComponent;\n\n // We need to keep track of current field name, to support nested fields.\n memoizedBindComponents.current[componentId].parentName = name;\n memoizedBindComponents.current[componentId].displayName = `Bind<${name}>`;\n memoizedBindComponents.current[componentId].ValidationContainer =\n createValidationContainer(name);\n\n return memoizedBindComponents.current[componentId];\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","createContext","useContext","useRef","cloneElement","useForm","createValidators","useModelField","createValidationContainer","BindParentNameContext","useBindParentName","createFieldCacheKey","field","id","fieldId","JSON","stringify","validation","listValidation","join","emptyValidators","useBind","Bind","memoizedBindComponents","cacheKey","form","index","parentName","name","undefined","filter","v","componentId","current","validators","listValidators","isMultipleValues","list","inputValidators","defaultValueFromSettings","settings","defaultValue","UseBind","params","childName","childValidators","children","createElement","Provider","value","context","bind","props","appendValue","newValue","currentValue","newIndex","length","onChange","slice","prependValue","appendValues","newValues","removeValue","validateInput","moveValueUp","splice","moveValueDown","displayName","ValidationContainer"],"sources":["useBind.tsx"],"sourcesContent":["import React, { createContext, useContext, useRef, cloneElement } from \"react\";\nimport type { Validator } from \"@webiny/validation/types.js\";\nimport { useForm } from \"@webiny/form\";\nimport { createValidators } from \"~/createValidators.js\";\nimport type { BindComponent, CmsModelField } from \"~/types/index.js\";\nimport { useModelField } from \"~/ModelFieldProvider/index.js\";\nimport { createValidationContainer } from \"~/createValidationContainer.js\";\n\nconst BindParentNameContext = createContext<string>(\"\");\n\nexport const useBindParentName = (): string => useContext(BindParentNameContext);\n\ninterface UseBindProps {\n Bind: BindComponent;\n}\n\ninterface UseBindParams {\n name?: string;\n validators?: Validator | Validator[];\n children?: any;\n defaultValue?: any;\n}\n\nconst createFieldCacheKey = (field: CmsModelField) => {\n return [\n field.id,\n field.fieldId,\n JSON.stringify(field.validation),\n JSON.stringify(field.listValidation)\n ].join(\";\");\n};\n\nexport interface GetBindCallable {\n (index?: number): BindComponent;\n}\n\nconst emptyValidators: Validator[] = [];\n\nexport function useBind({ Bind }: UseBindProps) {\n const { field } = useModelField();\n const memoizedBindComponents = useRef<Record<string, BindComponent>>({});\n const cacheKey = createFieldCacheKey(field);\n const form = useForm();\n\n return (index = -1) => {\n const { parentName } = Bind;\n\n // If there's a parent name assigned to the given Bind component, we need to include it in the new field \"name\".\n // This allows us to have nested fields (like \"object\" field with nested properties)\n const name = [parentName, field.fieldId, index >= 0 ? index : undefined]\n .filter(v => v !== undefined)\n .join(\".\");\n\n const componentId = `${name};${cacheKey}`;\n\n if (memoizedBindComponents.current[componentId]) {\n return memoizedBindComponents.current[componentId];\n }\n\n const validators = createValidators(field, field.validation || emptyValidators);\n const listValidators = createValidators(field, field.listValidation || emptyValidators);\n const isMultipleValues = index === -1 && field.list;\n const inputValidators = isMultipleValues ? listValidators : validators;\n\n // We only use default values for single-value fields.\n const defaultValueFromSettings = !isMultipleValues ? field.settings?.defaultValue : null;\n\n memoizedBindComponents.current[componentId] = function UseBind(params: UseBindParams) {\n const {\n name: childName,\n validators: childValidators,\n children,\n defaultValue = defaultValueFromSettings\n } = params;\n\n const { field } = useModelField();\n\n return (\n <BindParentNameContext.Provider value={name}>\n <Bind\n name={childName || name}\n validators={childValidators || inputValidators}\n defaultValue={defaultValue ?? null}\n context={{ field }}\n >\n {bind => {\n // Multiple-values functions below.\n const props = { ...bind };\n if (field.list && index === -1) {\n props.appendValue = (newValue: any, index?: number) => {\n const currentValue = bind.value || [];\n const newIndex = index ?? currentValue.length;\n\n bind.onChange([\n ...currentValue.slice(0, newIndex),\n newValue,\n ...currentValue.slice(newIndex)\n ]);\n };\n props.prependValue = (newValue: any) => {\n bind.onChange([newValue, ...(bind.value || [])]);\n };\n props.appendValues = (newValues: any[]) => {\n bind.onChange([...(bind.value || []), ...newValues]);\n };\n\n props.removeValue = (index: number) => {\n if (index < 0) {\n return;\n }\n\n const value = [\n ...bind.value.slice(0, index),\n ...bind.value.slice(index + 1)\n ];\n\n bind.onChange(value.length === 0 ? null : value);\n\n // To make sure the field is still valid, we must trigger validation.\n form.validateInput(field.fieldId);\n };\n\n props.moveValueUp = (index: number) => {\n if (index <= 0) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index - 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n\n props.moveValueDown = (index: number) => {\n if (index >= bind.value.length) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index + 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n }\n\n return typeof children === \"function\"\n ? children(props)\n : cloneElement(children, props);\n }}\n </Bind>\n </BindParentNameContext.Provider>\n );\n } as BindComponent;\n\n // We need to keep track of current field name, to support nested fields.\n memoizedBindComponents.current[componentId].parentName = name;\n memoizedBindComponents.current[componentId].displayName = `Bind<${name}>`;\n memoizedBindComponents.current[componentId].ValidationContainer =\n createValidationContainer(name);\n\n return memoizedBindComponents.current[componentId];\n };\n}\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,UAAU,EAAEC,MAAM,EAAEC,YAAY,QAAQ,OAAO;AAE9E,SAASC,OAAO,QAAQ,cAAc;AACtC,SAASC,gBAAgB;AAEzB,SAASC,aAAa;AACtB,SAASC,yBAAyB;AAElC,MAAMC,qBAAqB,gBAAGR,aAAa,CAAS,EAAE,CAAC;AAEvD,OAAO,MAAMS,iBAAiB,GAAGA,CAAA,KAAcR,UAAU,CAACO,qBAAqB,CAAC;AAahF,MAAME,mBAAmB,GAAIC,KAAoB,IAAK;EAClD,OAAO,CACHA,KAAK,CAACC,EAAE,EACRD,KAAK,CAACE,OAAO,EACbC,IAAI,CAACC,SAAS,CAACJ,KAAK,CAACK,UAAU,CAAC,EAChCF,IAAI,CAACC,SAAS,CAACJ,KAAK,CAACM,cAAc,CAAC,CACvC,CAACC,IAAI,CAAC,GAAG,CAAC;AACf,CAAC;AAMD,MAAMC,eAA4B,GAAG,EAAE;AAEvC,OAAO,SAASC,OAAOA,CAAC;EAAEC;AAAmB,CAAC,EAAE;EAC5C,MAAM;IAAEV;EAAM,CAAC,GAAGL,aAAa,CAAC,CAAC;EACjC,MAAMgB,sBAAsB,GAAGpB,MAAM,CAAgC,CAAC,CAAC,CAAC;EACxE,MAAMqB,QAAQ,GAAGb,mBAAmB,CAACC,KAAK,CAAC;EAC3C,MAAMa,IAAI,GAAGpB,OAAO,CAAC,CAAC;EAEtB,OAAO,CAACqB,KAAK,GAAG,CAAC,CAAC,KAAK;IACnB,MAAM;MAAEC;IAAW,CAAC,GAAGL,IAAI;;IAE3B;IACA;IACA,MAAMM,IAAI,GAAG,CAACD,UAAU,EAAEf,KAAK,CAACE,OAAO,EAAEY,KAAK,IAAI,CAAC,GAAGA,KAAK,GAAGG,SAAS,CAAC,CACnEC,MAAM,CAACC,CAAC,IAAIA,CAAC,KAAKF,SAAS,CAAC,CAC5BV,IAAI,CAAC,GAAG,CAAC;IAEd,MAAMa,WAAW,GAAG,GAAGJ,IAAI,IAAIJ,QAAQ,EAAE;IAEzC,IAAID,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC,EAAE;MAC7C,OAAOT,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC;IACtD;IAEA,MAAME,UAAU,GAAG5B,gBAAgB,CAACM,KAAK,EAAEA,KAAK,CAACK,UAAU,IAAIG,eAAe,CAAC;IAC/E,MAAMe,cAAc,GAAG7B,gBAAgB,CAACM,KAAK,EAAEA,KAAK,CAACM,cAAc,IAAIE,eAAe,CAAC;IACvF,MAAMgB,gBAAgB,GAAGV,KAAK,KAAK,CAAC,CAAC,IAAId,KAAK,CAACyB,IAAI;IACnD,MAAMC,eAAe,GAAGF,gBAAgB,GAAGD,cAAc,GAAGD,UAAU;;IAEtE;IACA,MAAMK,wBAAwB,GAAG,CAACH,gBAAgB,GAAGxB,KAAK,CAAC4B,QAAQ,EAAEC,YAAY,GAAG,IAAI;IAExFlB,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC,GAAG,SAASU,OAAOA,CAACC,MAAqB,EAAE;MAClF,MAAM;QACFf,IAAI,EAAEgB,SAAS;QACfV,UAAU,EAAEW,eAAe;QAC3BC,QAAQ;QACRL,YAAY,GAAGF;MACnB,CAAC,GAAGI,MAAM;MAEV,MAAM;QAAE/B;MAAM,CAAC,GAAGL,aAAa,CAAC,CAAC;MAEjC,oBACIP,KAAA,CAAA+C,aAAA,CAACtC,qBAAqB,CAACuC,QAAQ;QAACC,KAAK,EAAErB;MAAK,gBACxC5B,KAAA,CAAA+C,aAAA,CAACzB,IAAI;QACDM,IAAI,EAAEgB,SAAS,IAAIhB,IAAK;QACxBM,UAAU,EAAEW,eAAe,IAAIP,eAAgB;QAC/CG,YAAY,EAAEA,YAAY,IAAI,IAAK;QACnCS,OAAO,EAAE;UAAEtC;QAAM;MAAE,GAElBuC,IAAI,IAAI;QACL;QACA,MAAMC,KAAK,GAAG;UAAE,GAAGD;QAAK,CAAC;QACzB,IAAIvC,KAAK,CAACyB,IAAI,IAAIX,KAAK,KAAK,CAAC,CAAC,EAAE;UAC5B0B,KAAK,CAACC,WAAW,GAAG,CAACC,QAAa,EAAE5B,KAAc,KAAK;YACnD,MAAM6B,YAAY,GAAGJ,IAAI,CAACF,KAAK,IAAI,EAAE;YACrC,MAAMO,QAAQ,GAAG9B,KAAK,IAAI6B,YAAY,CAACE,MAAM;YAE7CN,IAAI,CAACO,QAAQ,CAAC,CACV,GAAGH,YAAY,CAACI,KAAK,CAAC,CAAC,EAAEH,QAAQ,CAAC,EAClCF,QAAQ,EACR,GAAGC,YAAY,CAACI,KAAK,CAACH,QAAQ,CAAC,CAClC,CAAC;UACN,CAAC;UACDJ,KAAK,CAACQ,YAAY,GAAIN,QAAa,IAAK;YACpCH,IAAI,CAACO,QAAQ,CAAC,CAACJ,QAAQ,EAAE,IAAIH,IAAI,CAACF,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;UACpD,CAAC;UACDG,KAAK,CAACS,YAAY,GAAIC,SAAgB,IAAK;YACvCX,IAAI,CAACO,QAAQ,CAAC,CAAC,IAAIP,IAAI,CAACF,KAAK,IAAI,EAAE,CAAC,EAAE,GAAGa,SAAS,CAAC,CAAC;UACxD,CAAC;UAEDV,KAAK,CAACW,WAAW,GAAIrC,KAAa,IAAK;YACnC,IAAIA,KAAK,GAAG,CAAC,EAAE;cACX;YACJ;YAEA,MAAMuB,KAAK,GAAG,CACV,GAAGE,IAAI,CAACF,KAAK,CAACU,KAAK,CAAC,CAAC,EAAEjC,KAAK,CAAC,EAC7B,GAAGyB,IAAI,CAACF,KAAK,CAACU,KAAK,CAACjC,KAAK,GAAG,CAAC,CAAC,CACjC;YAEDyB,IAAI,CAACO,QAAQ,CAACT,KAAK,CAACQ,MAAM,KAAK,CAAC,GAAG,IAAI,GAAGR,KAAK,CAAC;;YAEhD;YACAxB,IAAI,CAACuC,aAAa,CAACpD,KAAK,CAACE,OAAO,CAAC;UACrC,CAAC;UAEDsC,KAAK,CAACa,WAAW,GAAIvC,KAAa,IAAK;YACnC,IAAIA,KAAK,IAAI,CAAC,EAAE;cACZ;YACJ;YAEA,MAAMuB,KAAK,GAAG,CAAC,GAAGE,IAAI,CAACF,KAAK,CAAC;YAC7BA,KAAK,CAACiB,MAAM,CAACxC,KAAK,EAAE,CAAC,CAAC;YACtBuB,KAAK,CAACiB,MAAM,CAACxC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAEyB,IAAI,CAACF,KAAK,CAACvB,KAAK,CAAC,CAAC;YAE7CyB,IAAI,CAACO,QAAQ,CAACT,KAAK,CAAC;UACxB,CAAC;UAEDG,KAAK,CAACe,aAAa,GAAIzC,KAAa,IAAK;YACrC,IAAIA,KAAK,IAAIyB,IAAI,CAACF,KAAK,CAACQ,MAAM,EAAE;cAC5B;YACJ;YAEA,MAAMR,KAAK,GAAG,CAAC,GAAGE,IAAI,CAACF,KAAK,CAAC;YAC7BA,KAAK,CAACiB,MAAM,CAACxC,KAAK,EAAE,CAAC,CAAC;YACtBuB,KAAK,CAACiB,MAAM,CAACxC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAEyB,IAAI,CAACF,KAAK,CAACvB,KAAK,CAAC,CAAC;YAE7CyB,IAAI,CAACO,QAAQ,CAACT,KAAK,CAAC;UACxB,CAAC;QACL;QAEA,OAAO,OAAOH,QAAQ,KAAK,UAAU,GAC/BA,QAAQ,CAACM,KAAK,CAAC,gBACfhD,YAAY,CAAC0C,QAAQ,EAAEM,KAAK,CAAC;MACvC,CACE,CACsB,CAAC;IAEzC,CAAkB;;IAElB;IACA7B,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC,CAACL,UAAU,GAAGC,IAAI;IAC7DL,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC,CAACoC,WAAW,GAAG,QAAQxC,IAAI,GAAG;IACzEL,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC,CAACqC,mBAAmB,GAC3D7D,yBAAyB,CAACoB,IAAI,CAAC;IAEnC,OAAOL,sBAAsB,CAACU,OAAO,CAACD,WAAW,CAAC;EACtD,CAAC;AACL","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FieldRule } from "../types/model.js";
|
|
2
|
+
export interface EffectiveFieldRules {
|
|
3
|
+
canView: boolean;
|
|
4
|
+
canEdit: boolean;
|
|
5
|
+
hidden: boolean;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface HasRules {
|
|
9
|
+
rules?: FieldRule[];
|
|
10
|
+
}
|
|
11
|
+
interface IdentityLike {
|
|
12
|
+
id: string;
|
|
13
|
+
teams: {
|
|
14
|
+
slug: string;
|
|
15
|
+
}[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Hook that evaluates access control rules for the current identity.
|
|
19
|
+
* Does not require `bindParentName` — only identity-based permissions.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useFieldAccessControlRules(item: HasRules): Pick<EffectiveFieldRules, "canView" | "canEdit">;
|
|
22
|
+
/**
|
|
23
|
+
* Evaluate access control rules statically (without hooks).
|
|
24
|
+
* Used in RowRenderer for the visibility approximation where hooks can't be called.
|
|
25
|
+
*/
|
|
26
|
+
export declare function evaluateAccessControlRules(item: HasRules, identity: IdentityLike): EffectiveFieldRules;
|
|
27
|
+
/**
|
|
28
|
+
* Composes useParentRules and useFieldRules into a single hook
|
|
29
|
+
* that returns the effective (intersected) rules.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useFieldEffectiveRules(item: HasRules): EffectiveFieldRules;
|
|
32
|
+
export {};
|