@webiny/app-headless-cms-common 6.0.0-rc.1 → 6.0.0-rc.3

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.
Files changed (61) hide show
  1. package/Fields/FieldRulesProvider.d.ts +9 -0
  2. package/Fields/FieldRulesProvider.js +20 -0
  3. package/Fields/FieldRulesProvider.js.map +1 -0
  4. package/Fields/Fields.js +127 -14
  5. package/Fields/Fields.js.map +1 -1
  6. package/Fields/LayoutDescriptorCell.d.ts +12 -0
  7. package/Fields/LayoutDescriptorCell.js +47 -0
  8. package/Fields/LayoutDescriptorCell.js.map +1 -0
  9. package/Fields/evaluateExpression.d.ts +23 -0
  10. package/Fields/evaluateExpression.js +102 -0
  11. package/Fields/evaluateExpression.js.map +1 -0
  12. package/Fields/fieldOptions.d.ts +36 -0
  13. package/Fields/fieldOptions.js +113 -0
  14. package/Fields/fieldOptions.js.map +1 -0
  15. package/Fields/index.d.ts +5 -0
  16. package/Fields/index.js +5 -0
  17. package/Fields/index.js.map +1 -1
  18. package/Fields/layoutFieldRenderers/AlertFieldRenderer.d.ts +7 -0
  19. package/Fields/layoutFieldRenderers/AlertFieldRenderer.js +13 -0
  20. package/Fields/layoutFieldRenderers/AlertFieldRenderer.js.map +1 -0
  21. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.d.ts +7 -0
  22. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js +18 -0
  23. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js.map +1 -0
  24. package/Fields/layoutFieldRenderers/TabsFieldRenderer.d.ts +12 -0
  25. package/Fields/layoutFieldRenderers/TabsFieldRenderer.js +72 -0
  26. package/Fields/layoutFieldRenderers/TabsFieldRenderer.js.map +1 -0
  27. package/Fields/operatorOptions.d.ts +10 -0
  28. package/Fields/operatorOptions.js +92 -0
  29. package/Fields/operatorOptions.js.map +1 -0
  30. package/Fields/useBind.d.ts +1 -0
  31. package/Fields/useBind.js +7 -3
  32. package/Fields/useBind.js.map +1 -1
  33. package/Fields/useFieldRules.d.ts +32 -0
  34. package/Fields/useFieldRules.js +153 -0
  35. package/Fields/useFieldRules.js.map +1 -0
  36. package/ModelFieldProvider/CanEditField.d.ts +5 -0
  37. package/ModelFieldProvider/CanEditField.js +13 -0
  38. package/ModelFieldProvider/CanEditField.js.map +1 -0
  39. package/ModelFieldProvider/ModelFieldContext.d.ts +1 -0
  40. package/ModelFieldProvider/index.d.ts +1 -0
  41. package/ModelFieldProvider/index.js +1 -0
  42. package/ModelFieldProvider/index.js.map +1 -1
  43. package/ModelFieldProvider/useModelField.js +1 -1
  44. package/ModelFieldProvider/useModelField.js.map +1 -1
  45. package/entries.graphql.js +3 -0
  46. package/entries.graphql.js.map +1 -1
  47. package/exports/admin/cms/model.d.ts +2 -0
  48. package/exports/admin/cms/model.js +3 -0
  49. package/exports/admin/cms/model.js.map +1 -0
  50. package/exports/admin/cms.d.ts +1 -1
  51. package/exports/admin/cms.js.map +1 -1
  52. package/normalizeIcon.d.ts +3 -0
  53. package/normalizeIcon.js +10 -0
  54. package/normalizeIcon.js.map +1 -0
  55. package/package.json +12 -11
  56. package/types/index.d.ts +66 -3
  57. package/types/index.js +51 -1
  58. package/types/index.js.map +1 -1
  59. package/types/model.d.ts +53 -2
  60. package/types/model.js +27 -1
  61. package/types/model.js.map +1 -1
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { EffectiveFieldRules } from "./useFieldRules.js";
3
+ interface FieldRulesProviderProps {
4
+ rules: EffectiveFieldRules;
5
+ children: React.ReactNode;
6
+ }
7
+ export declare const FieldRulesProvider: ({ rules, children }: FieldRulesProviderProps) => React.JSX.Element;
8
+ export declare const useParentRules: () => EffectiveFieldRules;
9
+ export {};
@@ -0,0 +1,20 @@
1
+ import React, { createContext, useContext } from "react";
2
+ const FieldRulesContext = /*#__PURE__*/createContext({
3
+ canView: true,
4
+ canEdit: true,
5
+ hidden: false,
6
+ disabled: false
7
+ });
8
+ export const FieldRulesProvider = ({
9
+ rules,
10
+ children
11
+ }) => {
12
+ return /*#__PURE__*/React.createElement(FieldRulesContext.Provider, {
13
+ value: rules
14
+ }, children);
15
+ };
16
+ export const useParentRules = () => {
17
+ return useContext(FieldRulesContext);
18
+ };
19
+
20
+ //# sourceMappingURL=FieldRulesProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","createContext","useContext","FieldRulesContext","canView","canEdit","hidden","disabled","FieldRulesProvider","rules","children","createElement","Provider","value","useParentRules"],"sources":["FieldRulesProvider.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { EffectiveFieldRules } from \"./useFieldRules.js\";\n\nconst FieldRulesContext = createContext<EffectiveFieldRules>({\n canView: true,\n canEdit: true,\n hidden: false,\n disabled: false\n});\n\ninterface FieldRulesProviderProps {\n rules: EffectiveFieldRules;\n children: React.ReactNode;\n}\n\nexport const FieldRulesProvider = ({ rules, children }: FieldRulesProviderProps) => {\n return <FieldRulesContext.Provider value={rules}>{children}</FieldRulesContext.Provider>;\n};\n\nexport const useParentRules = (): EffectiveFieldRules => {\n return useContext(FieldRulesContext);\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,UAAU,QAAQ,OAAO;AAGxD,MAAMC,iBAAiB,gBAAGF,aAAa,CAAsB;EACzDG,OAAO,EAAE,IAAI;EACbC,OAAO,EAAE,IAAI;EACbC,MAAM,EAAE,KAAK;EACbC,QAAQ,EAAE;AACd,CAAC,CAAC;AAOF,OAAO,MAAMC,kBAAkB,GAAGA,CAAC;EAAEC,KAAK;EAAEC;AAAkC,CAAC,KAAK;EAChF,oBAAOV,KAAA,CAAAW,aAAA,CAACR,iBAAiB,CAACS,QAAQ;IAACC,KAAK,EAAEJ;EAAM,GAAEC,QAAqC,CAAC;AAC5F,CAAC;AAED,OAAO,MAAMI,cAAc,GAAGA,CAAA,KAA2B;EACrD,OAAOZ,UAAU,CAACC,iBAAiB,CAAC;AACxC,CAAC","ignoreList":[]}
package/Fields/Fields.js CHANGED
@@ -2,6 +2,11 @@ import React from "react";
2
2
  import { Alert, Grid } from "@webiny/admin-ui";
