@rippling/rippling-sdk 0.2.0-alpha.49 → 0.2.0-alpha.50
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/lib/manifest/custom-object-page-layout.d.mts +148 -34
- package/lib/manifest/custom-object-page-layout.d.mts.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.ts +148 -34
- package/lib/manifest/custom-object-page-layout.d.ts.map +1 -1
- package/lib/manifest/custom-object-page-layout.js +61 -18
- package/lib/manifest/custom-object-page-layout.js.map +1 -1
- package/lib/manifest/custom-object-page-layout.mjs +61 -18
- 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/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/src/lib/manifest/custom-object-page-layout.ts +294 -79
- package/src/lib/manifest/custom-object.ts +1 -1
- 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/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
|
@@ -11,6 +11,23 @@ export interface PageLayoutDeletionIdentifier {
|
|
|
11
11
|
objectRqlName: string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export type ObjectRqlName = string;
|
|
15
|
+
export type BlueprintKey = string;
|
|
16
|
+
export type LayoutApiName = string;
|
|
17
|
+
export type TabKey = string;
|
|
18
|
+
export type SectionKey = string;
|
|
19
|
+
export type HeaderFieldKey = string;
|
|
20
|
+
export type FieldRqlName = string;
|
|
21
|
+
export type RelatedObjectRqlName = string;
|
|
22
|
+
export type CanvasCompositionId = string;
|
|
23
|
+
export type HeaderButtonKey = string;
|
|
24
|
+
|
|
25
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
26
|
+
export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
27
|
+
export interface JsonObject {
|
|
28
|
+
[key: string]: JsonValue;
|
|
29
|
+
}
|
|
30
|
+
|
|
14
31
|
// ---------------------------------------------------------------------------
|
|
15
32
|
// header_edits — HeaderEditsDTO
|
|
16
33
|
// ---------------------------------------------------------------------------
|
|
@@ -18,7 +35,7 @@ export interface PageLayoutDeletionIdentifier {
|
|
|
18
35
|
/** Edit to a built-in (system) header field. */
|
|
19
36
|
export interface SystemHeaderFieldEdit {
|
|
20
37
|
/** Replace the system field's RQL field reference. Optional. */
|
|
21
|
-
newRqlField?:
|
|
38
|
+
newRqlField?: FieldRqlName;
|
|
22
39
|
/** Remove this system field from the header. Optional. */
|
|
23
40
|
deleted?: boolean;
|
|
24
41
|
}
|
|
@@ -31,9 +48,9 @@ export interface SystemHeaderFieldEdit {
|
|
|
31
48
|
*/
|
|
32
49
|
export interface NewHeaderField {
|
|
33
50
|
/** RQL field name to display. Required. */
|
|
34
|
-
rqlName:
|
|
51
|
+
rqlName: FieldRqlName;
|
|
35
52
|
/** Stable key for this field. Required. */
|
|
36
|
-
key:
|
|
53
|
+
key: HeaderFieldKey;
|
|
37
54
|
/** Whether the user can remove this field. Optional. */
|
|
38
55
|
canBeDeleted?: boolean;
|
|
39
56
|
/** Whether the user can swap this field for another. Optional. */
|
|
@@ -53,48 +70,93 @@ export interface NewHeaderField {
|
|
|
53
70
|
*/
|
|
54
71
|
export interface HeaderEdits {
|
|
55
72
|
/** Replace the record title field (pass the field's api_name). Optional. */
|
|
56
|
-
newTitleField?:
|
|
73
|
+
newTitleField?: FieldRqlName;
|
|
57
74
|
/** Remove the title field from the header. Optional. */
|
|
58
75
|
titleFieldDeleted?: boolean;
|
|
59
76
|
/** Replace the record description field. Optional. */
|
|
60
|
-
newDescriptionField?:
|
|
77
|
+
newDescriptionField?: FieldRqlName;
|
|
61
78
|
/** Remove the description field from the header. Optional. */
|
|
62
79
|
descriptionFieldDeleted?: boolean;
|
|
63
80
|
/** Edits to built-in system header fields, keyed by system field key. Optional. */
|
|
64
|
-
systemFieldEdits?: Record<
|
|
81
|
+
systemFieldEdits?: Record<HeaderFieldKey, SystemHeaderFieldEdit>;
|
|
65
82
|
/** Additional custom fields to add to the header. Optional. */
|
|
66
83
|
newFields?: NewHeaderField[];
|
|
67
84
|
/** Ordered list of header field RQL names. Custom header keys are accepted and converted. Optional. */
|
|
68
|
-
headerFieldsOrder?:
|
|
85
|
+
headerFieldsOrder?: FieldRqlName[];
|
|
69
86
|
/** Action button keys to show in the header. Optional. */
|
|
70
|
-
buttons?:
|
|
87
|
+
buttons?: HeaderButtonKey[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface SerializedSystemHeaderFieldEdit extends Omit<SystemHeaderFieldEdit, 'newRqlField'> {
|
|
91
|
+
newRqlField?: FieldRqlName | null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface SerializedHeaderEdits
|
|
95
|
+
extends Omit<HeaderEdits, 'newTitleField' | 'newDescriptionField' | 'systemFieldEdits'> {
|
|
96
|
+
newTitleField?: FieldRqlName | null;
|
|
97
|
+
newDescriptionField?: FieldRqlName | null;
|
|
98
|
+
systemFieldEdits?: Record<HeaderFieldKey, SerializedSystemHeaderFieldEdit>;
|
|
71
99
|
}
|
|
72
100
|
|
|
73
101
|
// ---------------------------------------------------------------------------
|
|
74
102
|
// tab_edits — TabEditsDTO + section/tab DTOs
|
|
75
103
|
// ---------------------------------------------------------------------------
|
|
76
104
|
|
|
105
|
+
export type SectionFieldsLayout = 'one_column' | 'two_column' | 'three_column' | 'responsive';
|
|
106
|
+
export type TabLayout = 'vertical' | 'horizontal';
|
|
107
|
+
export type SectionMovementOption = 'static' | 'tab' | 'free';
|
|
108
|
+
export type FieldMovementOption = 'tab' | 'free';
|
|
109
|
+
export type CustomObjectCustomSectionComponentKey = 'attachments' | 'comments';
|
|
110
|
+
|
|
111
|
+
/** Default value wrapper used by `SectionField.defaultValue`. */
|
|
112
|
+
export interface SectionFieldDefaultValue {
|
|
113
|
+
value: JsonValue;
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
/** Options for one field entry inside a `fields_section`. */
|
|
78
117
|
export interface SectionFieldOptions {
|
|
79
118
|
/** Hide this field from view. Optional. */
|
|
80
119
|
hidden?: boolean;
|
|
81
120
|
/** Allow inline editing of this field. Optional. */
|
|
82
121
|
editable?: boolean;
|
|
122
|
+
/** Render this field read-only. Optional. */
|
|
123
|
+
readOnly?: boolean;
|
|
124
|
+
/** Default value metadata for the field. Optional. */
|
|
125
|
+
defaultValue?: SectionFieldDefaultValue;
|
|
126
|
+
/** Rich-text field height. Optional. */
|
|
127
|
+
height?: number;
|
|
128
|
+
/** Whether the layout manager can remove this field. Optional. */
|
|
129
|
+
canBeDeleted?: boolean;
|
|
83
130
|
/** Controls how the field can be moved in the UI. Optional. */
|
|
84
|
-
movementOption?:
|
|
131
|
+
movementOption?: FieldMovementOption;
|
|
85
132
|
}
|
|
86
133
|
|
|
87
134
|
/** A typed field entry inside a `fields_section`. */
|
|
88
|
-
export interface
|
|
135
|
+
export interface SectionField extends SectionFieldOptions {
|
|
89
136
|
/** Field to display. Required. */
|
|
90
137
|
field: Field;
|
|
91
138
|
}
|
|
92
139
|
|
|
140
|
+
/** @deprecated Use `SectionField` for object entries or `SectionFieldInput` for field arrays. */
|
|
141
|
+
export type SectionFieldRef = SectionField;
|
|
142
|
+
|
|
93
143
|
/** One field entry inside a `fields_section`. */
|
|
94
|
-
export type
|
|
144
|
+
export type SectionFieldInput = Field | SectionField;
|
|
145
|
+
|
|
146
|
+
/** Common edit controls for sections. */
|
|
147
|
+
export interface PageLayoutSectionOptions {
|
|
148
|
+
/** Whether the layout manager can delete this section. Optional. */
|
|
149
|
+
canBeDeleted?: boolean;
|
|
150
|
+
/** Whether the layout manager can rename this section. Optional. */
|
|
151
|
+
canBeRenamed?: boolean;
|
|
152
|
+
/** Controls how the section can be moved. Optional. */
|
|
153
|
+
movementOption?: SectionMovementOption;
|
|
154
|
+
/** Hide the section title. Optional. */
|
|
155
|
+
hideName?: boolean;
|
|
156
|
+
}
|
|
95
157
|
|
|
96
158
|
/** A standard field-grid section inside a tab. */
|
|
97
|
-
export interface FieldsSection {
|
|
159
|
+
export interface FieldsSection extends PageLayoutSectionOptions {
|
|
98
160
|
type: 'fields_section';
|
|
99
161
|
/** Field section metadata for the fields displayed in this layout section. Required. */
|
|
100
162
|
section: CustomObjectFieldSection;
|
|
@@ -103,24 +165,105 @@ export interface FieldsSection {
|
|
|
103
165
|
/** Display name of the layout section. Optional. Defaults to the field section name. */
|
|
104
166
|
name?: string;
|
|
105
167
|
/** Fields to display in this section. Required. */
|
|
106
|
-
fields:
|
|
168
|
+
fields: SectionFieldInput[];
|
|
107
169
|
/** Column layout for the fields. Optional. @default `'responsive'` (backend default). */
|
|
108
170
|
layout?: SectionFieldsLayout;
|
|
109
171
|
}
|
|
110
172
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
173
|
+
export interface RelatedObjectSection extends PageLayoutSectionOptions {
|
|
174
|
+
type: 'related_object_section';
|
|
175
|
+
/** Stable layout section key. Required. */
|
|
176
|
+
key: SectionKey;
|
|
177
|
+
/** Display name of the layout section. Required. */
|
|
178
|
+
name: string;
|
|
179
|
+
/** Related object whose records point back to this custom object. Required. */
|
|
180
|
+
relatedObjectRqlName: RelatedObjectRqlName;
|
|
181
|
+
/** Field on the related object that points back to this custom object. Required. */
|
|
182
|
+
relatedFieldRqlName: FieldRqlName;
|
|
183
|
+
/** Field RQL names to display for related records. Required. */
|
|
184
|
+
fields: FieldRqlName[];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface RelatedFieldSection extends PageLayoutSectionOptions {
|
|
188
|
+
type: 'related_field_section';
|
|
189
|
+
/** Stable layout section key. Required. */
|
|
190
|
+
key: SectionKey;
|
|
191
|
+
/** Display name of the layout section. Required. */
|
|
192
|
+
name: string;
|
|
193
|
+
/** Related object reached from this custom object. Required. */
|
|
194
|
+
relatedObjectRqlName: RelatedObjectRqlName;
|
|
195
|
+
/** Field on this custom object that points to the related object. Required. */
|
|
196
|
+
relatedFieldRqlName: FieldRqlName;
|
|
197
|
+
/** Field RQL names to display from the related object. Required. */
|
|
198
|
+
fields: FieldRqlName[];
|
|
199
|
+
/** Column layout for the fields. Optional. @default `'responsive'` (backend default). */
|
|
200
|
+
layout?: SectionFieldsLayout;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface CustomSection extends PageLayoutSectionOptions {
|
|
204
|
+
type: 'custom_section';
|
|
205
|
+
/** Stable layout section key. Required. */
|
|
206
|
+
key: SectionKey;
|
|
207
|
+
/** Display name of the layout section. Required. */
|
|
208
|
+
name: string;
|
|
209
|
+
/** Custom object section component key. Required. */
|
|
210
|
+
componentKey: CustomObjectCustomSectionComponentKey;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface ResizableLayoutPosition {
|
|
214
|
+
identifier: string;
|
|
215
|
+
width: number;
|
|
216
|
+
height: number;
|
|
217
|
+
minWidth?: number;
|
|
218
|
+
minHeight?: number;
|
|
219
|
+
maxWidth?: number;
|
|
220
|
+
maxHeight?: number;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface ReportsSectionItem {
|
|
224
|
+
key: string;
|
|
225
|
+
reportId: string;
|
|
226
|
+
position: ResizableLayoutPosition;
|
|
227
|
+
contextualFieldAttrName?: FieldRqlName;
|
|
228
|
+
visualizationType?: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface ReportsSection extends PageLayoutSectionOptions {
|
|
232
|
+
type: 'reports_section';
|
|
233
|
+
/** Stable layout section key. Required. */
|
|
234
|
+
key: SectionKey;
|
|
235
|
+
/** Display name of the layout section. Required. */
|
|
236
|
+
name: string;
|
|
237
|
+
/** Reports to display in this section. Required. */
|
|
238
|
+
reports: ReportsSectionItem[];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface CanvasSection extends PageLayoutSectionOptions {
|
|
242
|
+
type: 'canvas_section';
|
|
243
|
+
/** Stable layout section key. Required. */
|
|
244
|
+
key: SectionKey;
|
|
245
|
+
/** Display name of the layout section. Required. */
|
|
246
|
+
name: string;
|
|
247
|
+
/** Canvas composition to render. Required. */
|
|
248
|
+
canvasCompositionId: CanvasCompositionId;
|
|
249
|
+
/** Composition input name to field or state path mapping. Optional. */
|
|
250
|
+
inputMapping?: Record<string, string>;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** A section inside a page layout tab. */
|
|
254
|
+
export type PageLayoutSection =
|
|
255
|
+
| FieldsSection
|
|
256
|
+
| RelatedObjectSection
|
|
257
|
+
| RelatedFieldSection
|
|
258
|
+
| CustomSection
|
|
259
|
+
| ReportsSection
|
|
260
|
+
| CanvasSection;
|
|
118
261
|
|
|
119
262
|
/** A tab that contains one or more field-grid sections. */
|
|
120
263
|
export interface TabWithSections {
|
|
121
264
|
type: 'tab_with_sections';
|
|
122
265
|
/** Stable key for this tab. Required. */
|
|
123
|
-
key:
|
|
266
|
+
key: TabKey;
|
|
124
267
|
/** Display name of the tab. Required. */
|
|
125
268
|
name: string;
|
|
126
269
|
/** Sections inside this tab. Required. */
|
|
@@ -131,7 +274,7 @@ export interface TabWithSections {
|
|
|
131
274
|
export interface CustomTab {
|
|
132
275
|
type: 'custom_tab';
|
|
133
276
|
/** Stable key for this tab. Required. */
|
|
134
|
-
key:
|
|
277
|
+
key: TabKey;
|
|
135
278
|
/** Display name of the tab. Required. */
|
|
136
279
|
name: string;
|
|
137
280
|
/** Key of the custom component to render. Required. */
|
|
@@ -142,8 +285,6 @@ export interface CustomTab {
|
|
|
142
285
|
export type PageLayoutTab = TabWithSections | CustomTab;
|
|
143
286
|
|
|
144
287
|
/** Column layout for a `fields_section`. */
|
|
145
|
-
export type SectionFieldsLayout = 'one_column' | 'two_column' | 'three_column' | 'responsive';
|
|
146
|
-
|
|
147
288
|
/** Edits to a built-in section inside a system tab. */
|
|
148
289
|
export interface SystemSectionEdit {
|
|
149
290
|
/** Rename this section. Optional. */
|
|
@@ -153,7 +294,7 @@ export interface SystemSectionEdit {
|
|
|
153
294
|
/** Change the column layout. Optional. */
|
|
154
295
|
newLayout?: SectionFieldsLayout;
|
|
155
296
|
/** Add fields to this section. Optional. */
|
|
156
|
-
newFields?:
|
|
297
|
+
newFields?: SectionFieldInput[];
|
|
157
298
|
/** Hide the section name header. Optional. */
|
|
158
299
|
newHideName?: boolean;
|
|
159
300
|
}
|
|
@@ -167,9 +308,9 @@ export interface SystemTabEdit {
|
|
|
167
308
|
/** Add new sections to this tab. Optional. */
|
|
168
309
|
newSections?: PageLayoutSection[];
|
|
169
310
|
/** Edits to built-in sections inside this tab, keyed by section key. Optional. */
|
|
170
|
-
systemSectionEdits?: Record<
|
|
311
|
+
systemSectionEdits?: Record<SectionKey, SystemSectionEdit>;
|
|
171
312
|
/** Reorder sections by key. Optional. */
|
|
172
|
-
sectionsOrder?:
|
|
313
|
+
sectionsOrder?: SectionKey[];
|
|
173
314
|
}
|
|
174
315
|
|
|
175
316
|
/**
|
|
@@ -184,11 +325,11 @@ export interface TabEdits {
|
|
|
184
325
|
/** New tabs to add to this layout. Each must include a `type` discriminator. Optional. */
|
|
185
326
|
newTabs?: PageLayoutTab[];
|
|
186
327
|
/** Edits to existing system tabs, keyed by tab key. Optional. */
|
|
187
|
-
systemTabEdits?: Record<
|
|
328
|
+
systemTabEdits?: Record<TabKey, SystemTabEdit>;
|
|
188
329
|
/** Ordered list of tab `key` values (new + system). Optional. */
|
|
189
|
-
tabsOrder?:
|
|
330
|
+
tabsOrder?: TabKey[];
|
|
190
331
|
/** Tab strip orientation. Optional. */
|
|
191
|
-
newTabLayout?:
|
|
332
|
+
newTabLayout?: TabLayout;
|
|
192
333
|
}
|
|
193
334
|
|
|
194
335
|
// ---------------------------------------------------------------------------
|
|
@@ -205,7 +346,7 @@ export interface VisibilityCondition {
|
|
|
205
346
|
/** RQL formula that controls visibility. Required. */
|
|
206
347
|
rqlFormula: string;
|
|
207
348
|
/** Layered conditions tree (AST). Required. */
|
|
208
|
-
layeredConditionsTree:
|
|
349
|
+
layeredConditionsTree: JsonObject;
|
|
209
350
|
}
|
|
210
351
|
|
|
211
352
|
/**
|
|
@@ -215,9 +356,9 @@ export interface VisibilityCondition {
|
|
|
215
356
|
*/
|
|
216
357
|
export interface VisibilityConditions {
|
|
217
358
|
/** Per-section visibility conditions, keyed by section key. Optional. */
|
|
218
|
-
sections?: Record<
|
|
359
|
+
sections?: Record<SectionKey, VisibilityCondition>;
|
|
219
360
|
/** Per-tab visibility conditions, keyed by tab key. Optional. */
|
|
220
|
-
tabs?: Record<
|
|
361
|
+
tabs?: Record<TabKey, VisibilityCondition>;
|
|
221
362
|
}
|
|
222
363
|
|
|
223
364
|
// ---------------------------------------------------------------------------
|
|
@@ -455,7 +596,7 @@ interface SerializedSectionField extends SectionFieldOptions {
|
|
|
455
596
|
fieldRqlName: string;
|
|
456
597
|
}
|
|
457
598
|
|
|
458
|
-
interface SerializedFieldsSection {
|
|
599
|
+
interface SerializedFieldsSection extends PageLayoutSectionOptions {
|
|
459
600
|
key?: string;
|
|
460
601
|
type: 'fields_section';
|
|
461
602
|
name: string;
|
|
@@ -463,11 +604,19 @@ interface SerializedFieldsSection {
|
|
|
463
604
|
layout?: SectionFieldsLayout;
|
|
464
605
|
}
|
|
465
606
|
|
|
607
|
+
type SerializedPageLayoutSection =
|
|
608
|
+
| SerializedFieldsSection
|
|
609
|
+
| RelatedObjectSection
|
|
610
|
+
| RelatedFieldSection
|
|
611
|
+
| CustomSection
|
|
612
|
+
| ReportsSection
|
|
613
|
+
| CanvasSection;
|
|
614
|
+
|
|
466
615
|
interface SerializedTabWithSections {
|
|
467
616
|
type: 'tab_with_sections';
|
|
468
617
|
key: string;
|
|
469
618
|
name: string;
|
|
470
|
-
sections:
|
|
619
|
+
sections: SerializedPageLayoutSection[];
|
|
471
620
|
}
|
|
472
621
|
|
|
473
622
|
type SerializedPageLayoutTab = SerializedTabWithSections | CustomTab;
|
|
@@ -477,7 +626,7 @@ interface SerializedSystemSectionEdit extends Omit<SystemSectionEdit, 'newFields
|
|
|
477
626
|
}
|
|
478
627
|
|
|
479
628
|
interface SerializedSystemTabEdit extends Omit<SystemTabEdit, 'newSections' | 'systemSectionEdits'> {
|
|
480
|
-
newSections?:
|
|
629
|
+
newSections?: SerializedPageLayoutSection[];
|
|
481
630
|
systemSectionEdits?: Record<string, SerializedSystemSectionEdit>;
|
|
482
631
|
}
|
|
483
632
|
|
|
@@ -502,7 +651,7 @@ function isField(value: unknown): value is Field {
|
|
|
502
651
|
);
|
|
503
652
|
}
|
|
504
653
|
|
|
505
|
-
function isFieldRef(value:
|
|
654
|
+
function isFieldRef(value: SectionFieldInput): value is SectionField {
|
|
506
655
|
const candidate = value as { field?: unknown } | null;
|
|
507
656
|
return candidate != null && typeof candidate === 'object' && isField(candidate.field);
|
|
508
657
|
}
|
|
@@ -528,22 +677,26 @@ function attachFieldSectionId(section: SerializedFieldsSection, sectionId: strin
|
|
|
528
677
|
return section;
|
|
529
678
|
}
|
|
530
679
|
|
|
531
|
-
function layoutSectionKey(section:
|
|
680
|
+
function layoutSectionKey(section: { key?: string }): string | undefined {
|
|
532
681
|
return (
|
|
533
682
|
section.key ??
|
|
534
683
|
(section as unknown as Record<typeof FIELD_SECTION_ID, string | undefined>)[FIELD_SECTION_ID]
|
|
535
684
|
);
|
|
536
685
|
}
|
|
537
686
|
|
|
538
|
-
function layoutSectionMatches(section:
|
|
687
|
+
function layoutSectionMatches(section: { key?: string }, sectionKey: string): boolean {
|
|
539
688
|
return layoutSectionKey(section) === sectionKey;
|
|
540
689
|
}
|
|
541
690
|
|
|
542
|
-
function inputFieldsSectionHasKey(input:
|
|
691
|
+
function inputFieldsSectionHasKey(input: FieldsSection): boolean {
|
|
543
692
|
const record = input as unknown as Record<string, unknown>;
|
|
544
693
|
return Object.prototype.hasOwnProperty.call(record, 'key') && record['key'] != null;
|
|
545
694
|
}
|
|
546
695
|
|
|
696
|
+
function isSerializedFieldsSection(section: SerializedPageLayoutSection): section is SerializedFieldsSection {
|
|
697
|
+
return section.type === 'fields_section';
|
|
698
|
+
}
|
|
699
|
+
|
|
547
700
|
function assertSameObject(customObject: CustomObject, field: Field, sectionKey: string): void {
|
|
548
701
|
if (field.getCustomObjectApiName() !== customObject.getApiName()) {
|
|
549
702
|
throw new Error(
|
|
@@ -585,15 +738,30 @@ function toSerializedSectionField(
|
|
|
585
738
|
const normalized: SerializedSectionField = { fieldRqlName };
|
|
586
739
|
if (options.hidden != null) normalized.hidden = options.hidden;
|
|
587
740
|
if (options.editable != null) normalized.editable = options.editable;
|
|
741
|
+
if (options.readOnly != null) normalized.readOnly = options.readOnly;
|
|
742
|
+
if (options.defaultValue != null) normalized.defaultValue = options.defaultValue;
|
|
743
|
+
if (options.height != null) normalized.height = options.height;
|
|
744
|
+
if (options.canBeDeleted != null) normalized.canBeDeleted = options.canBeDeleted;
|
|
588
745
|
if (options.movementOption != null) normalized.movementOption = options.movementOption;
|
|
589
746
|
return normalized;
|
|
590
747
|
}
|
|
591
748
|
|
|
749
|
+
function copySectionOptions<T extends PageLayoutSectionOptions>(
|
|
750
|
+
target: T,
|
|
751
|
+
input: PageLayoutSectionOptions,
|
|
752
|
+
): T {
|
|
753
|
+
if (input.canBeDeleted != null) target.canBeDeleted = input.canBeDeleted;
|
|
754
|
+
if (input.canBeRenamed != null) target.canBeRenamed = input.canBeRenamed;
|
|
755
|
+
if (input.movementOption != null) target.movementOption = input.movementOption;
|
|
756
|
+
if (input.hideName != null) target.hideName = input.hideName;
|
|
757
|
+
return target;
|
|
758
|
+
}
|
|
759
|
+
|
|
592
760
|
function normalizeSectionField(
|
|
593
761
|
customObject: CustomObject,
|
|
594
762
|
section: CustomObjectFieldSection | string,
|
|
595
763
|
sectionKey: string,
|
|
596
|
-
entry:
|
|
764
|
+
entry: SectionFieldInput,
|
|
597
765
|
): SerializedSectionField {
|
|
598
766
|
if (isField(entry)) {
|
|
599
767
|
assertSameObject(customObject, entry, sectionKey);
|
|
@@ -613,30 +781,40 @@ function normalizeSectionField(
|
|
|
613
781
|
);
|
|
614
782
|
}
|
|
615
783
|
|
|
616
|
-
function normalizeFieldsSection(
|
|
617
|
-
customObject: CustomObject,
|
|
618
|
-
input: PageLayoutSection,
|
|
619
|
-
): SerializedFieldsSection {
|
|
784
|
+
function normalizeFieldsSection(customObject: CustomObject, input: FieldsSection): SerializedFieldsSection {
|
|
620
785
|
assertSectionBelongsTo(customObject, input.section);
|
|
621
786
|
const sectionId = input.section.getSectionId();
|
|
622
787
|
if (inputFieldsSectionHasKey(input)) {
|
|
623
788
|
throw new Error('CustomObjectPageLayout fields_section key is not supported. Omit key.');
|
|
624
789
|
}
|
|
625
790
|
const name = input.name ?? input.section.getName();
|
|
626
|
-
const normalized
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
791
|
+
const normalized = copySectionOptions<SerializedFieldsSection>(
|
|
792
|
+
{
|
|
793
|
+
name,
|
|
794
|
+
type: 'fields_section',
|
|
795
|
+
fields: input.fields.map((field) =>
|
|
796
|
+
normalizeSectionField(customObject, input.section, sectionId, field),
|
|
797
|
+
),
|
|
798
|
+
},
|
|
799
|
+
input,
|
|
800
|
+
);
|
|
631
801
|
if (input.layout != null) normalized.layout = input.layout;
|
|
632
802
|
return attachFieldSectionId(normalized, sectionId);
|
|
633
803
|
}
|
|
634
804
|
|
|
805
|
+
function normalizeSection(
|
|
806
|
+
customObject: CustomObject,
|
|
807
|
+
section: PageLayoutSection,
|
|
808
|
+
): SerializedPageLayoutSection {
|
|
809
|
+
if (section.type === 'fields_section') return normalizeFieldsSection(customObject, section);
|
|
810
|
+
return { ...section };
|
|
811
|
+
}
|
|
812
|
+
|
|
635
813
|
function normalizeTab(customObject: CustomObject, tab: PageLayoutTab): SerializedPageLayoutTab {
|
|
636
814
|
if (tab.type === 'custom_tab') return tab;
|
|
637
815
|
return {
|
|
638
816
|
...tab,
|
|
639
|
-
sections: tab.sections.map((section) =>
|
|
817
|
+
sections: tab.sections.map((section) => normalizeSection(customObject, section)),
|
|
640
818
|
};
|
|
641
819
|
}
|
|
642
820
|
|
|
@@ -664,7 +842,7 @@ function normalizeSystemTabEdit(
|
|
|
664
842
|
const { newSections: _newSections, systemSectionEdits: _systemSectionEdits, ...rest } = edit;
|
|
665
843
|
const normalized: SerializedSystemTabEdit = { ...rest };
|
|
666
844
|
if (edit.newSections != null) {
|
|
667
|
-
normalized.newSections = edit.newSections.map((section) =>
|
|
845
|
+
normalized.newSections = edit.newSections.map((section) => normalizeSection(customObject, section));
|
|
668
846
|
}
|
|
669
847
|
if (edit.systemSectionEdits != null) {
|
|
670
848
|
const systemSectionEdits: Record<string, SerializedSystemSectionEdit> = {};
|
|
@@ -730,7 +908,7 @@ function assertKnownKeys(
|
|
|
730
908
|
}
|
|
731
909
|
}
|
|
732
910
|
|
|
733
|
-
function normalizeHeaderEdits(headerEdits: HeaderEdits):
|
|
911
|
+
function normalizeHeaderEdits(headerEdits: HeaderEdits): SerializedHeaderEdits {
|
|
734
912
|
assertKnownKeys(
|
|
735
913
|
headerEdits as unknown as Record<string, unknown>,
|
|
736
914
|
HEADER_EDIT_KEYS,
|
|
@@ -756,6 +934,27 @@ function normalizeHeaderEdits(headerEdits: HeaderEdits): HeaderEdits {
|
|
|
756
934
|
);
|
|
757
935
|
}
|
|
758
936
|
|
|
937
|
+
if (headerEdits.newTitleField === '') {
|
|
938
|
+
throw new Error(
|
|
939
|
+
'CustomObjectPageLayout headerEdits.newTitleField cannot be empty. Use titleFieldDeleted.',
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
if (headerEdits.newDescriptionField === '') {
|
|
943
|
+
throw new Error(
|
|
944
|
+
'CustomObjectPageLayout headerEdits.newDescriptionField cannot be empty. Use descriptionFieldDeleted.',
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
if (headerEdits.newTitleField != null && headerEdits.titleFieldDeleted === true) {
|
|
948
|
+
throw new Error(
|
|
949
|
+
'CustomObjectPageLayout headerEdits cannot both set newTitleField and titleFieldDeleted.',
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
if (headerEdits.newDescriptionField != null && headerEdits.descriptionFieldDeleted === true) {
|
|
953
|
+
throw new Error(
|
|
954
|
+
'CustomObjectPageLayout headerEdits cannot both set newDescriptionField and descriptionFieldDeleted.',
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
|
|
759
958
|
if (headerEdits.headerFieldsOrder == null) return headerEdits;
|
|
760
959
|
return {
|
|
761
960
|
...headerEdits,
|
|
@@ -768,13 +967,13 @@ function addUniqueHeaderOrderField(order: string[], field: unknown): void {
|
|
|
768
967
|
if (!order.includes(field)) order.push(field);
|
|
769
968
|
}
|
|
770
969
|
|
|
771
|
-
function normalizeHeaderFieldsOrder(headerEdits:
|
|
970
|
+
function normalizeHeaderFieldsOrder(headerEdits: SerializedHeaderEdits): string[] {
|
|
772
971
|
const customFieldRqlByKey = new Map(
|
|
773
972
|
(headerEdits.newFields ?? []).map((field) => [field.key, field.rqlName]),
|
|
774
973
|
);
|
|
775
974
|
const systemFieldRqlByKey = new Map(
|
|
776
975
|
Object.entries(headerEdits.systemFieldEdits ?? {})
|
|
777
|
-
.filter((entry): entry is [string,
|
|
976
|
+
.filter((entry): entry is [string, SerializedSystemHeaderFieldEdit & { newRqlField: string }] => {
|
|
778
977
|
const [, edit] = entry;
|
|
779
978
|
return typeof edit.newRqlField === 'string' && edit.newRqlField.length > 0;
|
|
780
979
|
})
|
|
@@ -894,13 +1093,19 @@ function annotateLoadedTabEdits(
|
|
|
894
1093
|
): SerializedTabEdits {
|
|
895
1094
|
for (const tab of tabEdits.newTabs ?? []) {
|
|
896
1095
|
if (!isTabWithSections(tab)) continue;
|
|
897
|
-
tab.sections = tab.sections.map((section) =>
|
|
1096
|
+
tab.sections = tab.sections.map((section) =>
|
|
1097
|
+
isSerializedFieldsSection(section) ?
|
|
1098
|
+
annotateLoadedFieldsSection(section, resolveFieldSectionId)
|
|
1099
|
+
: section,
|
|
1100
|
+
);
|
|
898
1101
|
}
|
|
899
1102
|
|
|
900
1103
|
for (const tabEdit of Object.values(tabEdits.systemTabEdits ?? {})) {
|
|
901
1104
|
if (tabEdit.newSections != null) {
|
|
902
1105
|
tabEdit.newSections = tabEdit.newSections.map((section) =>
|
|
903
|
-
|
|
1106
|
+
isSerializedFieldsSection(section) ?
|
|
1107
|
+
annotateLoadedFieldsSection(section, resolveFieldSectionId)
|
|
1108
|
+
: section,
|
|
904
1109
|
);
|
|
905
1110
|
}
|
|
906
1111
|
}
|
|
@@ -1020,7 +1225,7 @@ export class CustomObjectPageLayout {
|
|
|
1020
1225
|
private readonly _customObjectApiName: string;
|
|
1021
1226
|
private readonly _name: string;
|
|
1022
1227
|
private readonly _tabEdits: SerializedTabEdits;
|
|
1023
|
-
private readonly _headerEdits:
|
|
1228
|
+
private readonly _headerEdits: SerializedHeaderEdits;
|
|
1024
1229
|
private readonly _visibilityConditions: VisibilityConditions;
|
|
1025
1230
|
private readonly _blueprintKey: string | undefined;
|
|
1026
1231
|
|
|
@@ -1280,7 +1485,7 @@ export class CustomObjectPageLayout {
|
|
|
1280
1485
|
const normalized = this.normalizeSectionForMutation(section);
|
|
1281
1486
|
if (options.systemTab === true) {
|
|
1282
1487
|
const tabEdit = this.ensureSystemTabEdit(options.tabKey);
|
|
1283
|
-
const sections = ensureArrayProperty<
|
|
1488
|
+
const sections = ensureArrayProperty<SerializedPageLayoutSection>(
|
|
1284
1489
|
tabEdit as Record<string, any>,
|
|
1285
1490
|
'newSections',
|
|
1286
1491
|
`systemTabEdits.${options.tabKey}.newSections`,
|
|
@@ -1346,7 +1551,7 @@ export class CustomObjectPageLayout {
|
|
|
1346
1551
|
this.assertFieldSectionBelongsToLayout(section);
|
|
1347
1552
|
const sectionKey = section.getSectionId();
|
|
1348
1553
|
const matches: Array<{
|
|
1349
|
-
sections:
|
|
1554
|
+
sections: SerializedPageLayoutSection[];
|
|
1350
1555
|
section: SerializedFieldsSection;
|
|
1351
1556
|
index: number;
|
|
1352
1557
|
tabEdit?: SerializedSystemTabEdit;
|
|
@@ -1356,14 +1561,14 @@ export class CustomObjectPageLayout {
|
|
|
1356
1561
|
if (!isTabWithSections(tab)) continue;
|
|
1357
1562
|
if (options.tabKey != null && tab.key !== options.tabKey) continue;
|
|
1358
1563
|
tab.sections.forEach((section, index) => {
|
|
1359
|
-
if (layoutSectionMatches(section, sectionKey))
|
|
1564
|
+
if (isSerializedFieldsSection(section) && layoutSectionMatches(section, sectionKey))
|
|
1360
1565
|
matches.push({ sections: tab.sections, section, index, tabKey: tab.key });
|
|
1361
1566
|
});
|
|
1362
1567
|
}
|
|
1363
1568
|
for (const [tabKey, tabEdit] of Object.entries(this._tabEdits.systemTabEdits ?? {})) {
|
|
1364
1569
|
if (options.tabKey != null && tabKey !== options.tabKey) continue;
|
|
1365
1570
|
(tabEdit.newSections ?? []).forEach((section, index) => {
|
|
1366
|
-
if (layoutSectionMatches(section, sectionKey))
|
|
1571
|
+
if (isSerializedFieldsSection(section) && layoutSectionMatches(section, sectionKey))
|
|
1367
1572
|
matches.push({ sections: tabEdit.newSections!, section, index, tabEdit, tabKey });
|
|
1368
1573
|
});
|
|
1369
1574
|
}
|
|
@@ -1380,7 +1585,7 @@ export class CustomObjectPageLayout {
|
|
|
1380
1585
|
}
|
|
1381
1586
|
|
|
1382
1587
|
const removals = removeAll ? matches : matches.slice(0, 1);
|
|
1383
|
-
const byArray = new Map<
|
|
1588
|
+
const byArray = new Map<SerializedPageLayoutSection[], number[]>();
|
|
1384
1589
|
for (const match of removals) {
|
|
1385
1590
|
const indexes = byArray.get(match.sections) ?? [];
|
|
1386
1591
|
indexes.push(match.index);
|
|
@@ -1474,11 +1679,13 @@ export class CustomObjectPageLayout {
|
|
|
1474
1679
|
}
|
|
1475
1680
|
|
|
1476
1681
|
/** Sets the record title field in `header_edits`. */
|
|
1477
|
-
setTitleField(field: Field
|
|
1682
|
+
setTitleField(field: Field): this;
|
|
1683
|
+
setTitleField(fieldApiName: FieldRqlName): this;
|
|
1684
|
+
setTitleField(field: Field | FieldRqlName): this {
|
|
1478
1685
|
const previousTitleField = this._headerEdits.newTitleField;
|
|
1479
1686
|
const nextTitleField = this.headerFieldApiName(field);
|
|
1480
1687
|
this._headerEdits.newTitleField = nextTitleField;
|
|
1481
|
-
|
|
1688
|
+
this._headerEdits.titleFieldDeleted = false;
|
|
1482
1689
|
insertUniqueAt(this.ensureHeaderFieldsOrder(), nextTitleField, 'end');
|
|
1483
1690
|
this.removeHeaderOrderFieldIfUnused(previousTitleField);
|
|
1484
1691
|
return this;
|
|
@@ -1494,11 +1701,13 @@ export class CustomObjectPageLayout {
|
|
|
1494
1701
|
}
|
|
1495
1702
|
|
|
1496
1703
|
/** Sets the record description field in `header_edits`. */
|
|
1497
|
-
setDescriptionField(field: Field
|
|
1704
|
+
setDescriptionField(field: Field): this;
|
|
1705
|
+
setDescriptionField(fieldApiName: FieldRqlName): this;
|
|
1706
|
+
setDescriptionField(field: Field | FieldRqlName): this {
|
|
1498
1707
|
const previousDescriptionField = this._headerEdits.newDescriptionField;
|
|
1499
1708
|
const nextDescriptionField = this.headerFieldApiName(field);
|
|
1500
1709
|
this._headerEdits.newDescriptionField = nextDescriptionField;
|
|
1501
|
-
|
|
1710
|
+
this._headerEdits.descriptionFieldDeleted = false;
|
|
1502
1711
|
insertUniqueAt(this.ensureHeaderFieldsOrder(), nextDescriptionField, 'end');
|
|
1503
1712
|
this.removeHeaderOrderFieldIfUnused(previousDescriptionField);
|
|
1504
1713
|
return this;
|
|
@@ -1571,7 +1780,7 @@ export class CustomObjectPageLayout {
|
|
|
1571
1780
|
private normalizeSectionFieldForMutation(
|
|
1572
1781
|
section: CustomObjectFieldSection | string,
|
|
1573
1782
|
sectionKey: string,
|
|
1574
|
-
entry:
|
|
1783
|
+
entry: SectionFieldInput,
|
|
1575
1784
|
): SerializedSectionField {
|
|
1576
1785
|
if (isField(entry)) {
|
|
1577
1786
|
this.assertFieldBelongsToLayout(entry);
|
|
@@ -1591,7 +1800,9 @@ export class CustomObjectPageLayout {
|
|
|
1591
1800
|
);
|
|
1592
1801
|
}
|
|
1593
1802
|
|
|
1594
|
-
private normalizeSectionForMutation(input: PageLayoutSection):
|
|
1803
|
+
private normalizeSectionForMutation(input: PageLayoutSection): SerializedPageLayoutSection {
|
|
1804
|
+
if (input.type !== 'fields_section') return { ...input };
|
|
1805
|
+
|
|
1595
1806
|
this.assertFieldSectionBelongsToLayout(input.section);
|
|
1596
1807
|
|
|
1597
1808
|
const sectionId = input.section.getSectionId();
|
|
@@ -1599,13 +1810,16 @@ export class CustomObjectPageLayout {
|
|
|
1599
1810
|
throw new Error('CustomObjectPageLayout fields_section key is not supported. Omit key.');
|
|
1600
1811
|
}
|
|
1601
1812
|
const name = input.name ?? input.section.getName();
|
|
1602
|
-
const normalized
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1813
|
+
const normalized = copySectionOptions<SerializedFieldsSection>(
|
|
1814
|
+
{
|
|
1815
|
+
name,
|
|
1816
|
+
type: 'fields_section',
|
|
1817
|
+
fields: input.fields.map((field) =>
|
|
1818
|
+
this.normalizeSectionFieldForMutation(input.section, sectionId, field),
|
|
1819
|
+
),
|
|
1820
|
+
},
|
|
1821
|
+
input,
|
|
1822
|
+
);
|
|
1609
1823
|
if (input.layout != null) normalized.layout = input.layout;
|
|
1610
1824
|
return attachFieldSectionId(normalized, sectionId);
|
|
1611
1825
|
}
|
|
@@ -1738,6 +1952,7 @@ export class CustomObjectPageLayout {
|
|
|
1738
1952
|
if (!isTabWithSections(tab)) continue;
|
|
1739
1953
|
if (filter.tabKey != null && tab.key !== filter.tabKey) continue;
|
|
1740
1954
|
for (const [index, section] of tab.sections.entries()) {
|
|
1955
|
+
if (!isSerializedFieldsSection(section)) continue;
|
|
1741
1956
|
const sectionKey = layoutSectionKey(section);
|
|
1742
1957
|
if (filter.sectionKey != null && !layoutSectionMatches(section, filter.sectionKey)) continue;
|
|
1743
1958
|
const label = sectionKey == null ? `${tab.key}.sections[${index}]` : `${tab.key}.${sectionKey}`;
|
|
@@ -1758,6 +1973,7 @@ export class CustomObjectPageLayout {
|
|
|
1758
1973
|
for (const [tabKey, tabEdit] of Object.entries(this._tabEdits.systemTabEdits ?? {})) {
|
|
1759
1974
|
if (filter.tabKey != null && tabKey !== filter.tabKey) continue;
|
|
1760
1975
|
for (const [index, section] of (tabEdit.newSections ?? []).entries()) {
|
|
1976
|
+
if (!isSerializedFieldsSection(section)) continue;
|
|
1761
1977
|
const sectionKey = layoutSectionKey(section);
|
|
1762
1978
|
if (filter.sectionKey != null && !layoutSectionMatches(section, filter.sectionKey)) continue;
|
|
1763
1979
|
const label = sectionKey == null ? `${tabKey}.newSections[${index}]` : `${tabKey}.${sectionKey}`;
|
|
@@ -1870,7 +2086,7 @@ export class CustomObjectPageLayout {
|
|
|
1870
2086
|
}
|
|
1871
2087
|
|
|
1872
2088
|
private assertSectionKeyAvailable(
|
|
1873
|
-
sections:
|
|
2089
|
+
sections: SerializedPageLayoutSection[],
|
|
1874
2090
|
sectionKey: string | undefined,
|
|
1875
2091
|
tabKey: string,
|
|
1876
2092
|
allowDuplicate: boolean | undefined,
|
|
@@ -1903,8 +2119,7 @@ export class CustomObjectPageLayout {
|
|
|
1903
2119
|
return normalized;
|
|
1904
2120
|
}
|
|
1905
2121
|
|
|
1906
|
-
private headerFieldApiName(field: Field |
|
|
1907
|
-
if (field == null) return null;
|
|
2122
|
+
private headerFieldApiName(field: Field | FieldRqlName): FieldRqlName {
|
|
1908
2123
|
if (typeof field === 'string') return field;
|
|
1909
2124
|
this.assertFieldBelongsToLayout(field);
|
|
1910
2125
|
return field.getApiName();
|