@webiny/app-headless-cms 6.5.0 → 6.5.1-beta.0
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/features/formModel/CmsFormModelBuilder.test.js +213 -0
- package/features/formModel/CmsFormModelBuilder.test.js.map +1 -1
- package/features/formModel/CmsValidationMapper.d.ts +9 -0
- package/features/formModel/CmsValidationMapper.js +25 -19
- package/features/formModel/CmsValidationMapper.js.map +1 -1
- package/features/formModel/mappers/DateTimeFieldMapper.js +3 -0
- package/features/formModel/mappers/DateTimeFieldMapper.js.map +1 -1
- package/package.json +20 -20
- package/presentation/fieldEditor/groups/AppearanceGroup.js +12 -0
- package/presentation/fieldEditor/groups/AppearanceGroup.js.map +1 -1
- package/presentation/fieldEditor/groups/ValidationsGroup.d.ts +2 -0
- package/presentation/fieldEditor/groups/ValidationsGroup.js +20 -6
- package/presentation/fieldEditor/groups/ValidationsGroup.js.map +1 -1
- package/presentation/fieldEditor/renderers/CmsValidatorsRenderer.js +2 -2
- package/presentation/fieldEditor/renderers/CmsValidatorsRenderer.js.map +1 -1
- package/presentation/fieldRenderers/feature.js +2 -1
- package/presentation/fieldRenderers/feature.js.map +1 -1
- package/presentation/fieldTypes/renderers/dateTime/BirthdayInputRenderer.d.ts +15 -0
- package/presentation/fieldTypes/renderers/dateTime/BirthdayInputRenderer.js +19 -0
- package/presentation/fieldTypes/renderers/dateTime/BirthdayInputRenderer.js.map +1 -0
- package/presentation/fieldTypes/renderers/index.d.ts +1 -0
- package/presentation/fieldTypes/renderers/index.js +1 -0
- package/presentation/fieldValidators/abstractions.d.ts +7 -0
- package/presentation/fieldValidators/abstractions.js.map +1 -1
- package/presentation/fieldValidators/validators/DateGteValidator.d.ts +6 -0
- package/presentation/fieldValidators/validators/DateGteValidator.js +17 -25
- package/presentation/fieldValidators/validators/DateGteValidator.js.map +1 -1
- package/presentation/fieldValidators/validators/DateLteValidator.d.ts +6 -0
- package/presentation/fieldValidators/validators/DateLteValidator.js +17 -25
- package/presentation/fieldValidators/validators/DateLteValidator.js.map +1 -1
- package/presentation/fieldValidators/validators/dateLimitSettings.d.ts +20 -0
- package/presentation/fieldValidators/validators/dateLimitSettings.js +124 -0
- package/presentation/fieldValidators/validators/dateLimitSettings.js.map +1 -0
- package/presentation/fieldValidators/validators/dateLimitSettings.test.d.ts +1 -0
- package/presentation/fieldValidators/validators/dateLimitSettings.test.js +111 -0
- package/presentation/fieldValidators/validators/dateLimitSettings.test.js.map +1 -0
|
@@ -7,6 +7,7 @@ import { CmsFormModelBuilder } from "./abstractions.js";
|
|
|
7
7
|
import { CmsFormModelFeature } from "./feature.js";
|
|
8
8
|
import { DateTimeInputRenderer } from "../../presentation/fieldTypes/renderers/dateTime/DateTimeInputRenderer.js";
|
|
9
9
|
import { DateTimeInputsRenderer } from "../../presentation/fieldTypes/renderers/dateTime/DateTimeInputsRenderer.js";
|
|
10
|
+
import { BirthdayInputRenderer } from "../../presentation/fieldTypes/renderers/dateTime/BirthdayInputRenderer.js";
|
|
10
11
|
import { TextInputRenderer } from "../../presentation/fieldTypes/renderers/text/TextInputRenderer.js";
|
|
11
12
|
import { TextInputsRenderer } from "../../presentation/fieldTypes/renderers/text/TextInputsRenderer.js";
|
|
12
13
|
const field = (fieldId, type, list, renderer, extra = {})=>({
|
|
@@ -36,6 +37,7 @@ function createCmsForm(fields) {
|
|
|
36
37
|
CmsFormModelFeature.register(container);
|
|
37
38
|
container.register(DateTimeInputRenderer);
|
|
38
39
|
container.register(DateTimeInputsRenderer);
|
|
40
|
+
container.register(BirthdayInputRenderer);
|
|
39
41
|
container.register(TextInputRenderer);
|
|
40
42
|
container.register(TextInputsRenderer);
|
|
41
43
|
const model = {
|
|
@@ -107,6 +109,217 @@ describe("CmsFormModelBuilder renderer cardinality", ()=>{
|
|
|
107
109
|
expect(item.children.get("openTime").vm.renderer).toBe("dateTimeInput");
|
|
108
110
|
});
|
|
109
111
|
});
|
|
112
|
+
describe("CmsFormModelBuilder birthday picker", ()=>{
|
|
113
|
+
it("renders a date-only field with the birthday picker and keeps its value", ()=>{
|
|
114
|
+
const form = createCmsForm([
|
|
115
|
+
field("dob", "datetime", false, "birthday-input", {
|
|
116
|
+
settings: {
|
|
117
|
+
type: "date"
|
|
118
|
+
},
|
|
119
|
+
renderer: {
|
|
120
|
+
name: "birthday-input",
|
|
121
|
+
settings: null
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
]);
|
|
125
|
+
form.setData({
|
|
126
|
+
dob: "1990-02-09"
|
|
127
|
+
});
|
|
128
|
+
const vm = form.field("dob").vm;
|
|
129
|
+
expect(vm.renderer).toBe("birthdayInput");
|
|
130
|
+
expect(vm.rendererSettings).toEqual({
|
|
131
|
+
type: "date"
|
|
132
|
+
});
|
|
133
|
+
expect(vm.value).toBe("1990-02-09");
|
|
134
|
+
});
|
|
135
|
+
it("hands the field's date limits to the birthday picker", ()=>{
|
|
136
|
+
const form = createCmsForm([
|
|
137
|
+
field("dob", "datetime", false, "birthday-input", {
|
|
138
|
+
settings: {
|
|
139
|
+
type: "date"
|
|
140
|
+
},
|
|
141
|
+
validation: [
|
|
142
|
+
{
|
|
143
|
+
name: "dateGte",
|
|
144
|
+
message: "Too old.",
|
|
145
|
+
settings: {
|
|
146
|
+
value: "1950-01-01"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "dateLte",
|
|
151
|
+
message: "You must be 18 or older.",
|
|
152
|
+
settings: {
|
|
153
|
+
expression: "today-18y",
|
|
154
|
+
type: "date"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
})
|
|
159
|
+
]);
|
|
160
|
+
expect(form.field("dob").vm.rendererSettings).toEqual({
|
|
161
|
+
type: "date",
|
|
162
|
+
dateLimits: {
|
|
163
|
+
gte: [
|
|
164
|
+
"1950-01-01"
|
|
165
|
+
],
|
|
166
|
+
lte: [
|
|
167
|
+
{
|
|
168
|
+
expression: "today-18y"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
it("falls back to the date/time input when the field is no longer date-only", ()=>{
|
|
175
|
+
const form = createCmsForm([
|
|
176
|
+
field("openTime", "datetime", false, "birthday-input", {
|
|
177
|
+
settings: {
|
|
178
|
+
type: "time"
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
]);
|
|
182
|
+
expect(form.field("openTime").vm.renderer).toBe("dateTimeInput");
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe("CmsFormModelBuilder validators", ()=>{
|
|
186
|
+
const validate = async (form, name)=>{
|
|
187
|
+
const valid = await form.field(name).validate({
|
|
188
|
+
force: true
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
valid,
|
|
192
|
+
message: form.field(name).vm.validation.message
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
it("checks both date limits on a field that has two", async ()=>{
|
|
196
|
+
const form = createCmsForm([
|
|
197
|
+
field("bornOn", "datetime", false, "date-time-input", {
|
|
198
|
+
settings: {
|
|
199
|
+
type: "date"
|
|
200
|
+
},
|
|
201
|
+
validation: [
|
|
202
|
+
{
|
|
203
|
+
name: "dateGte",
|
|
204
|
+
message: "Too early.",
|
|
205
|
+
settings: {
|
|
206
|
+
value: "1950-01-01"
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "dateLte",
|
|
211
|
+
message: "Too late.",
|
|
212
|
+
settings: {
|
|
213
|
+
value: "2000-12-31"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
})
|
|
218
|
+
]);
|
|
219
|
+
form.setData({
|
|
220
|
+
bornOn: "2005-01-01"
|
|
221
|
+
});
|
|
222
|
+
expect(await validate(form, "bornOn")).toEqual({
|
|
223
|
+
valid: false,
|
|
224
|
+
message: "Too late."
|
|
225
|
+
});
|
|
226
|
+
form.setData({
|
|
227
|
+
bornOn: "1949-01-01"
|
|
228
|
+
});
|
|
229
|
+
expect(await validate(form, "bornOn")).toEqual({
|
|
230
|
+
valid: false,
|
|
231
|
+
message: "Too early."
|
|
232
|
+
});
|
|
233
|
+
form.setData({
|
|
234
|
+
bornOn: "1975-06-15"
|
|
235
|
+
});
|
|
236
|
+
expect((await validate(form, "bornOn")).valid).toBe(true);
|
|
237
|
+
});
|
|
238
|
+
it("works out a relative limit from today", async ()=>{
|
|
239
|
+
const form = createCmsForm([
|
|
240
|
+
field("bornOn", "datetime", false, "birthday-input", {
|
|
241
|
+
settings: {
|
|
242
|
+
type: "date"
|
|
243
|
+
},
|
|
244
|
+
validation: [
|
|
245
|
+
{
|
|
246
|
+
name: "dateLte",
|
|
247
|
+
message: "You must be 18 or older.",
|
|
248
|
+
settings: {
|
|
249
|
+
expression: "today-18y",
|
|
250
|
+
type: "date"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
})
|
|
255
|
+
]);
|
|
256
|
+
form.setData({
|
|
257
|
+
bornOn: `${new Date().getFullYear() - 10}-01-01`
|
|
258
|
+
});
|
|
259
|
+
expect(await validate(form, "bornOn")).toEqual({
|
|
260
|
+
valid: false,
|
|
261
|
+
message: "You must be 18 or older."
|
|
262
|
+
});
|
|
263
|
+
form.setData({
|
|
264
|
+
bornOn: `${new Date().getFullYear() - 30}-01-01`
|
|
265
|
+
});
|
|
266
|
+
expect((await validate(form, "bornOn")).valid).toBe(true);
|
|
267
|
+
});
|
|
268
|
+
it("checks every validator on a text field that has several", async ()=>{
|
|
269
|
+
const form = createCmsForm([
|
|
270
|
+
field("code", "text", false, "text-input", {
|
|
271
|
+
validation: [
|
|
272
|
+
{
|
|
273
|
+
name: "minLength",
|
|
274
|
+
message: "Too short.",
|
|
275
|
+
settings: {
|
|
276
|
+
value: 3
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: "maxLength",
|
|
281
|
+
message: "Too long.",
|
|
282
|
+
settings: {
|
|
283
|
+
value: 5
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "pattern",
|
|
288
|
+
message: "Letters only.",
|
|
289
|
+
settings: {
|
|
290
|
+
regex: "^[a-z]+$"
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
})
|
|
295
|
+
]);
|
|
296
|
+
form.setData({
|
|
297
|
+
code: "ab"
|
|
298
|
+
});
|
|
299
|
+
expect(await validate(form, "code")).toEqual({
|
|
300
|
+
valid: false,
|
|
301
|
+
message: "Too short."
|
|
302
|
+
});
|
|
303
|
+
form.setData({
|
|
304
|
+
code: "abcdef"
|
|
305
|
+
});
|
|
306
|
+
expect(await validate(form, "code")).toEqual({
|
|
307
|
+
valid: false,
|
|
308
|
+
message: "Too long."
|
|
309
|
+
});
|
|
310
|
+
form.setData({
|
|
311
|
+
code: "ab1"
|
|
312
|
+
});
|
|
313
|
+
expect(await validate(form, "code")).toEqual({
|
|
314
|
+
valid: false,
|
|
315
|
+
message: "Letters only."
|
|
316
|
+
});
|
|
317
|
+
form.setData({
|
|
318
|
+
code: "abcd"
|
|
319
|
+
});
|
|
320
|
+
expect((await validate(form, "code")).valid).toBe(true);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
110
323
|
const rowNames = (layout)=>layout.map((row)=>row.fields.map((f)=>f.name));
|
|
111
324
|
describe("CmsFormModelBuilder nested layouts", ()=>{
|
|
112
325
|
it("lays out a single object with the layout stored on the field", ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/formModel/CmsFormModelBuilder.test.js","sources":["../../../src/features/formModel/CmsFormModelBuilder.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"@webiny/app-admin/features/formModel/feature.js\";\nimport { IdentityContextFeature } from \"@webiny/app-admin/features/security/IdentityContext/feature.js\";\nimport { FormModelFactory } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport { CmsFormModelBuilder } from \"~/features/formModel/abstractions.js\";\nimport { CmsFormModelFeature } from \"~/features/formModel/feature.js\";\nimport { DateTimeInputRenderer } from \"~/presentation/fieldTypes/renderers/dateTime/DateTimeInputRenderer.js\";\nimport { DateTimeInputsRenderer } from \"~/presentation/fieldTypes/renderers/dateTime/DateTimeInputsRenderer.js\";\nimport { TextInputRenderer } from \"~/presentation/fieldTypes/renderers/text/TextInputRenderer.js\";\nimport { TextInputsRenderer } from \"~/presentation/fieldTypes/renderers/text/TextInputsRenderer.js\";\n\nconst field = (fieldId: string, type: string, list: boolean, renderer: string, extra = {}) => ({\n id: fieldId,\n fieldId,\n type,\n label: fieldId,\n tags: [],\n list,\n renderer: { name: renderer, settings: {} },\n validation: [],\n listValidation: [],\n settings: {},\n predefinedValues: { enabled: false, values: [] },\n ...extra\n});\n\nfunction createCmsForm(fields: any[]) {\n const container = new Container();\n IdentityContextFeature.register(container);\n FormModelFeature.register(container);\n CmsFormModelFeature.register(container);\n container.register(DateTimeInputRenderer);\n container.register(DateTimeInputsRenderer);\n container.register(TextInputRenderer);\n container.register(TextInputsRenderer);\n\n const model = {\n modelId: \"test\",\n fields,\n layout: fields.map(f => [f.fieldId])\n } as any;\n const config = container.resolve(CmsFormModelBuilder).build(model);\n return container.resolve(FormModelFactory).create(config);\n}\n\ndescribe(\"CmsFormModelBuilder renderer cardinality\", () => {\n it(\"keeps renderers that match the field's cardinality\", () => {\n const form = createCmsForm([\n field(\"single\", \"datetime\", false, \"date-time-input\"),\n field(\"many\", \"datetime\", true, \"date-time-inputs\")\n ]);\n\n expect(form.field(\"single\").vm.renderer).toBe(\"dateTimeInput\");\n expect(form.field(\"many\").vm.renderer).toBe(\"dateTimeInputs\");\n });\n\n it(\"falls back to the single-value renderer when a list renderer is set on a non-list field\", () => {\n const form = createCmsForm([\n field(\"openTime\", \"datetime\", false, \"date-time-inputs\"),\n field(\"name\", \"text\", false, \"text-inputs\")\n ]);\n\n expect(form.field(\"openTime\").vm.renderer).toBe(\"dateTimeInput\");\n expect(form.field(\"name\").vm.renderer).toBe(\"textInput\");\n });\n\n it(\"keeps the list renderer for list datetime fields with a subtype\", () => {\n const form = createCmsForm(\n [\"date\", \"time\", \"dateTimeWithTimezone\", \"dateTimeWithoutTimezone\"].map(type =>\n field(type, \"datetime\", true, \"date-time-inputs\", { settings: { type } })\n )\n );\n\n expect(form.field(\"date\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"time\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"dateTimeWithTimezone\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"dateTimeWithoutTimezone\").vm.renderer).toBe(\"dateTimeInputs\");\n });\n\n it(\"applies the fallback to fields nested in object lists\", () => {\n const form = createCmsForm([\n field(\"holidayHours\", \"object\", true, \"objects-accordion\", {\n settings: {\n fields: [field(\"openTime\", \"datetime\", false, \"date-time-inputs\")],\n layout: [[\"openTime\"]]\n }\n })\n ]);\n\n form.setData({ holidayHours: [{ openTime: \"2026-12-24T09:00:00.000Z\" }] });\n const item = (form.field(\"holidayHours\") as any).items[0];\n\n expect(item.children.get(\"openTime\").vm.renderer).toBe(\"dateTimeInput\");\n });\n});\n\nconst rowNames = (layout: any[]) => layout.map(row => row.fields.map((f: any) => f.name));\n\ndescribe(\"CmsFormModelBuilder nested layouts\", () => {\n it(\"lays out a single object with the layout stored on the field\", () => {\n const form = createCmsForm([\n field(\"address\", \"object\", false, \"object-accordion\", {\n settings: {\n fields: [\n field(\"street\", \"text\", false, \"text-input\"),\n // Fields created in the model editor have an `id` that differs from `fieldId`.\n field(\"city\", \"text\", false, \"text-input\", { id: \"c1ty\" }),\n field(\"zipCode\", \"text\", false, \"text-input\")\n ],\n layout: [[\"street\"], [\"c1ty\", \"zipCode\"]]\n }\n })\n ]);\n\n expect(rowNames((form.field(\"address\").vm as any).layout)).toEqual([\n [\"street\"],\n [\"city\", \"zipCode\"]\n ]);\n });\n\n it(\"lays out every item of an object list\", () => {\n const form = createCmsForm([\n field(\"facilityStats\", \"object\", true, \"objects-accordion\", {\n settings: {\n fields: [\n field(\"statValue\", \"text\", false, \"text-input\"),\n field(\"statLabel\", \"text\", false, \"text-input\")\n ],\n layout: [[\"statValue\", \"statLabel\"]]\n }\n })\n ]);\n\n form.setData({ facilityStats: [{ statValue: \"1\", statLabel: \"a\" }] });\n const vm = form.field(\"facilityStats\").vm as any;\n\n expect(rowNames(vm.items[0].layout)).toEqual([[\"statValue\", \"statLabel\"]]);\n });\n\n it(\"gives children missing from the stored layout a row of their own\", () => {\n const form = createCmsForm([\n field(\"address\", \"object\", false, \"object-accordion\", {\n settings: {\n fields: [\n field(\"street\", \"text\", false, \"text-input\"),\n field(\"city\", \"text\", false, \"text-input\"),\n field(\"state\", \"text\", false, \"text-input\")\n ],\n layout: [[\"street\", \"city\"]]\n }\n })\n ]);\n\n expect(rowNames((form.field(\"address\").vm as any).layout)).toEqual([\n [\"street\", \"city\"],\n [\"state\"]\n ]);\n });\n\n it(\"lays out a dynamic zone template with the template's layout\", () => {\n const form = createCmsForm([\n field(\"blocks\", \"dynamicZone\", true, \"dynamicZone\", {\n settings: {\n templates: [\n {\n id: \"hero\",\n name: \"Hero\",\n gqlTypeName: \"Hero\",\n description: \"\",\n icon: null,\n fields: [\n field(\"title\", \"text\", false, \"text-input\"),\n field(\"subtitle\", \"text\", false, \"text-input\")\n ],\n layout: [[\"title\", \"subtitle\"]],\n validation: []\n }\n ]\n }\n })\n ]);\n\n form.setData({ blocks: [{ _templateId: \"hero\", title: \"T\", subtitle: \"S\" }] });\n const vm = form.field(\"blocks\").vm as any;\n\n expect(rowNames(vm.items[0].layout)).toEqual([[\"title\", \"subtitle\"]]);\n });\n});\n"],"names":["field","fieldId","type","list","renderer","extra","createCmsForm","fields","container","Container","IdentityContextFeature","FormModelFeature","CmsFormModelFeature","DateTimeInputRenderer","DateTimeInputsRenderer","TextInputRenderer","TextInputsRenderer","model","f","config","CmsFormModelBuilder","FormModelFactory","describe","it","form","expect","item","rowNames","layout","row","vm"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features/formModel/CmsFormModelBuilder.test.js","sources":["../../../src/features/formModel/CmsFormModelBuilder.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"@webiny/app-admin/features/formModel/feature.js\";\nimport { IdentityContextFeature } from \"@webiny/app-admin/features/security/IdentityContext/feature.js\";\nimport { FormModelFactory } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport { CmsFormModelBuilder } from \"~/features/formModel/abstractions.js\";\nimport { CmsFormModelFeature } from \"~/features/formModel/feature.js\";\nimport { DateTimeInputRenderer } from \"~/presentation/fieldTypes/renderers/dateTime/DateTimeInputRenderer.js\";\nimport { DateTimeInputsRenderer } from \"~/presentation/fieldTypes/renderers/dateTime/DateTimeInputsRenderer.js\";\nimport { BirthdayInputRenderer } from \"~/presentation/fieldTypes/renderers/dateTime/BirthdayInputRenderer.js\";\nimport { TextInputRenderer } from \"~/presentation/fieldTypes/renderers/text/TextInputRenderer.js\";\nimport { TextInputsRenderer } from \"~/presentation/fieldTypes/renderers/text/TextInputsRenderer.js\";\n\nconst field = (fieldId: string, type: string, list: boolean, renderer: string, extra = {}) => ({\n id: fieldId,\n fieldId,\n type,\n label: fieldId,\n tags: [],\n list,\n renderer: { name: renderer, settings: {} },\n validation: [],\n listValidation: [],\n settings: {},\n predefinedValues: { enabled: false, values: [] },\n ...extra\n});\n\nfunction createCmsForm(fields: any[]) {\n const container = new Container();\n IdentityContextFeature.register(container);\n FormModelFeature.register(container);\n CmsFormModelFeature.register(container);\n container.register(DateTimeInputRenderer);\n container.register(DateTimeInputsRenderer);\n container.register(BirthdayInputRenderer);\n container.register(TextInputRenderer);\n container.register(TextInputsRenderer);\n\n const model = {\n modelId: \"test\",\n fields,\n layout: fields.map(f => [f.fieldId])\n } as any;\n const config = container.resolve(CmsFormModelBuilder).build(model);\n return container.resolve(FormModelFactory).create(config);\n}\n\ndescribe(\"CmsFormModelBuilder renderer cardinality\", () => {\n it(\"keeps renderers that match the field's cardinality\", () => {\n const form = createCmsForm([\n field(\"single\", \"datetime\", false, \"date-time-input\"),\n field(\"many\", \"datetime\", true, \"date-time-inputs\")\n ]);\n\n expect(form.field(\"single\").vm.renderer).toBe(\"dateTimeInput\");\n expect(form.field(\"many\").vm.renderer).toBe(\"dateTimeInputs\");\n });\n\n it(\"falls back to the single-value renderer when a list renderer is set on a non-list field\", () => {\n const form = createCmsForm([\n field(\"openTime\", \"datetime\", false, \"date-time-inputs\"),\n field(\"name\", \"text\", false, \"text-inputs\")\n ]);\n\n expect(form.field(\"openTime\").vm.renderer).toBe(\"dateTimeInput\");\n expect(form.field(\"name\").vm.renderer).toBe(\"textInput\");\n });\n\n it(\"keeps the list renderer for list datetime fields with a subtype\", () => {\n const form = createCmsForm(\n [\"date\", \"time\", \"dateTimeWithTimezone\", \"dateTimeWithoutTimezone\"].map(type =>\n field(type, \"datetime\", true, \"date-time-inputs\", { settings: { type } })\n )\n );\n\n expect(form.field(\"date\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"time\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"dateTimeWithTimezone\").vm.renderer).toBe(\"dateTimeInputs\");\n expect(form.field(\"dateTimeWithoutTimezone\").vm.renderer).toBe(\"dateTimeInputs\");\n });\n\n it(\"applies the fallback to fields nested in object lists\", () => {\n const form = createCmsForm([\n field(\"holidayHours\", \"object\", true, \"objects-accordion\", {\n settings: {\n fields: [field(\"openTime\", \"datetime\", false, \"date-time-inputs\")],\n layout: [[\"openTime\"]]\n }\n })\n ]);\n\n form.setData({ holidayHours: [{ openTime: \"2026-12-24T09:00:00.000Z\" }] });\n const item = (form.field(\"holidayHours\") as any).items[0];\n\n expect(item.children.get(\"openTime\").vm.renderer).toBe(\"dateTimeInput\");\n });\n});\n\ndescribe(\"CmsFormModelBuilder birthday picker\", () => {\n it(\"renders a date-only field with the birthday picker and keeps its value\", () => {\n const form = createCmsForm([\n field(\"dob\", \"datetime\", false, \"birthday-input\", {\n settings: { type: \"date\" },\n renderer: { name: \"birthday-input\", settings: null }\n })\n ]);\n form.setData({ dob: \"1990-02-09\" });\n\n const vm = form.field(\"dob\").vm as any;\n expect(vm.renderer).toBe(\"birthdayInput\");\n expect(vm.rendererSettings).toEqual({ type: \"date\" });\n expect(vm.value).toBe(\"1990-02-09\");\n });\n\n it(\"hands the field's date limits to the birthday picker\", () => {\n const form = createCmsForm([\n field(\"dob\", \"datetime\", false, \"birthday-input\", {\n settings: { type: \"date\" },\n validation: [\n { name: \"dateGte\", message: \"Too old.\", settings: { value: \"1950-01-01\" } },\n {\n name: \"dateLte\",\n message: \"You must be 18 or older.\",\n settings: { expression: \"today-18y\", type: \"date\" }\n }\n ]\n })\n ]);\n\n expect((form.field(\"dob\").vm as any).rendererSettings).toEqual({\n type: \"date\",\n dateLimits: { gte: [\"1950-01-01\"], lte: [{ expression: \"today-18y\" }] }\n });\n });\n\n it(\"falls back to the date/time input when the field is no longer date-only\", () => {\n const form = createCmsForm([\n field(\"openTime\", \"datetime\", false, \"birthday-input\", { settings: { type: \"time\" } })\n ]);\n\n expect(form.field(\"openTime\").vm.renderer).toBe(\"dateTimeInput\");\n });\n});\n\ndescribe(\"CmsFormModelBuilder validators\", () => {\n const validate = async (form: ReturnType<typeof createCmsForm>, name: string) => {\n const valid = await form.field(name).validate({ force: true });\n return { valid, message: form.field(name).vm.validation.message };\n };\n\n it(\"checks both date limits on a field that has two\", async () => {\n const form = createCmsForm([\n field(\"bornOn\", \"datetime\", false, \"date-time-input\", {\n settings: { type: \"date\" },\n validation: [\n { name: \"dateGte\", message: \"Too early.\", settings: { value: \"1950-01-01\" } },\n { name: \"dateLte\", message: \"Too late.\", settings: { value: \"2000-12-31\" } }\n ]\n })\n ]);\n\n form.setData({ bornOn: \"2005-01-01\" });\n expect(await validate(form, \"bornOn\")).toEqual({ valid: false, message: \"Too late.\" });\n\n form.setData({ bornOn: \"1949-01-01\" });\n expect(await validate(form, \"bornOn\")).toEqual({ valid: false, message: \"Too early.\" });\n\n form.setData({ bornOn: \"1975-06-15\" });\n expect((await validate(form, \"bornOn\")).valid).toBe(true);\n });\n\n it(\"works out a relative limit from today\", async () => {\n const form = createCmsForm([\n field(\"bornOn\", \"datetime\", false, \"birthday-input\", {\n settings: { type: \"date\" },\n validation: [\n {\n name: \"dateLte\",\n message: \"You must be 18 or older.\",\n settings: { expression: \"today-18y\", type: \"date\" }\n }\n ]\n })\n ]);\n\n form.setData({ bornOn: `${new Date().getFullYear() - 10}-01-01` });\n expect(await validate(form, \"bornOn\")).toEqual({\n valid: false,\n message: \"You must be 18 or older.\"\n });\n\n form.setData({ bornOn: `${new Date().getFullYear() - 30}-01-01` });\n expect((await validate(form, \"bornOn\")).valid).toBe(true);\n });\n\n it(\"checks every validator on a text field that has several\", async () => {\n const form = createCmsForm([\n field(\"code\", \"text\", false, \"text-input\", {\n validation: [\n { name: \"minLength\", message: \"Too short.\", settings: { value: 3 } },\n { name: \"maxLength\", message: \"Too long.\", settings: { value: 5 } },\n { name: \"pattern\", message: \"Letters only.\", settings: { regex: \"^[a-z]+$\" } }\n ]\n })\n ]);\n\n form.setData({ code: \"ab\" });\n expect(await validate(form, \"code\")).toEqual({ valid: false, message: \"Too short.\" });\n\n form.setData({ code: \"abcdef\" });\n expect(await validate(form, \"code\")).toEqual({ valid: false, message: \"Too long.\" });\n\n form.setData({ code: \"ab1\" });\n expect(await validate(form, \"code\")).toEqual({ valid: false, message: \"Letters only.\" });\n\n form.setData({ code: \"abcd\" });\n expect((await validate(form, \"code\")).valid).toBe(true);\n });\n});\n\nconst rowNames = (layout: any[]) => layout.map(row => row.fields.map((f: any) => f.name));\n\ndescribe(\"CmsFormModelBuilder nested layouts\", () => {\n it(\"lays out a single object with the layout stored on the field\", () => {\n const form = createCmsForm([\n field(\"address\", \"object\", false, \"object-accordion\", {\n settings: {\n fields: [\n field(\"street\", \"text\", false, \"text-input\"),\n // Fields created in the model editor have an `id` that differs from `fieldId`.\n field(\"city\", \"text\", false, \"text-input\", { id: \"c1ty\" }),\n field(\"zipCode\", \"text\", false, \"text-input\")\n ],\n layout: [[\"street\"], [\"c1ty\", \"zipCode\"]]\n }\n })\n ]);\n\n expect(rowNames((form.field(\"address\").vm as any).layout)).toEqual([\n [\"street\"],\n [\"city\", \"zipCode\"]\n ]);\n });\n\n it(\"lays out every item of an object list\", () => {\n const form = createCmsForm([\n field(\"facilityStats\", \"object\", true, \"objects-accordion\", {\n settings: {\n fields: [\n field(\"statValue\", \"text\", false, \"text-input\"),\n field(\"statLabel\", \"text\", false, \"text-input\")\n ],\n layout: [[\"statValue\", \"statLabel\"]]\n }\n })\n ]);\n\n form.setData({ facilityStats: [{ statValue: \"1\", statLabel: \"a\" }] });\n const vm = form.field(\"facilityStats\").vm as any;\n\n expect(rowNames(vm.items[0].layout)).toEqual([[\"statValue\", \"statLabel\"]]);\n });\n\n it(\"gives children missing from the stored layout a row of their own\", () => {\n const form = createCmsForm([\n field(\"address\", \"object\", false, \"object-accordion\", {\n settings: {\n fields: [\n field(\"street\", \"text\", false, \"text-input\"),\n field(\"city\", \"text\", false, \"text-input\"),\n field(\"state\", \"text\", false, \"text-input\")\n ],\n layout: [[\"street\", \"city\"]]\n }\n })\n ]);\n\n expect(rowNames((form.field(\"address\").vm as any).layout)).toEqual([\n [\"street\", \"city\"],\n [\"state\"]\n ]);\n });\n\n it(\"lays out a dynamic zone template with the template's layout\", () => {\n const form = createCmsForm([\n field(\"blocks\", \"dynamicZone\", true, \"dynamicZone\", {\n settings: {\n templates: [\n {\n id: \"hero\",\n name: \"Hero\",\n gqlTypeName: \"Hero\",\n description: \"\",\n icon: null,\n fields: [\n field(\"title\", \"text\", false, \"text-input\"),\n field(\"subtitle\", \"text\", false, \"text-input\")\n ],\n layout: [[\"title\", \"subtitle\"]],\n validation: []\n }\n ]\n }\n })\n ]);\n\n form.setData({ blocks: [{ _templateId: \"hero\", title: \"T\", subtitle: \"S\" }] });\n const vm = form.field(\"blocks\").vm as any;\n\n expect(rowNames(vm.items[0].layout)).toEqual([[\"title\", \"subtitle\"]]);\n });\n});\n"],"names":["field","fieldId","type","list","renderer","extra","createCmsForm","fields","container","Container","IdentityContextFeature","FormModelFeature","CmsFormModelFeature","DateTimeInputRenderer","DateTimeInputsRenderer","BirthdayInputRenderer","TextInputRenderer","TextInputsRenderer","model","f","config","CmsFormModelBuilder","FormModelFactory","describe","it","form","expect","item","vm","validate","name","valid","Date","rowNames","layout","row"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { DateBound } from "@webiny/utils";
|
|
2
3
|
import type { CmsModelFieldValidator } from "../../types.js";
|
|
3
4
|
export declare function mapCmsValidators(validators: (CmsModelFieldValidator | {
|
|
4
5
|
name: string;
|
|
@@ -7,6 +8,14 @@ export declare function mapCmsValidators(validators: (CmsModelFieldValidator | {
|
|
|
7
8
|
requiredMessage?: string;
|
|
8
9
|
schema: z.ZodTypeAny | undefined;
|
|
9
10
|
};
|
|
11
|
+
/** The `dateGte`/`dateLte` validators, as limits for the `datetime()` builder. */
|
|
12
|
+
export declare function mapCmsDateLimits(validators: (CmsModelFieldValidator | {
|
|
13
|
+
name: string;
|
|
14
|
+
})[] | undefined): {
|
|
15
|
+
name: "dateGte" | "dateLte";
|
|
16
|
+
bound: DateBound;
|
|
17
|
+
message?: string;
|
|
18
|
+
}[];
|
|
10
19
|
export declare function mapCmsListValidators(validators: (CmsModelFieldValidator | {
|
|
11
20
|
name: string;
|
|
12
21
|
})[] | undefined): {
|
|
@@ -44,31 +44,37 @@ function mapCmsValidators(validators) {
|
|
|
44
44
|
case "in":
|
|
45
45
|
if (Array.isArray(settings.values) && settings.values.length > 0) schemas.push(z["enum"](settings.values));
|
|
46
46
|
break;
|
|
47
|
-
case "dateGte":
|
|
48
|
-
if (null != settings.value) {
|
|
49
|
-
const minDate = settings.value;
|
|
50
|
-
schemas.push(z.string().refine((val)=>val >= minDate, {
|
|
51
|
-
message: msg || `Must be on or after ${minDate}`
|
|
52
|
-
}));
|
|
53
|
-
}
|
|
54
|
-
break;
|
|
55
|
-
case "dateLte":
|
|
56
|
-
if (null != settings.value) {
|
|
57
|
-
const maxDate = settings.value;
|
|
58
|
-
schemas.push(z.string().refine((val)=>val <= maxDate, {
|
|
59
|
-
message: msg || `Must be on or before ${maxDate}`
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
break;
|
|
63
47
|
}
|
|
64
48
|
}
|
|
65
|
-
const schema = 0 === schemas.length ? void 0 :
|
|
49
|
+
const schema = 0 === schemas.length ? void 0 : schemas.slice(1).reduce((acc, s)=>z.intersection(acc, s), schemas[0]);
|
|
66
50
|
return {
|
|
67
51
|
required,
|
|
68
52
|
requiredMessage,
|
|
69
|
-
schema
|
|
53
|
+
schema
|
|
70
54
|
};
|
|
71
55
|
}
|
|
56
|
+
function mapCmsDateLimits(validators) {
|
|
57
|
+
const limits = [];
|
|
58
|
+
for (const v of validators || []){
|
|
59
|
+
const validator = v;
|
|
60
|
+
if ("dateGte" !== validator.name && "dateLte" !== validator.name) continue;
|
|
61
|
+
const settings = validator.settings || {};
|
|
62
|
+
const message = interpolateMessage(validator.message, settings);
|
|
63
|
+
if ("string" == typeof settings.expression) limits.push({
|
|
64
|
+
name: validator.name,
|
|
65
|
+
bound: {
|
|
66
|
+
expression: settings.expression
|
|
67
|
+
},
|
|
68
|
+
message
|
|
69
|
+
});
|
|
70
|
+
else if (null != settings.value) limits.push({
|
|
71
|
+
name: validator.name,
|
|
72
|
+
bound: String(settings.value),
|
|
73
|
+
message
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return limits;
|
|
77
|
+
}
|
|
72
78
|
function mapCmsListValidators(validators) {
|
|
73
79
|
if (!validators || 0 === validators.length) return {
|
|
74
80
|
required: false,
|
|
@@ -101,6 +107,6 @@ function mapCmsListValidators(validators) {
|
|
|
101
107
|
schema: hasConstraints ? arraySchema : void 0
|
|
102
108
|
};
|
|
103
109
|
}
|
|
104
|
-
export { mapCmsListValidators, mapCmsValidators };
|
|
110
|
+
export { mapCmsDateLimits, mapCmsListValidators, mapCmsValidators };
|
|
105
111
|
|
|
106
112
|
//# sourceMappingURL=CmsValidationMapper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/formModel/CmsValidationMapper.js","sources":["../../../src/features/formModel/CmsValidationMapper.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { CmsModelFieldValidator } from \"~/types.js\";\n\nfunction interpolateMessage(\n message: string | undefined,\n settings: Record<string, unknown>\n): string | undefined {\n if (!message) {\n return undefined;\n }\n return message.replace(/\\{(\\w+)}/g, (match, key) => {\n const val = settings[key];\n return val != null ? String(val) : match;\n });\n}\n\nexport function mapCmsValidators(\n validators: (CmsModelFieldValidator | { name: string })[] | undefined\n): { required: boolean; requiredMessage?: string; schema: z.ZodTypeAny | undefined } {\n if (!validators || validators.length === 0) {\n return { required: false, schema: undefined };\n }\n\n let required = false;\n let requiredMessage: string | undefined;\n const schemas: z.ZodTypeAny[] = [];\n\n for (const v of validators) {\n const validator = v as CmsModelFieldValidator;\n const settings = validator.settings || {};\n\n const msg = interpolateMessage(validator.message, settings);\n\n switch (validator.name) {\n case \"required\":\n required = true;\n requiredMessage = msg;\n break;\n\n case \"minLength\":\n if (settings.value != null) {\n schemas.push(z.string().min(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"maxLength\":\n if (settings.value != null) {\n schemas.push(z.string().max(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"pattern\":\n if (settings.regex) {\n const flags = settings.flags || \"\";\n schemas.push(\n z.string().regex(new RegExp(settings.regex, flags), msg || undefined)\n );\n }\n break;\n\n case \"gte\":\n if (settings.value != null) {\n schemas.push(z.number().gte(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"lte\":\n if (settings.value != null) {\n schemas.push(z.number().lte(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"in\":\n if (Array.isArray(settings.values) && settings.values.length > 0) {\n schemas.push(z.enum(settings.values as [string, ...string[]]));\n }\n break;\n\n
|
|
1
|
+
{"version":3,"file":"features/formModel/CmsValidationMapper.js","sources":["../../../src/features/formModel/CmsValidationMapper.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { DateBound } from \"@webiny/utils\";\nimport type { CmsModelFieldValidator } from \"~/types.js\";\n\nfunction interpolateMessage(\n message: string | undefined,\n settings: Record<string, unknown>\n): string | undefined {\n if (!message) {\n return undefined;\n }\n return message.replace(/\\{(\\w+)}/g, (match, key) => {\n const val = settings[key];\n return val != null ? String(val) : match;\n });\n}\n\nexport function mapCmsValidators(\n validators: (CmsModelFieldValidator | { name: string })[] | undefined\n): { required: boolean; requiredMessage?: string; schema: z.ZodTypeAny | undefined } {\n if (!validators || validators.length === 0) {\n return { required: false, schema: undefined };\n }\n\n let required = false;\n let requiredMessage: string | undefined;\n const schemas: z.ZodTypeAny[] = [];\n\n for (const v of validators) {\n const validator = v as CmsModelFieldValidator;\n const settings = validator.settings || {};\n\n const msg = interpolateMessage(validator.message, settings);\n\n switch (validator.name) {\n case \"required\":\n required = true;\n requiredMessage = msg;\n break;\n\n case \"minLength\":\n if (settings.value != null) {\n schemas.push(z.string().min(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"maxLength\":\n if (settings.value != null) {\n schemas.push(z.string().max(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"pattern\":\n if (settings.regex) {\n const flags = settings.flags || \"\";\n schemas.push(\n z.string().regex(new RegExp(settings.regex, flags), msg || undefined)\n );\n }\n break;\n\n case \"gte\":\n if (settings.value != null) {\n schemas.push(z.number().gte(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"lte\":\n if (settings.value != null) {\n schemas.push(z.number().lte(Number(settings.value), msg || undefined));\n }\n break;\n\n case \"in\":\n if (Array.isArray(settings.values) && settings.values.length > 0) {\n schemas.push(z.enum(settings.values as [string, ...string[]]));\n }\n break;\n\n // \"dateGte\" and \"dateLte\" are applied by `DateTimeFieldMapper`, through the\n // `datetime()` builder, which also hands the limits to the field's picker.\n }\n }\n\n const schema =\n schemas.length === 0\n ? undefined\n : schemas.slice(1).reduce<z.ZodTypeAny>((acc, s) => z.intersection(acc, s), schemas[0]);\n\n return { required, requiredMessage, schema };\n}\n\n/** The `dateGte`/`dateLte` validators, as limits for the `datetime()` builder. */\nexport function mapCmsDateLimits(\n validators: (CmsModelFieldValidator | { name: string })[] | undefined\n): { name: \"dateGte\" | \"dateLte\"; bound: DateBound; message?: string }[] {\n const limits: { name: \"dateGte\" | \"dateLte\"; bound: DateBound; message?: string }[] = [];\n for (const v of validators || []) {\n const validator = v as CmsModelFieldValidator;\n if (validator.name !== \"dateGte\" && validator.name !== \"dateLte\") {\n continue;\n }\n const settings = validator.settings || {};\n const message = interpolateMessage(validator.message, settings);\n if (typeof settings.expression === \"string\") {\n limits.push({\n name: validator.name,\n bound: { expression: settings.expression },\n message\n });\n } else if (settings.value != null) {\n limits.push({ name: validator.name, bound: String(settings.value), message });\n }\n }\n return limits;\n}\n\nexport function mapCmsListValidators(\n validators: (CmsModelFieldValidator | { name: string })[] | undefined\n): { required: boolean; requiredMessage?: string; schema: z.ZodTypeAny | undefined } {\n if (!validators || validators.length === 0) {\n return { required: false, schema: undefined };\n }\n\n let required = false;\n let requiredMessage: string | undefined;\n let arraySchema = z.array(z.unknown());\n\n for (const v of validators) {\n const validator = v as CmsModelFieldValidator;\n const settings = validator.settings || {};\n const msg = interpolateMessage(validator.message, settings);\n\n switch (validator.name) {\n case \"required\":\n required = true;\n requiredMessage = msg;\n break;\n\n case \"minLength\":\n if (settings.value != null) {\n arraySchema = arraySchema.min(\n Number(settings.value),\n msg || undefined\n ) as typeof arraySchema;\n }\n break;\n\n case \"maxLength\":\n if (settings.value != null) {\n arraySchema = arraySchema.max(\n Number(settings.value),\n msg || undefined\n ) as typeof arraySchema;\n }\n break;\n }\n }\n\n const hasConstraints = validators.some(\n v =>\n (v as CmsModelFieldValidator).name === \"minLength\" ||\n (v as CmsModelFieldValidator).name === \"maxLength\"\n );\n\n return {\n required,\n requiredMessage,\n schema: hasConstraints ? arraySchema : undefined\n };\n}\n"],"names":["interpolateMessage","message","settings","match","key","val","String","mapCmsValidators","validators","undefined","required","requiredMessage","schemas","v","validator","msg","z","Number","flags","RegExp","Array","schema","acc","s","mapCmsDateLimits","limits","mapCmsListValidators","arraySchema","hasConstraints"],"mappings":";AAIA,SAASA,mBACLC,OAA2B,EAC3BC,QAAiC;IAEjC,IAAI,CAACD,SACD;IAEJ,OAAOA,QAAQ,OAAO,CAAC,aAAa,CAACE,OAAOC;QACxC,MAAMC,MAAMH,QAAQ,CAACE,IAAI;QACzB,OAAOC,AAAO,QAAPA,MAAcC,OAAOD,OAAOF;IACvC;AACJ;AAEO,SAASI,iBACZC,UAAqE;IAErE,IAAI,CAACA,cAAcA,AAAsB,MAAtBA,WAAW,MAAM,EAChC,OAAO;QAAE,UAAU;QAAO,QAAQC;IAAU;IAGhD,IAAIC,WAAW;IACf,IAAIC;IACJ,MAAMC,UAA0B,EAAE;IAElC,KAAK,MAAMC,KAAKL,WAAY;QACxB,MAAMM,YAAYD;QAClB,MAAMX,WAAWY,UAAU,QAAQ,IAAI,CAAC;QAExC,MAAMC,MAAMf,mBAAmBc,UAAU,OAAO,EAAEZ;QAElD,OAAQY,UAAU,IAAI;YAClB,KAAK;gBACDJ,WAAW;gBACXC,kBAAkBI;gBAClB;YAEJ,KAAK;gBACD,IAAIb,AAAkB,QAAlBA,SAAS,KAAK,EACdU,QAAQ,IAAI,CAACI,EAAE,MAAM,GAAG,GAAG,CAACC,OAAOf,SAAS,KAAK,GAAGa,OAAON;gBAE/D;YAEJ,KAAK;gBACD,IAAIP,AAAkB,QAAlBA,SAAS,KAAK,EACdU,QAAQ,IAAI,CAACI,EAAE,MAAM,GAAG,GAAG,CAACC,OAAOf,SAAS,KAAK,GAAGa,OAAON;gBAE/D;YAEJ,KAAK;gBACD,IAAIP,SAAS,KAAK,EAAE;oBAChB,MAAMgB,QAAQhB,SAAS,KAAK,IAAI;oBAChCU,QAAQ,IAAI,CACRI,EAAE,MAAM,GAAG,KAAK,CAAC,IAAIG,OAAOjB,SAAS,KAAK,EAAEgB,QAAQH,OAAON;gBAEnE;gBACA;YAEJ,KAAK;gBACD,IAAIP,AAAkB,QAAlBA,SAAS,KAAK,EACdU,QAAQ,IAAI,CAACI,EAAE,MAAM,GAAG,GAAG,CAACC,OAAOf,SAAS,KAAK,GAAGa,OAAON;gBAE/D;YAEJ,KAAK;gBACD,IAAIP,AAAkB,QAAlBA,SAAS,KAAK,EACdU,QAAQ,IAAI,CAACI,EAAE,MAAM,GAAG,GAAG,CAACC,OAAOf,SAAS,KAAK,GAAGa,OAAON;gBAE/D;YAEJ,KAAK;gBACD,IAAIW,MAAM,OAAO,CAAClB,SAAS,MAAM,KAAKA,SAAS,MAAM,CAAC,MAAM,GAAG,GAC3DU,QAAQ,IAAI,CAACI,CAAC,CAADA,OAAM,CAACd,SAAS,MAAM;gBAEvC;QAIR;IACJ;IAEA,MAAMmB,SACFT,AAAmB,MAAnBA,QAAQ,MAAM,GACRH,SACAG,QAAQ,KAAK,CAAC,GAAG,MAAM,CAAe,CAACU,KAAKC,IAAMP,EAAE,YAAY,CAACM,KAAKC,IAAIX,OAAO,CAAC,EAAE;IAE9F,OAAO;QAAEF;QAAUC;QAAiBU;IAAO;AAC/C;AAGO,SAASG,iBACZhB,UAAqE;IAErE,MAAMiB,SAAgF,EAAE;IACxF,KAAK,MAAMZ,KAAKL,cAAc,EAAE,CAAE;QAC9B,MAAMM,YAAYD;QAClB,IAAIC,AAAmB,cAAnBA,UAAU,IAAI,IAAkBA,AAAmB,cAAnBA,UAAU,IAAI,EAC9C;QAEJ,MAAMZ,WAAWY,UAAU,QAAQ,IAAI,CAAC;QACxC,MAAMb,UAAUD,mBAAmBc,UAAU,OAAO,EAAEZ;QACtD,IAAI,AAA+B,YAA/B,OAAOA,SAAS,UAAU,EAC1BuB,OAAO,IAAI,CAAC;YACR,MAAMX,UAAU,IAAI;YACpB,OAAO;gBAAE,YAAYZ,SAAS,UAAU;YAAC;YACzCD;QACJ;aACG,IAAIC,AAAkB,QAAlBA,SAAS,KAAK,EACrBuB,OAAO,IAAI,CAAC;YAAE,MAAMX,UAAU,IAAI;YAAE,OAAOR,OAAOJ,SAAS,KAAK;YAAGD;QAAQ;IAEnF;IACA,OAAOwB;AACX;AAEO,SAASC,qBACZlB,UAAqE;IAErE,IAAI,CAACA,cAAcA,AAAsB,MAAtBA,WAAW,MAAM,EAChC,OAAO;QAAE,UAAU;QAAO,QAAQC;IAAU;IAGhD,IAAIC,WAAW;IACf,IAAIC;IACJ,IAAIgB,cAAcX,EAAE,KAAK,CAACA,EAAE,OAAO;IAEnC,KAAK,MAAMH,KAAKL,WAAY;QACxB,MAAMM,YAAYD;QAClB,MAAMX,WAAWY,UAAU,QAAQ,IAAI,CAAC;QACxC,MAAMC,MAAMf,mBAAmBc,UAAU,OAAO,EAAEZ;QAElD,OAAQY,UAAU,IAAI;YAClB,KAAK;gBACDJ,WAAW;gBACXC,kBAAkBI;gBAClB;YAEJ,KAAK;gBACD,IAAIb,AAAkB,QAAlBA,SAAS,KAAK,EACdyB,cAAcA,YAAY,GAAG,CACzBV,OAAOf,SAAS,KAAK,GACrBa,OAAON;gBAGf;YAEJ,KAAK;gBACD,IAAIP,AAAkB,QAAlBA,SAAS,KAAK,EACdyB,cAAcA,YAAY,GAAG,CACzBV,OAAOf,SAAS,KAAK,GACrBa,OAAON;gBAGf;QACR;IACJ;IAEA,MAAMmB,iBAAiBpB,WAAW,IAAI,CAClCK,CAAAA,IACKA,AAAsC,gBAAtCA,EAA6B,IAAI,IACjCA,AAAsC,gBAAtCA,EAA6B,IAAI;IAG1C,OAAO;QACHH;QACAC;QACA,QAAQiB,iBAAiBD,cAAclB;IAC3C;AACJ"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { applyFieldProps } from "./applyFieldProps.js";
|
|
2
|
+
import { mapCmsDateLimits } from "../CmsValidationMapper.js";
|
|
2
3
|
class DateTimeFieldMapper {
|
|
3
4
|
map(field, registry, context) {
|
|
4
5
|
const builder = registry.datetime();
|
|
@@ -18,6 +19,8 @@ class DateTimeFieldMapper {
|
|
|
18
19
|
builder.withoutTimezone();
|
|
19
20
|
break;
|
|
20
21
|
}
|
|
22
|
+
for (const limit of mapCmsDateLimits(field.validation))if ("dateGte" === limit.name) builder.dateGte(limit.bound, limit.message);
|
|
23
|
+
else builder.dateLte(limit.bound, limit.message);
|
|
21
24
|
return builder;
|
|
22
25
|
}
|
|
23
26
|
constructor(){
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/formModel/mappers/DateTimeFieldMapper.js","sources":["../../../../src/features/formModel/mappers/DateTimeFieldMapper.ts"],"sourcesContent":["import type { ICmsFieldTypeMapper, ICmsFieldMapperContext } from \"../abstractions.js\";\nimport type { IFieldBuilderRegistry } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport type { CmsModelField } from \"~/types.js\";\nimport { applyFieldProps } from \"./applyFieldProps.js\";\n\nexport class DateTimeFieldMapper implements ICmsFieldTypeMapper {\n readonly type = \"datetime\";\n\n map(field: CmsModelField, registry: IFieldBuilderRegistry, context: ICmsFieldMapperContext) {\n const builder = registry.datetime();\n applyFieldProps(builder, field, context.rendererMap);\n\n const subtype = field.settings?.type as string | undefined;\n switch (subtype) {\n case \"date\":\n builder.dateOnly();\n break;\n case \"time\":\n builder.timeOnly();\n break;\n case \"dateTimeWithTimezone\":\n builder.withTimezone();\n break;\n case \"dateTimeWithoutTimezone\":\n builder.withoutTimezone();\n break;\n }\n\n return builder;\n }\n}\n"],"names":["DateTimeFieldMapper","field","registry","context","builder","applyFieldProps","subtype"],"mappings":"
|
|
1
|
+
{"version":3,"file":"features/formModel/mappers/DateTimeFieldMapper.js","sources":["../../../../src/features/formModel/mappers/DateTimeFieldMapper.ts"],"sourcesContent":["import type { ICmsFieldTypeMapper, ICmsFieldMapperContext } from \"../abstractions.js\";\nimport type { IFieldBuilderRegistry } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport type { CmsModelField } from \"~/types.js\";\nimport { applyFieldProps } from \"./applyFieldProps.js\";\nimport { mapCmsDateLimits } from \"../CmsValidationMapper.js\";\n\nexport class DateTimeFieldMapper implements ICmsFieldTypeMapper {\n readonly type = \"datetime\";\n\n map(field: CmsModelField, registry: IFieldBuilderRegistry, context: ICmsFieldMapperContext) {\n const builder = registry.datetime();\n applyFieldProps(builder, field, context.rendererMap);\n\n const subtype = field.settings?.type as string | undefined;\n switch (subtype) {\n case \"date\":\n builder.dateOnly();\n break;\n case \"time\":\n builder.timeOnly();\n break;\n case \"dateTimeWithTimezone\":\n builder.withTimezone();\n break;\n case \"dateTimeWithoutTimezone\":\n builder.withoutTimezone();\n break;\n }\n\n for (const limit of mapCmsDateLimits(field.validation)) {\n if (limit.name === \"dateGte\") {\n builder.dateGte(limit.bound, limit.message);\n } else {\n builder.dateLte(limit.bound, limit.message);\n }\n }\n\n return builder;\n }\n}\n"],"names":["DateTimeFieldMapper","field","registry","context","builder","applyFieldProps","subtype","limit","mapCmsDateLimits"],"mappings":";;AAMO,MAAMA;IAGT,IAAIC,KAAoB,EAAEC,QAA+B,EAAEC,OAA+B,EAAE;QACxF,MAAMC,UAAUF,SAAS,QAAQ;QACjCG,gBAAgBD,SAASH,OAAOE,QAAQ,WAAW;QAEnD,MAAMG,UAAUL,MAAM,QAAQ,EAAE;QAChC,OAAQK;YACJ,KAAK;gBACDF,QAAQ,QAAQ;gBAChB;YACJ,KAAK;gBACDA,QAAQ,QAAQ;gBAChB;YACJ,KAAK;gBACDA,QAAQ,YAAY;gBACpB;YACJ,KAAK;gBACDA,QAAQ,eAAe;gBACvB;QACR;QAEA,KAAK,MAAMG,SAASC,iBAAiBP,MAAM,UAAU,EACjD,IAAIM,AAAe,cAAfA,MAAM,IAAI,EACVH,QAAQ,OAAO,CAACG,MAAM,KAAK,EAAEA,MAAM,OAAO;aAE1CH,QAAQ,OAAO,CAACG,MAAM,KAAK,EAAEA,MAAM,OAAO;QAIlD,OAAOH;IACX;;aA/BS,IAAI,GAAG;;AAgCpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/app-headless-cms",
|
|
3
|
-
"version": "6.5.0",
|
|
3
|
+
"version": "6.5.1-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -28,25 +28,25 @@
|
|
|
28
28
|
"@fortawesome/react-fontawesome": "3.5.0",
|
|
29
29
|
"@lexical/utils": "0.52.0",
|
|
30
30
|
"@types/react": "18.3.31",
|
|
31
|
-
"@webiny/admin-ui": "6.5.0",
|
|
32
|
-
"@webiny/app": "6.5.0",
|
|
33
|
-
"@webiny/app-aco": "6.5.0",
|
|
34
|
-
"@webiny/app-admin": "6.5.0",
|
|
35
|
-
"@webiny/app-graphql-playground": "6.5.0",
|
|
36
|
-
"@webiny/app-headless-cms-common": "6.5.0",
|
|
37
|
-
"@webiny/cms-sdk": "6.5.0",
|
|
31
|
+
"@webiny/admin-ui": "6.5.1-beta.0",
|
|
32
|
+
"@webiny/app": "6.5.1-beta.0",
|
|
33
|
+
"@webiny/app-aco": "6.5.1-beta.0",
|
|
34
|
+
"@webiny/app-admin": "6.5.1-beta.0",
|
|
35
|
+
"@webiny/app-graphql-playground": "6.5.1-beta.0",
|
|
36
|
+
"@webiny/app-headless-cms-common": "6.5.1-beta.0",
|
|
37
|
+
"@webiny/cms-sdk": "6.5.1-beta.0",
|
|
38
38
|
"@webiny/di": "1.1.0",
|
|
39
|
-
"@webiny/feature": "6.5.0",
|
|
40
|
-
"@webiny/form": "6.5.0",
|
|
41
|
-
"@webiny/frontend-settings": "6.5.0",
|
|
42
|
-
"@webiny/icons": "6.5.0",
|
|
43
|
-
"@webiny/lexical-editor": "6.5.0",
|
|
44
|
-
"@webiny/lexical-nodes": "6.5.0",
|
|
45
|
-
"@webiny/plugins": "6.5.0",
|
|
46
|
-
"@webiny/react-composition": "6.5.0",
|
|
47
|
-
"@webiny/react-properties": "6.5.0",
|
|
48
|
-
"@webiny/utils": "6.5.0",
|
|
49
|
-
"@webiny/validation": "6.5.0",
|
|
39
|
+
"@webiny/feature": "6.5.1-beta.0",
|
|
40
|
+
"@webiny/form": "6.5.1-beta.0",
|
|
41
|
+
"@webiny/frontend-settings": "6.5.1-beta.0",
|
|
42
|
+
"@webiny/icons": "6.5.1-beta.0",
|
|
43
|
+
"@webiny/lexical-editor": "6.5.1-beta.0",
|
|
44
|
+
"@webiny/lexical-nodes": "6.5.1-beta.0",
|
|
45
|
+
"@webiny/plugins": "6.5.1-beta.0",
|
|
46
|
+
"@webiny/react-composition": "6.5.1-beta.0",
|
|
47
|
+
"@webiny/react-properties": "6.5.1-beta.0",
|
|
48
|
+
"@webiny/utils": "6.5.1-beta.0",
|
|
49
|
+
"@webiny/validation": "6.5.1-beta.0",
|
|
50
50
|
"dot-prop-immutable": "2.1.1",
|
|
51
51
|
"graphql": "16.14.2",
|
|
52
52
|
"graphql-tag": "2.12.7",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"zod": "4.6.7"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@webiny/build-tools": "6.5.0",
|
|
66
|
+
"@webiny/build-tools": "6.5.1-beta.0",
|
|
67
67
|
"rimraf": "6.1.3",
|
|
68
68
|
"typescript": "7.0.2",
|
|
69
69
|
"vitest": "5.0.5"
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { CmsFieldEditorGroup } from "../abstractions.js";
|
|
2
2
|
import { CmsFieldRenderer } from "../../fieldRenderers/abstractions.js";
|
|
3
|
+
const getOptionalValue = (form, path)=>{
|
|
4
|
+
try {
|
|
5
|
+
return form.field(path).getValue();
|
|
6
|
+
} catch {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
3
10
|
class AppearanceGroupImpl {
|
|
4
11
|
constructor(allRenderers){
|
|
5
12
|
this.allRenderers = allRenderers;
|
|
@@ -13,9 +20,14 @@ class AppearanceGroupImpl {
|
|
|
13
20
|
name: fields.text().options(({ form })=>{
|
|
14
21
|
const list = Boolean(form.field("general.list").getValue());
|
|
15
22
|
const predefined = Boolean(form.field("general.predefinedValuesEnabled").getValue());
|
|
23
|
+
const settingsType = getOptionalValue(form, "general.settingsType");
|
|
16
24
|
const liveField = {
|
|
17
25
|
...context.field,
|
|
18
26
|
list,
|
|
27
|
+
settings: "string" == typeof settingsType ? {
|
|
28
|
+
...context.field.settings,
|
|
29
|
+
type: settingsType
|
|
30
|
+
} : context.field.settings,
|
|
19
31
|
predefinedValues: {
|
|
20
32
|
values: context.field.predefinedValues?.values ?? [],
|
|
21
33
|
enabled: predefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentation/fieldEditor/groups/AppearanceGroup.js","sources":["../../../../src/presentation/fieldEditor/groups/AppearanceGroup.ts"],"sourcesContent":["import { CmsFieldEditorGroup } from \"../abstractions.js\";\nimport type { ICmsFieldEditorFormBuilder, ICmsFieldEditorContext } from \"../abstractions.js\";\nimport type { CmsModelField } from \"~/types.js\";\nimport { CmsFieldRenderer } from \"~/presentation/fieldRenderers/abstractions.js\";\nimport type {\n ICmsFieldRenderer,\n ICmsFieldRendererFormBuilder\n} from \"~/presentation/fieldRenderers/abstractions.js\";\nimport type { FormModelFactory, FormModel } from \"@webiny/app-admin\";\n\ndeclare module \"@webiny/app-admin/features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n cmsAppearance: { fieldType: \"object\"; settings: undefined };\n }\n}\n\ninterface RendererSettingsBuild {\n rendererName: string;\n fieldsFns: Array<\n (f: FormModelFactory.FieldBuilderRegistry) => Record<string, FormModelFactory.FieldBuilder>\n >;\n layoutFns: Array<(l: FormModelFactory.LayoutBuilder) => FormModel.LayoutNodeBuilder[]>;\n}\n\nclass AppearanceGroupImpl implements CmsFieldEditorGroup.Interface {\n name = \"appearance\";\n label = \"Appearance\";\n\n constructor(private allRenderers: ICmsFieldRenderer[]) {}\n\n buildForm(form: ICmsFieldEditorFormBuilder, context: ICmsFieldEditorContext) {\n const settingsBuilds = this.collectRendererSettings(this.allRenderers);\n\n form.fields(fields => {\n const rendererChildren: Record<string, FormModelFactory.FieldBuilder> = {\n name: fields.text().options(({ form }) => {\n const list = Boolean(form.field(\"general.list\").getValue());\n const predefined = Boolean(\n form.field(\"general.predefinedValuesEnabled\").getValue()\n );\n const liveField = {\n ...context.field,\n list,\n predefinedValues: {\n values: context.field.predefinedValues?.values ?? [],\n enabled: predefined\n }\n };\n\n return this.allRenderers\n .filter(r => r.canUse({ field: liveField, model: context.model }))\n .map(r => ({ label: r.name, value: r.rendererName }));\n })\n };\n\n for (const build of settingsBuilds) {\n const notSelected = ({ field }: FormModel.CallbackParams) =>\n field.parent().field(\"name\").getValue() !== build.rendererName;\n\n rendererChildren[`settings__${build.rendererName}`] = fields\n .object()\n .renderer(\"passthrough\")\n .hiddenWhen(notSelected)\n .fields((f: FormModelFactory.FieldBuilderRegistry) => {\n const merged: Record<string, FormModelFactory.FieldBuilder> = {};\n for (const fn of build.fieldsFns) {\n Object.assign(merged, fn(f));\n }\n return merged;\n });\n }\n\n return {\n renderer: fields\n .object()\n .renderer(\"cmsAppearance\")\n .fields(() => rendererChildren)\n };\n });\n\n form.layout(layout => {\n const innerLayout = (inner: FormModelFactory.LayoutBuilder) => {\n const nodes: FormModel.LayoutNodeBuilder[] = [inner.row(\"name\")];\n for (const build of settingsBuilds) {\n nodes.push(\n inner.object(`settings__${build.rendererName}`, settingsInner =>\n build.layoutFns.flatMap(fn => fn(settingsInner))\n )\n );\n }\n return nodes;\n };\n\n return [layout.object(\"renderer\", innerLayout)];\n });\n }\n\n mapToForm(field: CmsModelField) {\n const renderer = typeof field.renderer === \"object\" ? field.renderer : null;\n const rendererName = renderer ? renderer.name : \"\";\n const settings = renderer ? (renderer.settings ?? {}) : {};\n\n const result: Record<string, unknown> = {\n name: rendererName\n };\n\n for (const r of this.allRenderers) {\n if (r.buildSettingsForm) {\n result[`settings__${r.rendererName}`] =\n r.rendererName === rendererName ? settings : {};\n }\n }\n\n return { renderer: result };\n }\n\n mapFromForm(formData: Record<string, any>, field: CmsModelField) {\n const rendererName = formData.renderer?.name || \"\";\n const settingsKey = `settings__${rendererName}`;\n const settings = formData.renderer?.[settingsKey] ?? {};\n\n field.renderer = {\n name: rendererName,\n settings\n };\n }\n\n private collectRendererSettings(renderers: ICmsFieldRenderer[]): RendererSettingsBuild[] {\n const builds: RendererSettingsBuild[] = [];\n\n for (const renderer of renderers) {\n if (!renderer.buildSettingsForm) {\n continue;\n }\n\n const fieldsFns: RendererSettingsBuild[\"fieldsFns\"] = [];\n const layoutFns: RendererSettingsBuild[\"layoutFns\"] = [];\n\n const builder: ICmsFieldRendererFormBuilder = {\n fields: fn => {\n fieldsFns.push(fn);\n },\n layout: fn => {\n layoutFns.push(fn);\n }\n };\n\n renderer.buildSettingsForm(builder);\n\n if (fieldsFns.length > 0) {\n builds.push({ rendererName: renderer.rendererName, fieldsFns, layoutFns });\n }\n }\n\n return builds;\n }\n}\n\nexport const AppearanceGroup = CmsFieldEditorGroup.createImplementation({\n implementation: AppearanceGroupImpl,\n dependencies: [[CmsFieldRenderer, { multiple: true }]]\n});\n"],"names":["AppearanceGroupImpl","allRenderers","form","context","settingsBuilds","fields","rendererChildren","list","Boolean","predefined","liveField","r","build","notSelected","field","f","merged","fn","Object","layout","innerLayout","inner","nodes","settingsInner","renderer","rendererName","settings","result","formData","settingsKey","renderers","builds","fieldsFns","layoutFns","builder","AppearanceGroup","CmsFieldEditorGroup","CmsFieldRenderer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"presentation/fieldEditor/groups/AppearanceGroup.js","sources":["../../../../src/presentation/fieldEditor/groups/AppearanceGroup.ts"],"sourcesContent":["import { CmsFieldEditorGroup } from \"../abstractions.js\";\nimport type { ICmsFieldEditorFormBuilder, ICmsFieldEditorContext } from \"../abstractions.js\";\nimport type { CmsModelField } from \"~/types.js\";\nimport { CmsFieldRenderer } from \"~/presentation/fieldRenderers/abstractions.js\";\nimport type {\n ICmsFieldRenderer,\n ICmsFieldRendererFormBuilder\n} from \"~/presentation/fieldRenderers/abstractions.js\";\nimport type { FormModelFactory, FormModel } from \"@webiny/app-admin\";\n\ndeclare module \"@webiny/app-admin/features/formModel/abstractions.js\" {\n interface IFieldRendererRegistry {\n cmsAppearance: { fieldType: \"object\"; settings: undefined };\n }\n}\n\n/**\n * Only some field types add the field (date/time adds `general.settingsType`, the Format\n * dropdown), and `form.field()` throws for a path the form doesn't have.\n */\nconst getOptionalValue = (form: FormModel.Interface, path: string): unknown => {\n try {\n return form.field(path).getValue();\n } catch {\n return undefined;\n }\n};\n\ninterface RendererSettingsBuild {\n rendererName: string;\n fieldsFns: Array<\n (f: FormModelFactory.FieldBuilderRegistry) => Record<string, FormModelFactory.FieldBuilder>\n >;\n layoutFns: Array<(l: FormModelFactory.LayoutBuilder) => FormModel.LayoutNodeBuilder[]>;\n}\n\nclass AppearanceGroupImpl implements CmsFieldEditorGroup.Interface {\n name = \"appearance\";\n label = \"Appearance\";\n\n constructor(private allRenderers: ICmsFieldRenderer[]) {}\n\n buildForm(form: ICmsFieldEditorFormBuilder, context: ICmsFieldEditorContext) {\n const settingsBuilds = this.collectRendererSettings(this.allRenderers);\n\n form.fields(fields => {\n const rendererChildren: Record<string, FormModelFactory.FieldBuilder> = {\n name: fields.text().options(({ form }) => {\n const list = Boolean(form.field(\"general.list\").getValue());\n const predefined = Boolean(\n form.field(\"general.predefinedValuesEnabled\").getValue()\n );\n const settingsType = getOptionalValue(form, \"general.settingsType\");\n const liveField = {\n ...context.field,\n list,\n settings:\n typeof settingsType === \"string\"\n ? { ...context.field.settings, type: settingsType }\n : context.field.settings,\n predefinedValues: {\n values: context.field.predefinedValues?.values ?? [],\n enabled: predefined\n }\n };\n\n return this.allRenderers\n .filter(r => r.canUse({ field: liveField, model: context.model }))\n .map(r => ({ label: r.name, value: r.rendererName }));\n })\n };\n\n for (const build of settingsBuilds) {\n const notSelected = ({ field }: FormModel.CallbackParams) =>\n field.parent().field(\"name\").getValue() !== build.rendererName;\n\n rendererChildren[`settings__${build.rendererName}`] = fields\n .object()\n .renderer(\"passthrough\")\n .hiddenWhen(notSelected)\n .fields((f: FormModelFactory.FieldBuilderRegistry) => {\n const merged: Record<string, FormModelFactory.FieldBuilder> = {};\n for (const fn of build.fieldsFns) {\n Object.assign(merged, fn(f));\n }\n return merged;\n });\n }\n\n return {\n renderer: fields\n .object()\n .renderer(\"cmsAppearance\")\n .fields(() => rendererChildren)\n };\n });\n\n form.layout(layout => {\n const innerLayout = (inner: FormModelFactory.LayoutBuilder) => {\n const nodes: FormModel.LayoutNodeBuilder[] = [inner.row(\"name\")];\n for (const build of settingsBuilds) {\n nodes.push(\n inner.object(`settings__${build.rendererName}`, settingsInner =>\n build.layoutFns.flatMap(fn => fn(settingsInner))\n )\n );\n }\n return nodes;\n };\n\n return [layout.object(\"renderer\", innerLayout)];\n });\n }\n\n mapToForm(field: CmsModelField) {\n const renderer = typeof field.renderer === \"object\" ? field.renderer : null;\n const rendererName = renderer ? renderer.name : \"\";\n const settings = renderer ? (renderer.settings ?? {}) : {};\n\n const result: Record<string, unknown> = {\n name: rendererName\n };\n\n for (const r of this.allRenderers) {\n if (r.buildSettingsForm) {\n result[`settings__${r.rendererName}`] =\n r.rendererName === rendererName ? settings : {};\n }\n }\n\n return { renderer: result };\n }\n\n mapFromForm(formData: Record<string, any>, field: CmsModelField) {\n const rendererName = formData.renderer?.name || \"\";\n const settingsKey = `settings__${rendererName}`;\n const settings = formData.renderer?.[settingsKey] ?? {};\n\n field.renderer = {\n name: rendererName,\n settings\n };\n }\n\n private collectRendererSettings(renderers: ICmsFieldRenderer[]): RendererSettingsBuild[] {\n const builds: RendererSettingsBuild[] = [];\n\n for (const renderer of renderers) {\n if (!renderer.buildSettingsForm) {\n continue;\n }\n\n const fieldsFns: RendererSettingsBuild[\"fieldsFns\"] = [];\n const layoutFns: RendererSettingsBuild[\"layoutFns\"] = [];\n\n const builder: ICmsFieldRendererFormBuilder = {\n fields: fn => {\n fieldsFns.push(fn);\n },\n layout: fn => {\n layoutFns.push(fn);\n }\n };\n\n renderer.buildSettingsForm(builder);\n\n if (fieldsFns.length > 0) {\n builds.push({ rendererName: renderer.rendererName, fieldsFns, layoutFns });\n }\n }\n\n return builds;\n }\n}\n\nexport const AppearanceGroup = CmsFieldEditorGroup.createImplementation({\n implementation: AppearanceGroupImpl,\n dependencies: [[CmsFieldRenderer, { multiple: true }]]\n});\n"],"names":["getOptionalValue","form","path","AppearanceGroupImpl","allRenderers","context","settingsBuilds","fields","rendererChildren","list","Boolean","predefined","settingsType","liveField","r","build","notSelected","field","f","merged","fn","Object","layout","innerLayout","inner","nodes","settingsInner","renderer","rendererName","settings","result","formData","settingsKey","renderers","builds","fieldsFns","layoutFns","builder","AppearanceGroup","CmsFieldEditorGroup","CmsFieldRenderer"],"mappings":";;AAoBA,MAAMA,mBAAmB,CAACC,MAA2BC;IACjD,IAAI;QACA,OAAOD,KAAK,KAAK,CAACC,MAAM,QAAQ;IACpC,EAAE,OAAM;QACJ;IACJ;AACJ;AAUA,MAAMC;IAIF,YAAoBC,YAAiC,CAAE;aAAnCA,YAAY,GAAZA;aAHpB,IAAI,GAAG;aACP,KAAK,GAAG;IAEgD;IAExD,UAAUH,IAAgC,EAAEI,OAA+B,EAAE;QACzE,MAAMC,iBAAiB,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,YAAY;QAErEL,KAAK,MAAM,CAACM,CAAAA;YACR,MAAMC,mBAAkE;gBACpE,MAAMD,OAAO,IAAI,GAAG,OAAO,CAAC,CAAC,EAAEN,IAAI,EAAE;oBACjC,MAAMQ,OAAOC,QAAQT,KAAK,KAAK,CAAC,gBAAgB,QAAQ;oBACxD,MAAMU,aAAaD,QACfT,KAAK,KAAK,CAAC,mCAAmC,QAAQ;oBAE1D,MAAMW,eAAeZ,iBAAiBC,MAAM;oBAC5C,MAAMY,YAAY;wBACd,GAAGR,QAAQ,KAAK;wBAChBI;wBACA,UACI,AAAwB,YAAxB,OAAOG,eACD;4BAAE,GAAGP,QAAQ,KAAK,CAAC,QAAQ;4BAAE,MAAMO;wBAAa,IAChDP,QAAQ,KAAK,CAAC,QAAQ;wBAChC,kBAAkB;4BACd,QAAQA,QAAQ,KAAK,CAAC,gBAAgB,EAAE,UAAU,EAAE;4BACpD,SAASM;wBACb;oBACJ;oBAEA,OAAO,IAAI,CAAC,YAAY,CACnB,MAAM,CAACG,CAAAA,IAAKA,EAAE,MAAM,CAAC;4BAAE,OAAOD;4BAAW,OAAOR,QAAQ,KAAK;wBAAC,IAC9D,GAAG,CAACS,CAAAA,IAAM;4BAAE,OAAOA,EAAE,IAAI;4BAAE,OAAOA,EAAE,YAAY;wBAAC;gBAC1D;YACJ;YAEA,KAAK,MAAMC,SAAST,eAAgB;gBAChC,MAAMU,cAAc,CAAC,EAAEC,KAAK,EAA4B,GACpDA,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,QAAQ,OAAOF,MAAM,YAAY;gBAElEP,gBAAgB,CAAC,CAAC,UAAU,EAAEO,MAAM,YAAY,EAAE,CAAC,GAAGR,OACjD,MAAM,GACN,QAAQ,CAAC,eACT,UAAU,CAACS,aACX,MAAM,CAAC,CAACE;oBACL,MAAMC,SAAwD,CAAC;oBAC/D,KAAK,MAAMC,MAAML,MAAM,SAAS,CAC5BM,OAAO,MAAM,CAACF,QAAQC,GAAGF;oBAE7B,OAAOC;gBACX;YACR;YAEA,OAAO;gBACH,UAAUZ,OACL,MAAM,GACN,QAAQ,CAAC,iBACT,MAAM,CAAC,IAAMC;YACtB;QACJ;QAEAP,KAAK,MAAM,CAACqB,CAAAA;YACR,MAAMC,cAAc,CAACC;gBACjB,MAAMC,QAAuC;oBAACD,MAAM,GAAG,CAAC;iBAAQ;gBAChE,KAAK,MAAMT,SAAST,eAChBmB,MAAM,IAAI,CACND,MAAM,MAAM,CAAC,CAAC,UAAU,EAAET,MAAM,YAAY,EAAE,EAAEW,CAAAA,gBAC5CX,MAAM,SAAS,CAAC,OAAO,CAACK,CAAAA,KAAMA,GAAGM;gBAI7C,OAAOD;YACX;YAEA,OAAO;gBAACH,OAAO,MAAM,CAAC,YAAYC;aAAa;QACnD;IACJ;IAEA,UAAUN,KAAoB,EAAE;QAC5B,MAAMU,WAAW,AAA0B,YAA1B,OAAOV,MAAM,QAAQ,GAAgBA,MAAM,QAAQ,GAAG;QACvE,MAAMW,eAAeD,WAAWA,SAAS,IAAI,GAAG;QAChD,MAAME,WAAWF,WAAYA,SAAS,QAAQ,IAAI,CAAC,IAAK,CAAC;QAEzD,MAAMG,SAAkC;YACpC,MAAMF;QACV;QAEA,KAAK,MAAMd,KAAK,IAAI,CAAC,YAAY,CAC7B,IAAIA,EAAE,iBAAiB,EACnBgB,MAAM,CAAC,CAAC,UAAU,EAAEhB,EAAE,YAAY,EAAE,CAAC,GACjCA,EAAE,YAAY,KAAKc,eAAeC,WAAW,CAAC;QAI1D,OAAO;YAAE,UAAUC;QAAO;IAC9B;IAEA,YAAYC,QAA6B,EAAEd,KAAoB,EAAE;QAC7D,MAAMW,eAAeG,SAAS,QAAQ,EAAE,QAAQ;QAChD,MAAMC,cAAc,CAAC,UAAU,EAAEJ,cAAc;QAC/C,MAAMC,WAAWE,SAAS,QAAQ,EAAE,CAACC,YAAY,IAAI,CAAC;QAEtDf,MAAM,QAAQ,GAAG;YACb,MAAMW;YACNC;QACJ;IACJ;IAEQ,wBAAwBI,SAA8B,EAA2B;QACrF,MAAMC,SAAkC,EAAE;QAE1C,KAAK,MAAMP,YAAYM,UAAW;YAC9B,IAAI,CAACN,SAAS,iBAAiB,EAC3B;YAGJ,MAAMQ,YAAgD,EAAE;YACxD,MAAMC,YAAgD,EAAE;YAExD,MAAMC,UAAwC;gBAC1C,QAAQjB,CAAAA;oBACJe,UAAU,IAAI,CAACf;gBACnB;gBACA,QAAQA,CAAAA;oBACJgB,UAAU,IAAI,CAAChB;gBACnB;YACJ;YAEAO,SAAS,iBAAiB,CAACU;YAE3B,IAAIF,UAAU,MAAM,GAAG,GACnBD,OAAO,IAAI,CAAC;gBAAE,cAAcP,SAAS,YAAY;gBAAEQ;gBAAWC;YAAU;QAEhF;QAEA,OAAOF;IACX;AACJ;AAEO,MAAMI,kBAAkBC,oBAAoB,oBAAoB,CAAC;IACpE,gBAAgBpC;IAChB,cAAc;QAAC;YAACqC;YAAkB;gBAAE,UAAU;YAAK;SAAE;KAAC;AAC1D"}
|