@rippling/rippling-sdk 0.2.0-alpha.49 → 0.2.0-alpha.51
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/examples/manifest/existing-manifest-mutations/existing-manifest-mutations.ts +5 -0
- package/lib/manifest/custom-object-page-layout.d.mts +167 -48
- package/lib/manifest/custom-object-page-layout.d.mts.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.ts +167 -48
- package/lib/manifest/custom-object-page-layout.d.ts.map +1 -1
- package/lib/manifest/custom-object-page-layout.js +202 -88
- package/lib/manifest/custom-object-page-layout.js.map +1 -1
- package/lib/manifest/custom-object-page-layout.mjs +202 -88
- package/lib/manifest/custom-object-page-layout.mjs.map +1 -1
- package/lib/manifest/custom-object.d.mts +1 -1
- package/lib/manifest/custom-object.d.ts +1 -1
- package/lib/manifest/custom-object.js +1 -1
- package/lib/manifest/custom-object.mjs +1 -1
- package/lib/manifest/existing-manifest-context.d.mts +1 -0
- package/lib/manifest/existing-manifest-context.d.mts.map +1 -1
- package/lib/manifest/existing-manifest-context.d.ts +1 -0
- package/lib/manifest/existing-manifest-context.d.ts.map +1 -1
- package/lib/manifest/existing-manifest-context.js +7 -6
- package/lib/manifest/existing-manifest-context.js.map +1 -1
- package/lib/manifest/existing-manifest-context.mjs +7 -6
- package/lib/manifest/existing-manifest-context.mjs.map +1 -1
- package/lib/manifest/field.d.mts +3 -3
- package/lib/manifest/field.d.ts +3 -3
- package/lib/manifest/field.js +2 -2
- package/lib/manifest/field.mjs +2 -2
- package/lib/manifest/index.d.mts +1 -1
- package/lib/manifest/index.d.mts.map +1 -1
- package/lib/manifest/index.d.ts +1 -1
- package/lib/manifest/index.d.ts.map +1 -1
- package/lib/manifest/index.js.map +1 -1
- package/lib/manifest/index.mjs.map +1 -1
- package/lib/sdui/components.d.mts +100 -211
- package/lib/sdui/components.d.mts.map +1 -1
- package/lib/sdui/components.d.ts +100 -211
- package/lib/sdui/components.d.ts.map +1 -1
- package/lib/sdui/components.js +96 -182
- package/lib/sdui/components.js.map +1 -1
- package/lib/sdui/components.mjs +93 -178
- package/lib/sdui/components.mjs.map +1 -1
- package/lib/sdui/index.d.mts +12 -52
- package/lib/sdui/index.d.mts.map +1 -1
- package/lib/sdui/index.d.ts +12 -52
- package/lib/sdui/index.d.ts.map +1 -1
- package/lib/sdui/index.js +10 -50
- package/lib/sdui/index.js.map +1 -1
- package/lib/sdui/index.mjs +5 -25
- package/lib/sdui/index.mjs.map +1 -1
- package/lib/sdui/propTypes.d.mts +3156 -3515
- package/lib/sdui/propTypes.d.mts.map +1 -1
- package/lib/sdui/propTypes.d.ts +3156 -3515
- package/lib/sdui/propTypes.d.ts.map +1 -1
- package/lib/sdui/propTypes.js +1 -1
- package/lib/sdui/propTypes.mjs +1 -1
- package/package.json +1 -1
- package/resources/leave-balances.d.mts +10 -0
- package/resources/leave-balances.d.mts.map +1 -1
- package/resources/leave-balances.d.ts +10 -0
- package/resources/leave-balances.d.ts.map +1 -1
- package/src/lib/manifest/custom-object-page-layout.ts +497 -180
- package/src/lib/manifest/custom-object.ts +1 -1
- package/src/lib/manifest/existing-manifest-context.ts +11 -6
- package/src/lib/manifest/field.ts +3 -3
- package/src/lib/manifest/index.ts +27 -0
- package/src/lib/sdui/components.ts +181 -332
- package/src/lib/sdui/index.ts +13 -93
- package/src/lib/sdui/propTypes.ts +3509 -3892
- package/src/resources/leave-balances.ts +12 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -17,32 +17,34 @@ function isFieldRef(value) {
|
|
|
17
17
|
const candidate = value;
|
|
18
18
|
return candidate != null && typeof candidate === 'object' && isField(candidate.field);
|
|
19
19
|
}
|
|
20
|
-
const
|
|
20
|
+
const LAYOUT_SECTION_KEY = Symbol('CustomObjectPageLayout.layoutSectionKey');
|
|
21
21
|
function isCustomObjectFieldSection(value) {
|
|
22
22
|
return value instanceof custom_object_field_section_1.CustomObjectFieldSection;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
function explicitLayoutSectionKey(section) {
|
|
25
|
+
const record = section;
|
|
26
|
+
const key = section.key ?? record['layout_section_key'] ?? record['layoutSectionKey'];
|
|
27
|
+
return typeof key === 'string' ? key : undefined;
|
|
28
|
+
}
|
|
29
|
+
function attachLayoutSectionKey(section, sectionKey) {
|
|
30
|
+
if (explicitLayoutSectionKey(section) == null)
|
|
31
|
+
section.key = sectionKey;
|
|
32
|
+
Object.defineProperty(section, LAYOUT_SECTION_KEY, {
|
|
33
|
+
value: sectionKey,
|
|
31
34
|
enumerable: false,
|
|
32
35
|
configurable: true,
|
|
33
36
|
});
|
|
34
37
|
return section;
|
|
35
38
|
}
|
|
36
39
|
function layoutSectionKey(section) {
|
|
37
|
-
return (section
|
|
38
|
-
section[
|
|
40
|
+
return (explicitLayoutSectionKey(section) ??
|
|
41
|
+
section[LAYOUT_SECTION_KEY]);
|
|
39
42
|
}
|
|
40
43
|
function layoutSectionMatches(section, sectionKey) {
|
|
41
44
|
return layoutSectionKey(section) === sectionKey;
|
|
42
45
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
return Object.prototype.hasOwnProperty.call(record, 'key') && record['key'] != null;
|
|
46
|
+
function isSerializedFieldsSection(section) {
|
|
47
|
+
return section.type === 'fields_section';
|
|
46
48
|
}
|
|
47
49
|
function assertSameObject(customObject, field, sectionKey) {
|
|
48
50
|
if (field.getCustomObjectApiName() !== customObject.getApiName()) {
|
|
@@ -77,10 +79,29 @@ function toSerializedSectionField(fieldRqlName, options = {}) {
|
|
|
77
79
|
normalized.hidden = options.hidden;
|
|
78
80
|
if (options.editable != null)
|
|
79
81
|
normalized.editable = options.editable;
|
|
82
|
+
if (options.readOnly != null)
|
|
83
|
+
normalized.readOnly = options.readOnly;
|
|
84
|
+
if (options.defaultValue != null)
|
|
85
|
+
normalized.defaultValue = options.defaultValue;
|
|
86
|
+
if (options.height != null)
|
|
87
|
+
normalized.height = options.height;
|
|
88
|
+
if (options.canBeDeleted != null)
|
|
89
|
+
normalized.canBeDeleted = options.canBeDeleted;
|
|
80
90
|
if (options.movementOption != null)
|
|
81
91
|
normalized.movementOption = options.movementOption;
|
|
82
92
|
return normalized;
|
|
83
93
|
}
|
|
94
|
+
function copySectionOptions(target, input) {
|
|
95
|
+
if (input.canBeDeleted != null)
|
|
96
|
+
target.canBeDeleted = input.canBeDeleted;
|
|
97
|
+
if (input.canBeRenamed != null)
|
|
98
|
+
target.canBeRenamed = input.canBeRenamed;
|
|
99
|
+
if (input.movementOption != null)
|
|
100
|
+
target.movementOption = input.movementOption;
|
|
101
|
+
if (input.hideName != null)
|
|
102
|
+
target.hideName = input.hideName;
|
|
103
|
+
return target;
|
|
104
|
+
}
|
|
84
105
|
function normalizeSectionField(customObject, section, sectionKey, entry) {
|
|
85
106
|
if (isField(entry)) {
|
|
86
107
|
assertSameObject(customObject, entry, sectionKey);
|
|
@@ -97,26 +118,28 @@ function normalizeSectionField(customObject, section, sectionKey, entry) {
|
|
|
97
118
|
}
|
|
98
119
|
function normalizeFieldsSection(customObject, input) {
|
|
99
120
|
assertSectionBelongsTo(customObject, input.section);
|
|
100
|
-
const
|
|
101
|
-
if (inputFieldsSectionHasKey(input)) {
|
|
102
|
-
throw new Error('CustomObjectPageLayout fields_section key is not supported. Omit key.');
|
|
103
|
-
}
|
|
121
|
+
const sectionKey = input.key ?? input.section.getSectionId();
|
|
104
122
|
const name = input.name ?? input.section.getName();
|
|
105
|
-
const normalized = {
|
|
123
|
+
const normalized = copySectionOptions({
|
|
106
124
|
name,
|
|
107
125
|
type: 'fields_section',
|
|
108
|
-
fields: input.fields.map((field) => normalizeSectionField(customObject, input.section,
|
|
109
|
-
};
|
|
126
|
+
fields: input.fields.map((field) => normalizeSectionField(customObject, input.section, sectionKey, field)),
|
|
127
|
+
}, input);
|
|
110
128
|
if (input.layout != null)
|
|
111
129
|
normalized.layout = input.layout;
|
|
112
|
-
return
|
|
130
|
+
return attachLayoutSectionKey(normalized, sectionKey);
|
|
131
|
+
}
|
|
132
|
+
function normalizeSection(customObject, section) {
|
|
133
|
+
if (section.type === 'fields_section')
|
|
134
|
+
return normalizeFieldsSection(customObject, section);
|
|
135
|
+
return { ...section };
|
|
113
136
|
}
|
|
114
137
|
function normalizeTab(customObject, tab) {
|
|
115
138
|
if (tab.type === 'custom_tab')
|
|
116
139
|
return tab;
|
|
117
140
|
return {
|
|
118
141
|
...tab,
|
|
119
|
-
sections: tab.sections.map((section) =>
|
|
142
|
+
sections: tab.sections.map((section) => normalizeSection(customObject, section)),
|
|
120
143
|
};
|
|
121
144
|
}
|
|
122
145
|
function normalizeSystemSectionEdit(customObject, tabKey, sectionKey, edit) {
|
|
@@ -131,7 +154,7 @@ function normalizeSystemTabEdit(customObject, tabKey, edit) {
|
|
|
131
154
|
const { newSections: _newSections, systemSectionEdits: _systemSectionEdits, ...rest } = edit;
|
|
132
155
|
const normalized = { ...rest };
|
|
133
156
|
if (edit.newSections != null) {
|
|
134
|
-
normalized.newSections = edit.newSections.map((section) =>
|
|
157
|
+
normalized.newSections = edit.newSections.map((section) => normalizeSection(customObject, section));
|
|
135
158
|
}
|
|
136
159
|
if (edit.systemSectionEdits != null) {
|
|
137
160
|
const systemSectionEdits = {};
|
|
@@ -189,6 +212,18 @@ function normalizeHeaderEdits(headerEdits) {
|
|
|
189
212
|
for (const [index, field] of (headerEdits.newFields ?? []).entries()) {
|
|
190
213
|
assertKnownKeys(field, NEW_HEADER_FIELD_KEYS, `CustomObjectPageLayout headerEdits.newFields[${index}]`, 'Use { rqlName, key } entries, or call addHeaderField(field).');
|
|
191
214
|
}
|
|
215
|
+
if (headerEdits.newTitleField === '') {
|
|
216
|
+
throw new Error('CustomObjectPageLayout headerEdits.newTitleField cannot be empty. Use titleFieldDeleted.');
|
|
217
|
+
}
|
|
218
|
+
if (headerEdits.newDescriptionField === '') {
|
|
219
|
+
throw new Error('CustomObjectPageLayout headerEdits.newDescriptionField cannot be empty. Use descriptionFieldDeleted.');
|
|
220
|
+
}
|
|
221
|
+
if (headerEdits.newTitleField != null && headerEdits.titleFieldDeleted === true) {
|
|
222
|
+
throw new Error('CustomObjectPageLayout headerEdits cannot both set newTitleField and titleFieldDeleted.');
|
|
223
|
+
}
|
|
224
|
+
if (headerEdits.newDescriptionField != null && headerEdits.descriptionFieldDeleted === true) {
|
|
225
|
+
throw new Error('CustomObjectPageLayout headerEdits cannot both set newDescriptionField and descriptionFieldDeleted.');
|
|
226
|
+
}
|
|
192
227
|
if (headerEdits.headerFieldsOrder == null)
|
|
193
228
|
return headerEdits;
|
|
194
229
|
return {
|
|
@@ -251,52 +286,90 @@ function fieldRqlNameOf(entry) {
|
|
|
251
286
|
if (entry == null || typeof entry !== 'object')
|
|
252
287
|
return undefined;
|
|
253
288
|
const record = entry;
|
|
254
|
-
const fieldRqlName = record['fieldRqlName'] ?? record['field_rql_name'];
|
|
289
|
+
const fieldRqlName = record['fieldRqlName'] ?? record['field_rql_name'] ?? record['apiName'] ?? record['api_name'];
|
|
255
290
|
return typeof fieldRqlName === 'string' ? fieldRqlName : undefined;
|
|
256
291
|
}
|
|
257
|
-
function
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
292
|
+
function addFieldSectionLayoutSection(index, fieldSectionId, entry) {
|
|
293
|
+
const entries = index.get(fieldSectionId) ?? [];
|
|
294
|
+
if (!entries.some((existing) => existing.tabKey === entry.tabKey && existing.sectionKey === entry.sectionKey)) {
|
|
295
|
+
entries.push(entry);
|
|
296
|
+
}
|
|
297
|
+
index.set(fieldSectionId, entries);
|
|
263
298
|
}
|
|
264
|
-
function
|
|
265
|
-
|
|
299
|
+
function indexFieldsSectionInput(index, tabKey, section) {
|
|
300
|
+
addFieldSectionLayoutSection(index, section.section.getSectionId(), {
|
|
301
|
+
tabKey,
|
|
302
|
+
sectionKey: section.key ?? section.section.getSectionId(),
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
function indexPageLayoutSectionInput(index, tabKey, section) {
|
|
306
|
+
if (section.type === 'fields_section')
|
|
307
|
+
indexFieldsSectionInput(index, tabKey, section);
|
|
308
|
+
}
|
|
309
|
+
function buildFieldSectionLayoutIndexFromProps(tabEdits) {
|
|
310
|
+
const index = new Map();
|
|
311
|
+
if (tabEdits == null)
|
|
312
|
+
return index;
|
|
313
|
+
for (const tab of tabEdits.newTabs ?? []) {
|
|
314
|
+
if (tab.type !== 'tab_with_sections')
|
|
315
|
+
continue;
|
|
316
|
+
for (const section of tab.sections)
|
|
317
|
+
indexPageLayoutSectionInput(index, tab.key, section);
|
|
318
|
+
}
|
|
319
|
+
for (const [tabKey, tabEdit] of Object.entries(tabEdits.systemTabEdits ?? {})) {
|
|
320
|
+
for (const section of tabEdit.newSections ?? []) {
|
|
321
|
+
indexPageLayoutSectionInput(index, tabKey, section);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return index;
|
|
325
|
+
}
|
|
326
|
+
function indexLoadedFieldsSection(index, tabKey, section, resolveFieldSectionId) {
|
|
327
|
+
const sectionKey = layoutSectionKey(section);
|
|
328
|
+
if (sectionKey == null || resolveFieldSectionId == null)
|
|
329
|
+
return;
|
|
266
330
|
for (const field of section.fields ?? []) {
|
|
267
|
-
const
|
|
268
|
-
if (
|
|
269
|
-
sectionIds.add(explicitSectionId);
|
|
331
|
+
const fieldRqlName = fieldRqlNameOf(field);
|
|
332
|
+
if (fieldRqlName == null)
|
|
270
333
|
continue;
|
|
334
|
+
const fieldSectionId = resolveFieldSectionId(fieldRqlName);
|
|
335
|
+
if (fieldSectionId != null) {
|
|
336
|
+
addFieldSectionLayoutSection(index, fieldSectionId, { tabKey, sectionKey });
|
|
271
337
|
}
|
|
272
|
-
|
|
273
|
-
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function buildFieldSectionLayoutIndexFromLoadedTabEdits(tabEdits, resolveFieldSectionId) {
|
|
341
|
+
const index = new Map();
|
|
342
|
+
for (const tab of tabEdits.newTabs ?? []) {
|
|
343
|
+
if (!isTabWithSections(tab))
|
|
274
344
|
continue;
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
345
|
+
for (const section of tab.sections) {
|
|
346
|
+
if (isSerializedFieldsSection(section)) {
|
|
347
|
+
indexLoadedFieldsSection(index, tab.key, section, resolveFieldSectionId);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
278
350
|
}
|
|
279
|
-
|
|
351
|
+
for (const [tabKey, tabEdit] of Object.entries(tabEdits.systemTabEdits ?? {})) {
|
|
352
|
+
for (const section of tabEdit.newSections ?? []) {
|
|
353
|
+
if (isSerializedFieldsSection(section)) {
|
|
354
|
+
indexLoadedFieldsSection(index, tabKey, section, resolveFieldSectionId);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return index;
|
|
280
359
|
}
|
|
281
|
-
function annotateLoadedFieldsSection(section
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
if (explicitSectionId != null && inferredSectionId != null && explicitSectionId !== inferredSectionId) {
|
|
285
|
-
throw new Error(`CustomObjectPageLayout fields_section key "${explicitSectionId}" does not match ` +
|
|
286
|
-
`field section "${inferredSectionId}".`);
|
|
287
|
-
}
|
|
288
|
-
const sectionId = explicitSectionId ?? inferredSectionId;
|
|
289
|
-
return sectionId == null ? section : attachFieldSectionId(section, sectionId);
|
|
360
|
+
function annotateLoadedFieldsSection(section) {
|
|
361
|
+
const sectionKey = layoutSectionKey(section);
|
|
362
|
+
return sectionKey == null ? section : attachLayoutSectionKey(section, sectionKey);
|
|
290
363
|
}
|
|
291
|
-
function annotateLoadedTabEdits(tabEdits
|
|
364
|
+
function annotateLoadedTabEdits(tabEdits) {
|
|
292
365
|
for (const tab of tabEdits.newTabs ?? []) {
|
|
293
366
|
if (!isTabWithSections(tab))
|
|
294
367
|
continue;
|
|
295
|
-
tab.sections = tab.sections.map((section) => annotateLoadedFieldsSection(section
|
|
368
|
+
tab.sections = tab.sections.map((section) => isSerializedFieldsSection(section) ? annotateLoadedFieldsSection(section) : section);
|
|
296
369
|
}
|
|
297
370
|
for (const tabEdit of Object.values(tabEdits.systemTabEdits ?? {})) {
|
|
298
371
|
if (tabEdit.newSections != null) {
|
|
299
|
-
tabEdit.newSections = tabEdit.newSections.map((section) => annotateLoadedFieldsSection(section
|
|
372
|
+
tabEdit.newSections = tabEdit.newSections.map((section) => isSerializedFieldsSection(section) ? annotateLoadedFieldsSection(section) : section);
|
|
300
373
|
}
|
|
301
374
|
}
|
|
302
375
|
return tabEdits;
|
|
@@ -412,6 +485,7 @@ class CustomObjectPageLayout {
|
|
|
412
485
|
this._customObjectApiName = customObject.getApiName();
|
|
413
486
|
this._name = props.name;
|
|
414
487
|
this._tabEdits = normalizeTabEdits(customObject, props.tabEdits ?? {});
|
|
488
|
+
this._fieldSectionLayoutSections = buildFieldSectionLayoutIndexFromProps(props.tabEdits);
|
|
415
489
|
this._headerEdits = normalizeHeaderEdits(props.headerEdits ?? {});
|
|
416
490
|
this._visibilityConditions = props.visibilityConditions ?? {};
|
|
417
491
|
this._blueprintKey = props.blueprintKey;
|
|
@@ -430,15 +504,17 @@ class CustomObjectPageLayout {
|
|
|
430
504
|
/** @internal Hydrates a page layout from existing manifest wire JSON. */
|
|
431
505
|
static _fromExistingComponent(customObject, component, resolveFieldSectionId) {
|
|
432
506
|
const layout = Object.create(CustomObjectPageLayout.prototype);
|
|
507
|
+
const tabEdits = annotateLoadedTabEdits(cloneJson(component['tab_edits'] ?? {}));
|
|
433
508
|
Object.assign(layout, {
|
|
434
509
|
_layoutId: (0, _existing_component_fields_1.requireStringComponentField)(component, 'layout_id', CustomObjectPageLayout.componentType),
|
|
435
510
|
_apiName: (0, _existing_component_fields_1.requireStringComponentField)(component, 'api_name', CustomObjectPageLayout.componentType),
|
|
436
511
|
_customObjectApiName: (0, _existing_component_fields_1.requireStringComponentField)(component, 'object_rql_name', CustomObjectPageLayout.componentType),
|
|
437
512
|
_name: (0, _existing_component_fields_1.requireStringComponentField)(component, 'name', CustomObjectPageLayout.componentType),
|
|
438
|
-
_tabEdits:
|
|
513
|
+
_tabEdits: tabEdits,
|
|
439
514
|
_headerEdits: cloneJson(component['header_edits'] ?? {}),
|
|
440
515
|
_visibilityConditions: cloneJson(component['visibility_conditions'] ?? {}),
|
|
441
516
|
_blueprintKey: component['blueprint_key'],
|
|
517
|
+
_fieldSectionLayoutSections: buildFieldSectionLayoutIndexFromLoadedTabEdits(tabEdits, resolveFieldSectionId),
|
|
442
518
|
});
|
|
443
519
|
customObject._register(layout);
|
|
444
520
|
return layout;
|
|
@@ -474,8 +550,8 @@ class CustomObjectPageLayout {
|
|
|
474
550
|
* Adds multiple fields to an existing layout section.
|
|
475
551
|
*
|
|
476
552
|
* Fields are inserted in the order provided. For custom layout sections,
|
|
477
|
-
* pass `
|
|
478
|
-
*
|
|
553
|
+
* pass `section` to choose the typed field section. Use `sectionKey` only
|
|
554
|
+
* when a field section maps to multiple layout sections.
|
|
479
555
|
*/
|
|
480
556
|
addFields(fields, options) {
|
|
481
557
|
if (fields.length === 0)
|
|
@@ -489,14 +565,19 @@ class CustomObjectPageLayout {
|
|
|
489
565
|
return this.ensureSystemSectionFieldContainer(options.tabKey, options.sectionKey);
|
|
490
566
|
})()
|
|
491
567
|
: (() => {
|
|
492
|
-
assertOptionAbsent(options, 'sectionKey', 'CustomObjectPageLayout addField sectionKey is only supported with systemSection: true. ' +
|
|
493
|
-
'Pass section: CustomObjectFieldSection for custom layout sections.');
|
|
494
568
|
assertOptionAbsent(options, 'fieldSection', 'CustomObjectPageLayout addField fieldSection is no longer supported. ' +
|
|
495
569
|
'Pass section: CustomObjectFieldSection instead.');
|
|
496
|
-
const section =
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
570
|
+
const section = options.section == null ?
|
|
571
|
+
undefined
|
|
572
|
+
: requireFieldSectionOption(options.section, 'CustomObjectPageLayout addField section');
|
|
573
|
+
if (section != null) {
|
|
574
|
+
this.assertFieldSectionBelongsToLayout(section);
|
|
575
|
+
fieldSectionForMutation = section;
|
|
576
|
+
}
|
|
577
|
+
const sectionKey = options.sectionKey ??
|
|
578
|
+
(section == null ? undefined : this.layoutSectionKeyForFieldSection(options.tabKey, section)) ??
|
|
579
|
+
section?.getSectionId();
|
|
580
|
+
return this.requireOneFieldContainer(options.tabKey, sectionKey, section);
|
|
500
581
|
})();
|
|
501
582
|
const entries = fields.map((field) => this.serializeFieldForMutation(field, container.sectionKey ?? container.label, options, fieldSectionForMutation));
|
|
502
583
|
if (options.allowDuplicate !== true) {
|
|
@@ -530,12 +611,12 @@ class CustomObjectPageLayout {
|
|
|
530
611
|
sectionKey = options.sectionKey;
|
|
531
612
|
}
|
|
532
613
|
else {
|
|
533
|
-
|
|
534
|
-
'Pass section: CustomObjectFieldSection for custom layout sections.');
|
|
614
|
+
sectionKey = options.sectionKey;
|
|
535
615
|
if (options.section != null) {
|
|
536
616
|
const section = requireFieldSectionOption(options.section, 'CustomObjectPageLayout removeField section');
|
|
537
617
|
this.assertFieldSectionBelongsToLayout(section);
|
|
538
|
-
sectionKey =
|
|
618
|
+
sectionKey ?? (sectionKey = this.layoutSectionKeyForFieldSection(options.tabKey, section));
|
|
619
|
+
sectionKey ?? (sectionKey = section.getSectionId());
|
|
539
620
|
}
|
|
540
621
|
}
|
|
541
622
|
const containers = this.findFieldContainers({
|
|
@@ -593,6 +674,9 @@ class CustomObjectPageLayout {
|
|
|
593
674
|
const sectionsOrder = this.ensureSystemSectionsOrder(tabEdit);
|
|
594
675
|
insertAt(sections, normalized, options.position);
|
|
595
676
|
insertUniqueAt(sectionsOrder, layoutSectionKey(normalized), options.position);
|
|
677
|
+
if (section.type === 'fields_section') {
|
|
678
|
+
this.rememberFieldSectionLayoutSection(section.section, options.tabKey, layoutSectionKey(normalized));
|
|
679
|
+
}
|
|
596
680
|
return this;
|
|
597
681
|
}
|
|
598
682
|
const tab = this.findNewTabWithSections(options.tabKey);
|
|
@@ -602,6 +686,9 @@ class CustomObjectPageLayout {
|
|
|
602
686
|
}
|
|
603
687
|
this.assertSectionKeyAvailable(tab.sections, layoutSectionKey(normalized), options.tabKey, options.allowDuplicate);
|
|
604
688
|
insertAt(tab.sections, normalized, options.position);
|
|
689
|
+
if (section.type === 'fields_section') {
|
|
690
|
+
this.rememberFieldSectionLayoutSection(section.section, tab.key, layoutSectionKey(normalized));
|
|
691
|
+
}
|
|
605
692
|
return this;
|
|
606
693
|
}
|
|
607
694
|
removeSection(sectionOrKey, options = {}) {
|
|
@@ -618,9 +705,15 @@ class CustomObjectPageLayout {
|
|
|
618
705
|
this.removeSectionVisibility(sectionOrKey);
|
|
619
706
|
return this;
|
|
620
707
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
708
|
+
let sectionKey;
|
|
709
|
+
if (typeof sectionOrKey === 'string') {
|
|
710
|
+
sectionKey = sectionOrKey;
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
const section = requireFieldSectionOption(sectionOrKey, 'CustomObjectPageLayout removeSection section');
|
|
714
|
+
this.assertFieldSectionBelongsToLayout(section);
|
|
715
|
+
sectionKey = this.layoutSectionKeyForFieldSection(options.tabKey, section) ?? section.getSectionId();
|
|
716
|
+
}
|
|
624
717
|
const matches = [];
|
|
625
718
|
for (const tab of this._tabEdits.newTabs ?? []) {
|
|
626
719
|
if (!isTabWithSections(tab))
|
|
@@ -628,7 +721,7 @@ class CustomObjectPageLayout {
|
|
|
628
721
|
if (options.tabKey != null && tab.key !== options.tabKey)
|
|
629
722
|
continue;
|
|
630
723
|
tab.sections.forEach((section, index) => {
|
|
631
|
-
if (layoutSectionMatches(section, sectionKey))
|
|
724
|
+
if (isSerializedFieldsSection(section) && layoutSectionMatches(section, sectionKey))
|
|
632
725
|
matches.push({ sections: tab.sections, section, index, tabKey: tab.key });
|
|
633
726
|
});
|
|
634
727
|
}
|
|
@@ -636,7 +729,7 @@ class CustomObjectPageLayout {
|
|
|
636
729
|
if (options.tabKey != null && tabKey !== options.tabKey)
|
|
637
730
|
continue;
|
|
638
731
|
(tabEdit.newSections ?? []).forEach((section, index) => {
|
|
639
|
-
if (layoutSectionMatches(section, sectionKey))
|
|
732
|
+
if (isSerializedFieldsSection(section) && layoutSectionMatches(section, sectionKey))
|
|
640
733
|
matches.push({ sections: tabEdit.newSections, section, index, tabEdit, tabKey });
|
|
641
734
|
});
|
|
642
735
|
}
|
|
@@ -674,6 +767,10 @@ class CustomObjectPageLayout {
|
|
|
674
767
|
const tabsOrder = this.ensureTabsOrder();
|
|
675
768
|
insertAt(newTabs, normalized, options.position);
|
|
676
769
|
insertUniqueAt(tabsOrder, normalized.key, options.position);
|
|
770
|
+
if (tab.type === 'tab_with_sections') {
|
|
771
|
+
for (const section of tab.sections)
|
|
772
|
+
indexPageLayoutSectionInput(this._fieldSectionLayoutSections, tab.key, section);
|
|
773
|
+
}
|
|
677
774
|
return this;
|
|
678
775
|
}
|
|
679
776
|
/**
|
|
@@ -732,13 +829,11 @@ class CustomObjectPageLayout {
|
|
|
732
829
|
this.removeHeaderOrderFieldIfUnused(removedField);
|
|
733
830
|
return this;
|
|
734
831
|
}
|
|
735
|
-
/** Sets the record title field in `header_edits`. */
|
|
736
832
|
setTitleField(field) {
|
|
737
833
|
const previousTitleField = this._headerEdits.newTitleField;
|
|
738
834
|
const nextTitleField = this.headerFieldApiName(field);
|
|
739
835
|
this._headerEdits.newTitleField = nextTitleField;
|
|
740
|
-
|
|
741
|
-
this._headerEdits.titleFieldDeleted = false;
|
|
836
|
+
this._headerEdits.titleFieldDeleted = false;
|
|
742
837
|
insertUniqueAt(this.ensureHeaderFieldsOrder(), nextTitleField, 'end');
|
|
743
838
|
this.removeHeaderOrderFieldIfUnused(previousTitleField);
|
|
744
839
|
return this;
|
|
@@ -751,13 +846,11 @@ class CustomObjectPageLayout {
|
|
|
751
846
|
this.removeHeaderOrderFieldIfUnused(previousTitleField);
|
|
752
847
|
return this;
|
|
753
848
|
}
|
|
754
|
-
/** Sets the record description field in `header_edits`. */
|
|
755
849
|
setDescriptionField(field) {
|
|
756
850
|
const previousDescriptionField = this._headerEdits.newDescriptionField;
|
|
757
851
|
const nextDescriptionField = this.headerFieldApiName(field);
|
|
758
852
|
this._headerEdits.newDescriptionField = nextDescriptionField;
|
|
759
|
-
|
|
760
|
-
this._headerEdits.descriptionFieldDeleted = false;
|
|
853
|
+
this._headerEdits.descriptionFieldDeleted = false;
|
|
761
854
|
insertUniqueAt(this.ensureHeaderFieldsOrder(), nextDescriptionField, 'end');
|
|
762
855
|
this.removeHeaderOrderFieldIfUnused(previousDescriptionField);
|
|
763
856
|
return this;
|
|
@@ -833,20 +926,19 @@ class CustomObjectPageLayout {
|
|
|
833
926
|
'pass a Field instance or { field }.');
|
|
834
927
|
}
|
|
835
928
|
normalizeSectionForMutation(input) {
|
|
929
|
+
if (input.type !== 'fields_section')
|
|
930
|
+
return { ...input };
|
|
836
931
|
this.assertFieldSectionBelongsToLayout(input.section);
|
|
837
|
-
const
|
|
838
|
-
if (inputFieldsSectionHasKey(input)) {
|
|
839
|
-
throw new Error('CustomObjectPageLayout fields_section key is not supported. Omit key.');
|
|
840
|
-
}
|
|
932
|
+
const sectionKey = input.key ?? input.section.getSectionId();
|
|
841
933
|
const name = input.name ?? input.section.getName();
|
|
842
|
-
const normalized = {
|
|
934
|
+
const normalized = copySectionOptions({
|
|
843
935
|
name,
|
|
844
936
|
type: 'fields_section',
|
|
845
|
-
fields: input.fields.map((field) => this.normalizeSectionFieldForMutation(input.section,
|
|
846
|
-
};
|
|
937
|
+
fields: input.fields.map((field) => this.normalizeSectionFieldForMutation(input.section, sectionKey, field)),
|
|
938
|
+
}, input);
|
|
847
939
|
if (input.layout != null)
|
|
848
940
|
normalized.layout = input.layout;
|
|
849
|
-
return
|
|
941
|
+
return attachLayoutSectionKey(normalized, sectionKey);
|
|
850
942
|
}
|
|
851
943
|
normalizeTabForMutation(tab) {
|
|
852
944
|
if (tab.type === 'custom_tab')
|
|
@@ -888,6 +980,26 @@ class CustomObjectPageLayout {
|
|
|
888
980
|
`"${section.getModelApiName()}", but the layout belongs to "${this._customObjectApiName}".`);
|
|
889
981
|
}
|
|
890
982
|
}
|
|
983
|
+
rememberFieldSectionLayoutSection(section, tabKey, sectionKey) {
|
|
984
|
+
if (sectionKey == null)
|
|
985
|
+
return;
|
|
986
|
+
addFieldSectionLayoutSection(this._fieldSectionLayoutSections, section.getSectionId(), {
|
|
987
|
+
tabKey,
|
|
988
|
+
sectionKey,
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
layoutSectionKeyForFieldSection(tabKey, section) {
|
|
992
|
+
const entries = this._fieldSectionLayoutSections.get(section.getSectionId()) ?? [];
|
|
993
|
+
const matches = tabKey == null ? entries : entries.filter((entry) => entry.tabKey === tabKey);
|
|
994
|
+
const sectionKeys = [...new Set(matches.map((entry) => entry.sectionKey))];
|
|
995
|
+
if (sectionKeys.length === 0)
|
|
996
|
+
return undefined;
|
|
997
|
+
if (sectionKeys.length === 1)
|
|
998
|
+
return sectionKeys[0];
|
|
999
|
+
const scope = tabKey == null ? '' : ` in tab "${tabKey}"`;
|
|
1000
|
+
throw new Error(`CustomObjectPageLayout field section "${section.getSectionId()}" maps to multiple layout sections${scope}: ` +
|
|
1001
|
+
`${sectionKeys.join(', ')}. Pass sectionKey to choose one.`);
|
|
1002
|
+
}
|
|
891
1003
|
requireOneFieldContainer(tabKey, sectionKey, fallbackFieldSection) {
|
|
892
1004
|
const containers = this.findFieldContainers({
|
|
893
1005
|
tabKey,
|
|
@@ -907,8 +1019,8 @@ class CustomObjectPageLayout {
|
|
|
907
1019
|
`"${fallbackFieldSection.getModelApiName()}", but the layout belongs to "${this._customObjectApiName}".`);
|
|
908
1020
|
}
|
|
909
1021
|
const container = unkeyedContainers[0];
|
|
910
|
-
|
|
911
|
-
container.sectionKey =
|
|
1022
|
+
attachLayoutSectionKey(container.section, sectionKey);
|
|
1023
|
+
container.sectionKey = sectionKey;
|
|
912
1024
|
container.label = `${container.tabKey}.${container.sectionKey}`;
|
|
913
1025
|
return container;
|
|
914
1026
|
}
|
|
@@ -935,6 +1047,8 @@ class CustomObjectPageLayout {
|
|
|
935
1047
|
if (filter.tabKey != null && tab.key !== filter.tabKey)
|
|
936
1048
|
continue;
|
|
937
1049
|
for (const [index, section] of tab.sections.entries()) {
|
|
1050
|
+
if (!isSerializedFieldsSection(section))
|
|
1051
|
+
continue;
|
|
938
1052
|
const sectionKey = layoutSectionKey(section);
|
|
939
1053
|
if (filter.sectionKey != null && !layoutSectionMatches(section, filter.sectionKey))
|
|
940
1054
|
continue;
|
|
@@ -952,6 +1066,8 @@ class CustomObjectPageLayout {
|
|
|
952
1066
|
if (filter.tabKey != null && tabKey !== filter.tabKey)
|
|
953
1067
|
continue;
|
|
954
1068
|
for (const [index, section] of (tabEdit.newSections ?? []).entries()) {
|
|
1069
|
+
if (!isSerializedFieldsSection(section))
|
|
1070
|
+
continue;
|
|
955
1071
|
const sectionKey = layoutSectionKey(section);
|
|
956
1072
|
if (filter.sectionKey != null && !layoutSectionMatches(section, filter.sectionKey))
|
|
957
1073
|
continue;
|
|
@@ -1060,8 +1176,6 @@ class CustomObjectPageLayout {
|
|
|
1060
1176
|
return normalized;
|
|
1061
1177
|
}
|
|
1062
1178
|
headerFieldApiName(field) {
|
|
1063
|
-
if (field == null)
|
|
1064
|
-
return null;
|
|
1065
1179
|
if (typeof field === 'string')
|
|
1066
1180
|
return field;
|
|
1067
1181
|
this.assertFieldBelongsToLayout(field);
|