3
3
  import { FieldElement } from "./FieldElement.js";
4
4
  import { FieldElementError } from "./FieldElementError.js";
5
+ import { isLayoutDescriptor } from "../types/model.js";
6
+ import { LayoutDescriptorCell } from "./LayoutDescriptorCell.js";
7
+ import { useAuthentication } from "@webiny/app-admin";
8
+ import { FieldRulesProvider, useParentRules } from "./FieldRulesProvider.js";
9
+ import { evaluateAccessControlRules, useEffectiveRules } from "./useFieldRules.js";
5
10
  const getFieldById = (fields, id) => {
6
11
  return fields.find(field => field.id === id) || null;
7
12
  };
@@ -10,6 +15,121 @@ const LayoutNotDefined = () => {
10
15
  type: "warning"
11
16
  }, "You are missing the layout definition in your code content model. Please ensure you have the layout property correctly defined.");
12
17
  };
18
+
19
+ /**
20
+ * Renders a single layout descriptor cell with rules + permissions.
21
+ */
22
+
23
+ const LayoutCell = ({
24
+ cell,
25
+ Bind,
26
+ fields,
27
+ contentModel,
28
+ gridClassName
29
+ }) => {
30
+ const isLayout = isLayoutDescriptor(cell);
31
+ const rules = useEffectiveRules(isLayout ? cell : {});
32
+ if (!isLayout) {
33
+ return null;
34
+ }
35
+ if (!rules.canView || rules.hidden) {
36
+ return null;
37
+ }
38
+ return /*#__PURE__*/React.createElement(FieldRulesProvider, {
39
+ rules: rules
40
+ }, /*#__PURE__*/React.createElement(LayoutDescriptorCell, {
41
+ descriptor: cell,
42
+ Bind: Bind,
43
+ fields: fields,
44
+ contentModel: contentModel,
45
+ gridClassName: gridClassName
46
+ }));
47
+ };
48
+
49
+ /**
50
+ * Renders a single data field cell with rules + permissions.
51
+ */
52
+
53
+ const FieldCell = ({
54
+ id,
55
+ field,
56
+ span,
57
+ Bind,
58
+ contentModel
59
+ }) => {
60
+ const rules = useEffectiveRules(field ?? {});
61
+ if (!rules.canView || rules.hidden) {
62
+ return null;
63
+ }
64
+ return /*#__PURE__*/React.createElement(Grid.Column, {
65
+ span: span
66
+ }, field ? /*#__PURE__*/React.createElement(FieldRulesProvider, {
67
+ rules: rules
68
+ }, /*#__PURE__*/React.createElement(FieldElement, {
69
+ field: field,
70
+ Bind: Bind,
71
+ contentModel: contentModel
72
+ })) : /*#__PURE__*/React.createElement(FieldElementError, {
73
+ title: `Missing field with id "${id}"!`,
74
+ description: "Make sure field layout contains the correct field ids (hint: check for typos)."
75
+ }));
76
+ };
77
+
78
+ /**
79
+ * Renders a single row, delegating each cell to FieldCell or LayoutCell.
80
+ */
81
+
82
+ const RowRenderer = ({
83
+ row,
84
+ fields,
85
+ Bind,
86
+ contentModel,
87
+ gridClassName
88
+ }) => {
89
+ const {
90
+ identity
91
+ } = useAuthentication();
92
+ const parentRules = useParentRules();
93
+
94
+ // Count visible string cells for column span calculation.
95
+ // This count is approximate based on access control rules only (not entry value rules),
96
+ // because entry value rules require per-field hooks and we can't call them in a filter.
97
+ // The actual visibility is enforced in FieldCell.
98
+ const visibleStringCells = row.filter(c => {
99
+ if (typeof c !== "string") {
100
+ return false;
101
+ }
102
+ const f = getFieldById(fields, c);
103
+ if (!f) {
104
+ return true;
105
+ }
106
+ const acPerms = evaluateAccessControlRules(f, identity);
107
+ return parentRules.canView && acPerms.canView;
108
+ });
109
+ const span = visibleStringCells.length > 0 ? Math.floor(12 / visibleStringCells.length) : 12;
110
+ return /*#__PURE__*/React.createElement(React.Fragment, null, row.map(cell => {
111
+ if (isLayoutDescriptor(cell)) {
112
+ return /*#__PURE__*/React.createElement(LayoutCell, {
113
+ key: cell.id,
114
+ cell: cell,
115
+ Bind: Bind,
116
+ fields: fields,
117
+ contentModel: contentModel,
118
+ gridClassName: gridClassName
119
+ });
120
+ }
121
+ const id = cell;
122
+ const field = getFieldById(fields, id);
123
+ return /*#__PURE__*/React.createElement(FieldCell, {
124
+ key: id,
125
+ id: id,
126
+ field: field,
127
+ span: span,
128
+ Bind: Bind,
129
+ contentModel: contentModel
130
+ });
131
+ }));
132
+ };
13
133
  export const Fields = ({
14
134
  Bind,
15
135
  fields,
@@ -17,26 +137,19 @@ export const Fields = ({
17
137
  contentModel,
18
138
  gridClassName
19
139
  }) => {
20
- if (fields.length > 0 && layout.length === 0) {
140
+ if (contentModel.plugin && fields.length > 0 && layout.length === 0) {
21
141
  return /*#__PURE__*/React.createElement(LayoutNotDefined, null);
22
142
  }
23
143
  return /*#__PURE__*/React.createElement(Grid, {
24
144
  className: gridClassName
25
145
  }, layout.map((row, rowIndex) => /*#__PURE__*/React.createElement(React.Fragment, {
26
146
  key: rowIndex
27
- }, row.map(id => {
28
- const field = getFieldById(fields, id);
29
- return /*#__PURE__*/React.createElement(Grid.Column, {
30
- span: Math.floor(12 / row.length),
31
- key: id
32
- }, field ? /*#__PURE__*/React.createElement(FieldElement, {
33
- field: field,
34
- Bind: Bind,
35
- contentModel: contentModel
36
- }) : /*#__PURE__*/React.createElement(FieldElementError, {
37
- title: `Missing field with id "${id}"!`,
38
- description: "Make sure field layout contains the correct field ids (hint: check for typos)."
39
- }));
147
+ }, /*#__PURE__*/React.createElement(RowRenderer, {
148
+ row: row,
149
+ fields: fields,
150
+ Bind: Bind,
151
+ contentModel: contentModel,
152
+ gridClassName: gridClassName
40
153
  }))));
41
154
  };
42
155
 
@@ -1 +1 @@
1
- {"version":3,"names":["React","Alert","Grid","FieldElement","FieldElementError","getFieldById","fields","id","find","field","LayoutNotDefined","createElement","type","Fields","Bind","layout","contentModel","gridClassName","length","className","map","row","rowIndex","Fragment","key","Column","span","Math","floor","title","description"],"sources":["Fields.tsx"],"sourcesContent":["import React from \"react\";\nimport { Alert, type ColumnProps, Grid } from \"@webiny/admin-ui\";\nimport { FieldElement } from \"./FieldElement.js\";\nimport { FieldElementError } from \"./FieldElementError.js\";\nimport type {\n BindComponent,\n CmsEditorContentModel,\n CmsEditorFieldsLayout,\n CmsModelField\n} from \"~/types/index.js\";\n\ninterface FieldsProps {\n Bind: BindComponent;\n contentModel: CmsEditorContentModel;\n fields: CmsModelField[];\n layout: CmsEditorFieldsLayout;\n gridClassName?: string;\n}\n\nconst getFieldById = (fields: CmsModelField[], id: string): CmsModelField | null => {\n return fields.find(field => field.id === id) || null;\n};\n\nconst LayoutNotDefined = () => {\n return (\n <Alert type={\"warning\"}>\n You are missing the layout definition in your code content model. Please ensure you have\n the layout property correctly defined.\n </Alert>\n );\n};\n\nexport const Fields = ({ Bind, fields, layout, contentModel, gridClassName }: FieldsProps) => {\n if (fields.length > 0 && layout.length === 0) {\n return <LayoutNotDefined />;\n }\n\n return (\n <Grid className={gridClassName}>\n {layout.map((row, rowIndex) => (\n <React.Fragment key={rowIndex}>\n {row.map(id => {\n const field = getFieldById(fields, id) as CmsModelField;\n\n return (\n <Grid.Column\n span={Math.floor(12 / row.length) as ColumnProps[\"span\"]}\n key={id}\n >\n {field ? (\n <FieldElement\n field={field}\n Bind={Bind}\n contentModel={contentModel}\n />\n ) : (\n <FieldElementError\n title={`Missing field with id \"${id}\"!`}\n description={\n \"Make sure field layout contains the correct field ids (hint: check for typos).\"\n }\n />\n )}\n </Grid.Column>\n );\n })}\n </React.Fragment>\n ))}\n </Grid>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,KAAK,EAAoBC,IAAI,QAAQ,kBAAkB;AAChE,SAASC,YAAY;AACrB,SAASC,iBAAiB;AAgB1B,MAAMC,YAAY,GAAGA,CAACC,MAAuB,EAAEC,EAAU,KAA2B;EAChF,OAAOD,MAAM,CAACE,IAAI,CAACC,KAAK,IAAIA,KAAK,CAACF,EAAE,KAAKA,EAAE,CAAC,IAAI,IAAI;AACxD,CAAC;AAED,MAAMG,gBAAgB,GAAGA,CAAA,KAAM;EAC3B,oBACIV,KAAA,CAAAW,aAAA,CAACV,KAAK;IAACW,IAAI,EAAE;EAAU,GAAC,iIAGjB,CAAC;AAEhB,CAAC;AAED,OAAO,MAAMC,MAAM,GAAGA,CAAC;EAAEC,IAAI;EAAER,MAAM;EAAES,MAAM;EAAEC,YAAY;EAAEC;AAA2B,CAAC,KAAK;EAC1F,IAAIX,MAAM,CAACY,MAAM,GAAG,CAAC,IAAIH,MAAM,CAACG,MAAM,KAAK,CAAC,EAAE;IAC1C,oBAAOlB,KAAA,CAAAW,aAAA,CAACD,gBAAgB,MAAE,CAAC;EAC/B;EAEA,oBACIV,KAAA,CAAAW,aAAA,CAACT,IAAI;IAACiB,SAAS,EAAEF;EAAc,GAC1BF,MAAM,CAACK,GAAG,CAAC,CAACC,GAAG,EAAEC,QAAQ,kBACtBtB,KAAA,CAAAW,aAAA,CAACX,KAAK,CAACuB,QAAQ;IAACC,GAAG,EAAEF;EAAS,GACzBD,GAAG,CAACD,GAAG,CAACb,EAAE,IAAI;IACX,MAAME,KAAK,GAAGJ,YAAY,CAACC,MAAM,EAAEC,EAAE,CAAkB;IAEvD,oBACIP,KAAA,CAAAW,aAAA,CAACT,IAAI,CAACuB,MAAM;MACRC,IAAI,EAAEC,IAAI,CAACC,KAAK,CAAC,EAAE,GAAGP,GAAG,CAACH,MAAM,CAAyB;MACzDM,GAAG,EAAEjB;IAAG,GAEPE,KAAK,gBACFT,KAAA,CAAAW,aAAA,CAACR,YAAY;MACTM,KAAK,EAAEA,KAAM;MACbK,IAAI,EAAEA,IAAK;MACXE,YAAY,EAAEA;IAAa,CAC9B,CAAC,gBAEFhB,KAAA,CAAAW,aAAA,CAACP,iBAAiB;MACdyB,KAAK,EAAE,0BAA0BtB,EAAE,IAAK;MACxCuB,WAAW,EACP;IACH,CACJ,CAEI,CAAC;EAEtB,CAAC,CACW,CACnB,CACC,CAAC;AAEf,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","Alert","Grid","FieldElement","FieldElementError","isLayoutDescriptor","LayoutDescriptorCell","useAuthentication","FieldRulesProvider","useParentRules","evaluateAccessControlRules","useEffectiveRules","getFieldById","fields","id","find","field","LayoutNotDefined","createElement","type","LayoutCell","cell","Bind","contentModel","gridClassName","isLayout","rules","canView","hidden","descriptor","FieldCell","span","Column","title","description","RowRenderer","row","identity","parentRules","visibleStringCells","filter","c","f","acPerms","length","Math","floor","Fragment","map","key","Fields","layout","plugin","className","rowIndex"],"sources":["Fields.tsx"],"sourcesContent":["import React from \"react\";\nimport { Alert, type ColumnProps, Grid } from \"@webiny/admin-ui\";\nimport { FieldElement } from \"./FieldElement.js\";\nimport { FieldElementError } from \"./FieldElementError.js\";\nimport type {\n BindComponent,\n CmsEditorContentModel,\n CmsEditorFieldsLayout,\n CmsModelField\n} from \"~/types/index.js\";\nimport type { CmsEditorLayoutCell } from \"~/types/model.js\";\nimport { isLayoutDescriptor } from \"~/types/model.js\";\nimport { LayoutDescriptorCell } from \"./LayoutDescriptorCell.js\";\nimport { useAuthentication } from \"@webiny/app-admin\";\nimport { FieldRulesProvider, useParentRules } from \"./FieldRulesProvider.js\";\nimport { evaluateAccessControlRules, useEffectiveRules } from \"./useFieldRules.js\";\n\ninterface FieldsProps {\n Bind: BindComponent;\n contentModel: CmsEditorContentModel;\n fields: CmsModelField[];\n layout: CmsEditorFieldsLayout;\n gridClassName?: string;\n}\n\nconst getFieldById = (fields: CmsModelField[], id: string): CmsModelField | null => {\n return fields.find(field => field.id === id) || null;\n};\n\nconst LayoutNotDefined = () => {\n return (\n <Alert type={\"warning\"}>\n You are missing the layout definition in your code content model. Please ensure you have\n the layout property correctly defined.\n </Alert>\n );\n};\n\n/**\n * Renders a single layout descriptor cell with rules + permissions.\n */\ninterface LayoutCellProps {\n cell: CmsEditorLayoutCell;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\nconst LayoutCell = ({ cell, Bind, fields, contentModel, gridClassName }: LayoutCellProps) => {\n const isLayout = isLayoutDescriptor(cell);\n const rules = useEffectiveRules(isLayout ? cell : {});\n\n if (!isLayout) {\n return null;\n }\n\n if (!rules.canView || rules.hidden) {\n return null;\n }\n\n return (\n <FieldRulesProvider rules={rules}>\n <LayoutDescriptorCell\n descriptor={cell}\n Bind={Bind}\n fields={fields}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n </FieldRulesProvider>\n );\n};\n\n/**\n * Renders a single data field cell with rules + permissions.\n */\ninterface FieldCellProps {\n id: string;\n field: CmsModelField | null;\n span: ColumnProps[\"span\"];\n Bind: BindComponent;\n contentModel: CmsEditorContentModel;\n}\n\nconst FieldCell = ({ id, field, span, Bind, contentModel }: FieldCellProps) => {\n const rules = useEffectiveRules(field ?? {});\n\n if (!rules.canView || rules.hidden) {\n return null;\n }\n\n return (\n <Grid.Column span={span}>\n {field ? (\n <FieldRulesProvider rules={rules}>\n <FieldElement field={field} Bind={Bind} contentModel={contentModel} />\n </FieldRulesProvider>\n ) : (\n <FieldElementError\n title={`Missing field with id \"${id}\"!`}\n description={\n \"Make sure field layout contains the correct field ids (hint: check for typos).\"\n }\n />\n )}\n </Grid.Column>\n );\n};\n\n/**\n * Renders a single row, delegating each cell to FieldCell or LayoutCell.\n */\ninterface RowRendererProps {\n row: CmsEditorLayoutCell[];\n fields: CmsModelField[];\n Bind: BindComponent;\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\nconst RowRenderer = ({ row, fields, Bind, contentModel, gridClassName }: RowRendererProps) => {\n const { identity } = useAuthentication();\n const parentRules = useParentRules();\n\n // Count visible string cells for column span calculation.\n // This count is approximate based on access control rules only (not entry value rules),\n // because entry value rules require per-field hooks and we can't call them in a filter.\n // The actual visibility is enforced in FieldCell.\n const visibleStringCells = row.filter(c => {\n if (typeof c !== \"string\") {\n return false;\n }\n const f = getFieldById(fields, c);\n if (!f) {\n return true;\n }\n const acPerms = evaluateAccessControlRules(f, identity);\n return parentRules.canView && acPerms.canView;\n });\n\n const span =\n visibleStringCells.length > 0\n ? (Math.floor(12 / visibleStringCells.length) as ColumnProps[\"span\"])\n : (12 as ColumnProps[\"span\"]);\n\n return (\n <>\n {row.map(cell => {\n if (isLayoutDescriptor(cell)) {\n return (\n <LayoutCell\n key={cell.id}\n cell={cell}\n Bind={Bind}\n fields={fields}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n );\n }\n\n const id = cell as string;\n const field = getFieldById(fields, id);\n\n return (\n <FieldCell\n key={id}\n id={id}\n field={field}\n span={span}\n Bind={Bind}\n contentModel={contentModel}\n />\n );\n })}\n </>\n );\n};\n\nexport const Fields = ({ Bind, fields, layout, contentModel, gridClassName }: FieldsProps) => {\n if (contentModel.plugin && fields.length > 0 && layout.length === 0) {\n return <LayoutNotDefined />;\n }\n\n return (\n <Grid className={gridClassName}>\n {layout.map((row, rowIndex) => (\n <React.Fragment key={rowIndex}>\n <RowRenderer\n row={row}\n fields={fields}\n Bind={Bind}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n </React.Fragment>\n ))}\n </Grid>\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { CmsLayoutDescriptor } from "../types/model.js";
3
+ import type { BindComponent, CmsEditorContentModel, CmsModelField } from "../types/index.js";
4
+ interface LayoutDescriptorCellProps {
5
+ descriptor: CmsLayoutDescriptor;
6
+ Bind: BindComponent;
7
+ fields: CmsModelField[];
8
+ contentModel: CmsEditorContentModel;
9
+ gridClassName?: string;
10
+ }
11
+ export declare const LayoutDescriptorCell: ({ descriptor, Bind, fields, contentModel, gridClassName }: LayoutDescriptorCellProps) => React.JSX.Element | null;
12
+ export {};
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+ import { plugins } from "@webiny/plugins";
3
+ import { SeparatorFieldRenderer } from "./layoutFieldRenderers/SeparatorFieldRenderer.js";
4
+ import { AlertFieldRenderer } from "./layoutFieldRenderers/AlertFieldRenderer.js";
5
+ import { TabsFieldRenderer } from "./layoutFieldRenderers/TabsFieldRenderer.js";
6
+ export const LayoutDescriptorCell = ({
7
+ descriptor,
8
+ Bind,
9
+ fields,
10
+ contentModel,
11
+ gridClassName
12
+ }) => {
13
+ switch (descriptor.type) {
14
+ case "separator":
15
+ return /*#__PURE__*/React.createElement(SeparatorFieldRenderer, {
16
+ descriptor: descriptor
17
+ });
18
+ case "alert":
19
+ return /*#__PURE__*/React.createElement(AlertFieldRenderer, {
20
+ descriptor: descriptor
21
+ });
22
+ case "tabs":
23
+ return /*#__PURE__*/React.createElement(TabsFieldRenderer, {
24
+ descriptor: descriptor,
25
+ Bind: Bind,
26
+ fields: fields,
27
+ contentModel: contentModel,
28
+ gridClassName: gridClassName
29
+ });
30
+ default:
31
+ {
32
+ const rendererPlugin = plugins.byType("cms-layout-descriptor-renderer").find(p => p.descriptorType === descriptor.type);
33
+ if (rendererPlugin) {
34
+ return rendererPlugin.render({
35
+ descriptor,
36
+ Bind,
37
+ fields,
38
+ contentModel,
39
+ gridClassName
40
+ });
41
+ }
42
+ return null;
43
+ }
44
+ }
45
+ };
46
+
47
+ //# sourceMappingURL=LayoutDescriptorCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","plugins","SeparatorFieldRenderer","AlertFieldRenderer","TabsFieldRenderer","LayoutDescriptorCell","descriptor","Bind","fields","contentModel","gridClassName","type","createElement","rendererPlugin","byType","find","p","descriptorType","render"],"sources":["LayoutDescriptorCell.tsx"],"sourcesContent":["import React from \"react\";\nimport type {\n CmsAlertLayoutDescriptor,\n CmsLayoutDescriptor,\n CmsSeparatorLayoutDescriptor,\n CmsTabLayoutDescriptor\n} from \"~/types/model.js\";\nimport type {\n BindComponent,\n CmsEditorContentModel,\n CmsLayoutDescriptorRendererPlugin,\n CmsModelField\n} from \"~/types/index.js\";\nimport { plugins } from \"@webiny/plugins\";\nimport { SeparatorFieldRenderer } from \"./layoutFieldRenderers/SeparatorFieldRenderer.js\";\nimport { AlertFieldRenderer } from \"./layoutFieldRenderers/AlertFieldRenderer.js\";\nimport { TabsFieldRenderer } from \"./layoutFieldRenderers/TabsFieldRenderer.js\";\n\ninterface LayoutDescriptorCellProps {\n descriptor: CmsLayoutDescriptor;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\nexport const LayoutDescriptorCell = ({\n descriptor,\n Bind,\n fields,\n contentModel,\n gridClassName\n}: LayoutDescriptorCellProps) => {\n switch (descriptor.type) {\n case \"separator\":\n return (\n <SeparatorFieldRenderer descriptor={descriptor as CmsSeparatorLayoutDescriptor} />\n );\n case \"alert\":\n return <AlertFieldRenderer descriptor={descriptor as CmsAlertLayoutDescriptor} />;\n case \"tabs\":\n return (\n <TabsFieldRenderer\n descriptor={descriptor as CmsTabLayoutDescriptor}\n Bind={Bind}\n fields={fields}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n );\n default: {\n const rendererPlugin = plugins\n .byType<CmsLayoutDescriptorRendererPlugin>(\"cms-layout-descriptor-renderer\")\n .find(p => p.descriptorType === descriptor.type);\n if (rendererPlugin) {\n return rendererPlugin.render({\n descriptor,\n Bind,\n fields,\n contentModel,\n gridClassName\n });\n }\n return null;\n }\n }\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAazB,SAASC,OAAO,QAAQ,iBAAiB;AACzC,SAASC,sBAAsB;AAC/B,SAASC,kBAAkB;AAC3B,SAASC,iBAAiB;AAU1B,OAAO,MAAMC,oBAAoB,GAAGA,CAAC;EACjCC,UAAU;EACVC,IAAI;EACJC,MAAM;EACNC,YAAY;EACZC;AACuB,CAAC,KAAK;EAC7B,QAAQJ,UAAU,CAACK,IAAI;IACnB,KAAK,WAAW;MACZ,oBACIX,KAAA,CAAAY,aAAA,CAACV,sBAAsB;QAACI,UAAU,EAAEA;MAA2C,CAAE,CAAC;IAE1F,KAAK,OAAO;MACR,oBAAON,KAAA,CAAAY,aAAA,CAACT,kBAAkB;QAACG,UAAU,EAAEA;MAAuC,CAAE,CAAC;IACrF,KAAK,MAAM;MACP,oBACIN,KAAA,CAAAY,aAAA,CAACR,iBAAiB;QACdE,UAAU,EAAEA,UAAqC;QACjDC,IAAI,EAAEA,IAAK;QACXC,MAAM,EAAEA,MAAO;QACfC,YAAY,EAAEA,YAAa;QAC3BC,aAAa,EAAEA;MAAc,CAChC,CAAC;IAEV;MAAS;QACL,MAAMG,cAAc,GAAGZ,OAAO,CACzBa,MAAM,CAAoC,gCAAgC,CAAC,CAC3EC,IAAI,CAACC,CAAC,IAAIA,CAAC,CAACC,cAAc,KAAKX,UAAU,CAACK,IAAI,CAAC;QACpD,IAAIE,cAAc,EAAE;UAChB,OAAOA,cAAc,CAACK,MAAM,CAAC;YACzBZ,UAAU;YACVC,IAAI;YACJC,MAAM;YACNC,YAAY;YACZC;UACJ,CAAC,CAAC;QACN;QACA,OAAO,IAAI;MACf;EACJ;AACJ,CAAC","ignoreList":[]}
@@ -0,0 +1,23 @@
1
+ export type Operator = "==" | "!=" | ">" | "<" | ">=" | "<=" | "contains" | "startsWith" | "endsWith" | "isEmpty" | "isNotEmpty";
2
+ export interface ParsedExpression {
3
+ target: string;
4
+ operator: Operator;
5
+ value: string | number | boolean | null;
6
+ }
7
+ /**
8
+ * Resolve a fieldPath that may contain `$` placeholders using the bindParentName.
9
+ *
10
+ * The bindParentName gives us the concrete indices for the current list context.
11
+ * For example, if fieldPath is `panorama.hotspots.$.title` and bindParentName
12
+ * is `panorama.hotspots.2`, the result is `panorama.hotspots.2.title`.
13
+ *
14
+ * Supports multiple nested `$` segments for deeply nested list objects.
15
+ */
16
+ export declare function resolveFieldPath(fieldPath: string, bindParentName?: string): string;
17
+ /**
18
+ * Evaluate a parsed expression against form values.
19
+ *
20
+ * If the resolved fieldPath ends with `.length`, it reads the array at the parent
21
+ * path and uses its length as the left-hand value.
22
+ */
23
+ export declare function evaluateExpression(parsed: ParsedExpression, getFormValue: (path: string) => unknown): boolean;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Resolve a fieldPath that may contain `$` placeholders using the bindParentName.
3
+ *
4
+ * The bindParentName gives us the concrete indices for the current list context.
5
+ * For example, if fieldPath is `panorama.hotspots.$.title` and bindParentName
6
+ * is `panorama.hotspots.2`, the result is `panorama.hotspots.2.title`.
7
+ *
8
+ * Supports multiple nested `$` segments for deeply nested list objects.
9
+ */
10
+ export function resolveFieldPath(fieldPath, bindParentName) {
11
+ if (!fieldPath.includes("$")) {
12
+ return fieldPath;
13
+ }
14
+ if (!bindParentName) {
15
+ // No parent context, replace $ with 0 as fallback
16
+ return fieldPath.replace(/\$/g, "0");
17
+ }
18
+ const pathParts = fieldPath.split(".");
19
+ const parentParts = bindParentName.split(".");
20
+
21
+ // Build a map of prefix -> index from the parent path.
22
+ // E.g., parentName "panorama.hotspots.2.items.1" gives us:
23
+ // "panorama.hotspots" -> "2"
24
+ // "panorama.hotspots.2.items" -> "1"
25
+ const indexMap = new Map();
26
+ const prefixParts = [];
27
+ for (const part of parentParts) {
28
+ if (/^\d+$/.test(part)) {
29
+ indexMap.set(prefixParts.join("."), part);
30
+ } else {
31
+ prefixParts.push(part);
32
+ }
33
+ }
34
+
35
+ // Walk through pathParts and replace each `$` with the corresponding index
36
+ const resolved = [];
37
+ const currentPrefix = [];
38
+ for (const part of pathParts) {
39
+ if (part === "$") {
40
+ const key = currentPrefix.join(".");
41
+ const index = indexMap.get(key) ?? "0";
42
+ resolved.push(index);
43
+ } else {
44
+ currentPrefix.push(part);
45
+ resolved.push(part);
46
+ }
47
+ }
48
+ return resolved.join(".");
49
+ }
50
+ function compareValues(operator, val, rhs) {
51
+ switch (operator) {
52
+ case "==":
53
+ return val == rhs;
54
+ case "!=":
55
+ return val != rhs;
56
+ case ">":
57
+ return Number(val) > Number(rhs);
58
+ case "<":
59
+ return Number(val) < Number(rhs);
60
+ case ">=":
61
+ return Number(val) >= Number(rhs);
62
+ case "<=":
63
+ return Number(val) <= Number(rhs);
64
+ case "contains":
65
+ return String(val ?? "").includes(String(rhs ?? ""));
66
+ case "startsWith":
67
+ return String(val ?? "").startsWith(String(rhs ?? ""));
68
+ case "endsWith":
69
+ return String(val ?? "").endsWith(String(rhs ?? ""));
70
+ case "isEmpty":
71
+ return val == null || val === "" || Array.isArray(val) && val.length === 0;
72
+ case "isNotEmpty":
73
+ return val != null && val !== "" && !(Array.isArray(val) && val.length === 0);
74
+ default:
75
+ return false;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Evaluate a parsed expression against form values.
81
+ *
82
+ * If the resolved fieldPath ends with `.length`, it reads the array at the parent
83
+ * path and uses its length as the left-hand value.
84
+ */
85
+ export function evaluateExpression(parsed, getFormValue) {
86
+ const {
87
+ target,
88
+ operator,
89
+ value: rhs
90
+ } = parsed;
91
+ let val;
92
+ if (target.endsWith(".length")) {
93
+ const arrayPath = target.slice(0, -".length".length);
94
+ const arr = getFormValue(arrayPath);
95
+ val = Array.isArray(arr) ? arr.length : 0;
96
+ } else {
97
+ val = getFormValue(target);
98
+ }
99
+ return compareValues(operator, val, rhs);
100
+ }
101
+
102
+ //# sourceMappingURL=evaluateExpression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["resolveFieldPath","fieldPath","bindParentName","includes","replace","pathParts","split","parentParts","indexMap","Map","prefixParts","part","test","set","join","push","resolved","currentPrefix","key","index","get","compareValues","operator","val","rhs","Number","String","startsWith","endsWith","Array","isArray","length","evaluateExpression","parsed","getFormValue","target","value","arrayPath","slice","arr"],"sources":["evaluateExpression.ts"],"sourcesContent":["export type Operator =\n | \"==\"\n | \"!=\"\n | \">\"\n | \"<\"\n | \">=\"\n | \"<=\"\n | \"contains\"\n | \"startsWith\"\n | \"endsWith\"\n | \"isEmpty\"\n | \"isNotEmpty\";\n\nexport interface ParsedExpression {\n target: string;\n operator: Operator;\n value: string | number | boolean | null;\n}\n\n/**\n * Resolve a fieldPath that may contain `$` placeholders using the bindParentName.\n *\n * The bindParentName gives us the concrete indices for the current list context.\n * For example, if fieldPath is `panorama.hotspots.$.title` and bindParentName\n * is `panorama.hotspots.2`, the result is `panorama.hotspots.2.title`.\n *\n * Supports multiple nested `$` segments for deeply nested list objects.\n */\nexport function resolveFieldPath(fieldPath: string, bindParentName?: string): string {\n if (!fieldPath.includes(\"$\")) {\n return fieldPath;\n }\n\n if (!bindParentName) {\n // No parent context, replace $ with 0 as fallback\n return fieldPath.replace(/\\$/g, \"0\");\n }\n\n const pathParts = fieldPath.split(\".\");\n const parentParts = bindParentName.split(\".\");\n\n // Build a map of prefix -> index from the parent path.\n // E.g., parentName \"panorama.hotspots.2.items.1\" gives us:\n // \"panorama.hotspots\" -> \"2\"\n // \"panorama.hotspots.2.items\" -> \"1\"\n const indexMap = new Map<string, string>();\n const prefixParts: string[] = [];\n for (const part of parentParts) {\n if (/^\\d+$/.test(part)) {\n indexMap.set(prefixParts.join(\".\"), part);\n } else {\n prefixParts.push(part);\n }\n }\n\n // Walk through pathParts and replace each `$` with the corresponding index\n const resolved: string[] = [];\n const currentPrefix: string[] = [];\n for (const part of pathParts) {\n if (part === \"$\") {\n const key = currentPrefix.join(\".\");\n const index = indexMap.get(key) ?? \"0\";\n resolved.push(index);\n } else {\n currentPrefix.push(part);\n resolved.push(part);\n }\n }\n\n return resolved.join(\".\");\n}\n\nfunction compareValues(\n operator: string,\n val: unknown,\n rhs: string | number | boolean | null\n): boolean {\n switch (operator) {\n case \"==\":\n return val == rhs;\n case \"!=\":\n return val != rhs;\n case \">\":\n return Number(val) > Number(rhs);\n case \"<\":\n return Number(val) < Number(rhs);\n case \">=\":\n return Number(val) >= Number(rhs);\n case \"<=\":\n return Number(val) <= Number(rhs);\n case \"contains\":\n return String(val ?? \"\").includes(String(rhs ?? \"\"));\n case \"startsWith\":\n return String(val ?? \"\").startsWith(String(rhs ?? \"\"));\n case \"endsWith\":\n return String(val ?? \"\").endsWith(String(rhs ?? \"\"));\n case \"isEmpty\":\n return val == null || val === \"\" || (Array.isArray(val) && val.length === 0);\n case \"isNotEmpty\":\n return val != null && val !== \"\" && !(Array.isArray(val) && val.length === 0);\n default:\n return false;\n }\n}\n\n/**\n * Evaluate a parsed expression against form values.\n *\n * If the resolved fieldPath ends with `.length`, it reads the array at the parent\n * path and uses its length as the left-hand value.\n */\nexport function evaluateExpression(\n parsed: ParsedExpression,\n getFormValue: (path: string) => unknown\n): boolean {\n const { target, operator, value: rhs } = parsed;\n\n let val: unknown;\n if (target.endsWith(\".length\")) {\n const arrayPath = target.slice(0, -\".length\".length);\n const arr = getFormValue(arrayPath);\n val = Array.isArray(arr) ? arr.length : 0;\n } else {\n val = getFormValue(target);\n }\n\n return compareValues(operator, val, rhs);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,36 @@
1
+ import type { CmsModelField, CmsEditorFieldsLayout } from "../types/model.js";
2
+ import type { CmsLayoutFieldTypePlugin } 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: CmsLayoutFieldTypePlugin[]): 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?: CmsLayoutFieldTypePlugin[]): FieldOption[];
@@ -0,0 +1,113 @@
1
+ import { isLayoutDescriptor } 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 (!isLayoutDescriptor(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
+ descriptor: 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":["isLayoutDescriptor","buildFieldLabelPrefixes","layout","plugins","map","Map","pluginByType","p","field","type","row","cell","plugin","get","getFieldLabelPrefixes","prefixes","descriptor","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 { CmsLayoutFieldTypePlugin } from \"~/types/index.js\";\nimport { isLayoutDescriptor } 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: CmsLayoutFieldTypePlugin[]\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 (!isLayoutDescriptor(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({ descriptor: 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?: CmsLayoutFieldTypePlugin[]\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
1
  export * from "./FieldElement.js";
2
2
  export * from "./Fields.js";
3
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
1
  export * from "./FieldElement.js";
2
2
  export * from "./Fields.js";
3
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