@pega/sdk 0.0.13 → 0.0.14
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/package.json +1 -1
- package/templates/angular-sdk-reference/angular.json +2 -1
- package/templates/angular-sdk-reference/package.json +1 -0
- package/templates/angular-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
- package/templates/angular-sdk-reference/src/app/app.component.ts +232 -15
- package/templates/angular-sdk-reference/src/components/component-map.ts +90 -0
- package/templates/angular-sdk-reference/src/components/fields/auto-complete/auto-complete.component.ts +267 -0
- package/templates/angular-sdk-reference/src/components/fields/checkbox/checkbox.component.ts +84 -0
- package/templates/angular-sdk-reference/src/components/fields/currency/currency.component.ts +97 -0
- package/templates/angular-sdk-reference/src/components/fields/date-input/date-input.component.ts +88 -0
- package/templates/angular-sdk-reference/src/components/fields/dropdown/dropdown.component.ts +101 -0
- package/templates/angular-sdk-reference/src/components/fields/email/email.component.ts +91 -0
- package/templates/angular-sdk-reference/src/components/fields/integer/integer.component.ts +93 -0
- package/templates/angular-sdk-reference/src/components/fields/phone/phone.component.ts +91 -0
- package/templates/angular-sdk-reference/src/components/fields/radio-buttons/radio-buttons.component.ts +102 -0
- package/templates/angular-sdk-reference/src/components/fields/text-area/text-area.component.ts +98 -0
- package/templates/angular-sdk-reference/src/components/fields/text-input/text-input.component.ts +97 -0
- package/templates/angular-sdk-reference/src/components/fields/url-input/url-input.component.ts +94 -0
- package/templates/angular-sdk-reference/src/components/infra/assignment/assignment.component.ts +206 -0
- package/templates/angular-sdk-reference/src/components/infra/case-summary/case-summary.component.ts +76 -0
- package/templates/angular-sdk-reference/src/components/infra/case-view/case-view.component.ts +114 -0
- package/templates/angular-sdk-reference/src/components/infra/flow-container/flow-container.component.ts +411 -0
- package/templates/angular-sdk-reference/src/components/infra/reference/reference.component.ts +158 -0
- package/templates/angular-sdk-reference/src/components/infra/region/region.component.ts +39 -0
- package/templates/angular-sdk-reference/src/components/infra/root-container/root-container.component.ts +193 -0
- package/templates/angular-sdk-reference/src/components/infra/stages/stages.component.ts +78 -0
- package/templates/angular-sdk-reference/src/components/infra/view/view.component.ts +139 -0
- package/templates/angular-sdk-reference/src/components/infra/view-container/view-container.component.ts +191 -0
- package/templates/angular-sdk-reference/src/components/templates/default-form/default-form.component.ts +101 -0
- package/templates/angular-sdk-reference/src/components/templates/narrow-wide/narrow-wide.component.ts +37 -0
- package/templates/angular-sdk-reference/src/components/templates/one-column/one-column.component.ts +37 -0
- package/templates/angular-sdk-reference/src/components/templates/two-column/two-column.component.ts +37 -0
- package/templates/angular-sdk-reference/src/components/templates/wide-narrow/wide-narrow.component.ts +37 -0
- package/templates/angular-sdk-reference/src/helpers/event-utils.ts +18 -0
- package/templates/angular-sdk-reference/src/helpers/utils.ts +38 -0
- package/templates/angular-sdk-reference/src/helpers/versionHelpers.ts +14 -0
- package/templates/angular-sdk-reference/tsconfig.json +5 -2
- package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +11 -4
- package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +7 -0
- package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +3 -1
- package/templates/react-sdk-reference/.ai-common/skills/field-components.md +75 -29
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/AutoComplete.md +133 -101
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedData.md +385 -0
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedDataMulti.md +506 -0
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/ObjectReference.md +549 -86
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/UserReference.md +181 -83
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListView.md +125 -153
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/SimpleTable.md +90 -81
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Skill: ObjectReference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reference field that binds a case to another data record or case, rendered as a picker, table, card list, search form, or read-only link.
|
|
4
4
|
|
|
5
5
|
> **Prerequisite skill:** [`field-components.md`](../field-components.md) — covers architecture, input contract, display modes, event handling, and registration patterns common to ALL field components.
|
|
6
6
|
|
|
@@ -8,142 +8,605 @@ Composite field that dynamically renders a child component (Dropdown, AutoComple
|
|
|
8
8
|
|
|
9
9
|
## Component Purpose
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Renders no input control of its own. It inspects its own configuration, decides which component should actually present the reference, resolves that component from the project's component registry, and hands it a derived configuration.
|
|
12
|
+
|
|
13
|
+
One component covers a large surface: two Pega field types (Data Reference and Case Reference), two selection modes (a single record or a list of records), an editable and a read-only form of each, and six presentations. That is eighteen reachable combinations, and the configuration keys that are meaningful differ in every one of them.
|
|
14
|
+
|
|
15
|
+
Because it is an orchestrator, almost everything it does is _deciding_ rather than _drawing_. Read the Rendering Decision Tree as an ordered procedure — several conditions overlap, and the first match wins.
|
|
12
16
|
|
|
13
17
|
## Pega Metadata
|
|
14
18
|
|
|
15
19
|
- **Pega Name:** `ObjectReference`
|
|
16
20
|
- **Type / Subtype:** `Field` / `Reference`
|
|
17
21
|
- **Registration key:** `ObjectReference` (in the project's component map)
|
|
22
|
+
- **Shown in the configuration UI as:** `Data Reference` or `Case Reference`. Both compile to this same component; they differ only in the values described under Reference Types.
|
|
23
|
+
|
|
24
|
+
### Reference Types
|
|
25
|
+
|
|
26
|
+
The `targetObjectType` key carries `"data"` or `"case"` — compare it case-insensitively and treat anything that is not the case value as data. The configuration surface is identical for both; only these values differ.
|
|
27
|
+
|
|
28
|
+
| Aspect | Data Reference | Case Reference |
|
|
29
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| `targetObjectType` | `"data"` | `"case"` |
|
|
31
|
+
| `targetObjectClass` | a class name whose third segment is `Data`, as in `Organisation-Application-Data-ObjectName` | a class name whose third segment is `Work`, as in `Organisation-Application-Work-CaseTypeName` |
|
|
32
|
+
| Identifying property | `pyGUID` | `pyID` |
|
|
33
|
+
| Extra key | none | `previewKey`, holding the instance handle `pzInsKey`. Emitted for EVERY presentation, not only the read-only one |
|
|
34
|
+
| `displayField` default | a property chosen during configuration | `pyLabel` |
|
|
35
|
+
| `detailsView` resolution | the named view contains its field descriptors directly, one level down | the named view contains a region holding a view reference, which resolves to a second view that holds the descriptors |
|
|
36
|
+
| Read-only link activation | opens the referenced data record | opens the referenced case by its handle |
|
|
37
|
+
| Generated column definitions | no extra column | one extra secondary column carrying `pyID` |
|
|
38
|
+
|
|
39
|
+
Always read the class name verbatim from `targetObjectClass`. The segment patterns above describe what the value looks like so that the two reference types can be told apart on sight — they are not a template for constructing a class name. Never derive, normalise, or guess a class name, and never assume the organisation and application segments match those of the case that holds the field: a referenced data page can belong to a different application, or to an inherited base class.
|
|
40
|
+
|
|
41
|
+
The identifying property names above are fixed platform properties, so they can be relied on. Every other property path in the configuration is chosen during configuration and must be read from the key that carries it.
|
|
42
|
+
|
|
43
|
+
### Mode and Presentation Matrix
|
|
44
|
+
|
|
45
|
+
`mode` has four values, not two. The implementation constant for selection mode only knows the two editable values, so never compare `mode` directly against that constant without also handling the read-only values.
|
|
46
|
+
|
|
47
|
+
The configuration UI offers a Mode control and a Display as control, and the options in the second depend on the first. `componentType` records the chosen presentation.
|
|
48
|
+
|
|
49
|
+
| `mode` | Display as | `componentType` | Present using |
|
|
50
|
+
| ----------------- | ----------------- | ----------------- | ----------------------------------------------------------------------- |
|
|
51
|
+
| `single` | Combobox | `Combobox` | the search/typeahead component |
|
|
52
|
+
| `single` | Dropdown | `Dropdown` | the dropdown/select component |
|
|
53
|
+
| `single` | Table | `Table` | the selectable-table component, table presentation |
|
|
54
|
+
| `single` | Simple table | `SimpleTable` | the selectable-table component, simple-table presentation |
|
|
55
|
+
| `single` | Search and select | `SearchAndSelect` | the search-form component, with this component's children |
|
|
56
|
+
| `single` | Cards | `Cards` | the single-choice component in its card presentation |
|
|
57
|
+
| `readonly-single` | Read-only field | `SemanticLink` | the link component, or a read-only text component — see `linkReference` |
|
|
58
|
+
| `multi` | Table | `Table` | the selectable-table component, table presentation |
|
|
59
|
+
| `multi` | Simple table | `SimpleTable` | the selectable-table component, simple-table presentation |
|
|
60
|
+
| `multi` | Combobox | `Combobox` | the multi-select component |
|
|
61
|
+
| `multi` | Checkbox group | `CheckboxGroup` | the multiple-choice component in its checkbox-group presentation |
|
|
62
|
+
| `multi` | Search and select | `SearchAndSelect` | the search-form component, with this component's children |
|
|
63
|
+
| `multi` | Cards | `Cards` | the multiple-choice component in its card presentation |
|
|
64
|
+
| `readonly-multi` | Read-only field | `SemanticLink` | the multi-reference read-only component |
|
|
65
|
+
| `readonly-multi` | Table | `Table` | the selectable-table component in read-only mode |
|
|
66
|
+
| `readonly-multi` | Simple table | `SimpleTable` | the selectable-table component in read-only mode |
|
|
67
|
+
| `readonly-multi` | Map | `Map` | not currently presented — see Implementation Status |
|
|
68
|
+
| `readonly-multi` | Cards | `Cards` | the multiple-choice component in its card presentation, read-only |
|
|
69
|
+
|
|
70
|
+
Two further `componentType` values exist that the configuration UI cannot produce, but which may appear in older or generated views: a multi-select value that behaves as the `multi` Combobox case, and an embedded-insight table value that should present as a manually-fed read-only table.
|
|
71
|
+
|
|
72
|
+
**Table and Simple table render identically.** Both values route to the same selectable-table component, which presents one simple table with a selection control per row. The settings that only a full table could honour — Filter by, Group by, Sort by, Row density, Max height, Column to take remaining width, and Allow user edit column visibility — are out of scope: ignore their keys whatever they contain. Pass the presentation name through only so the table knows which one was configured.
|
|
73
|
+
|
|
74
|
+
Defaults worth knowing: a newly created single-record field arrives as `Combobox`; a newly created list-of-records field arrives as `Table`. Under `readonly-single` the Display as control offers exactly one option, so treat that pairing as fixed. Under `readonly-multi` it offers five, so do not generalise the single-record behaviour.
|
|
75
|
+
|
|
76
|
+
### Configuration Settings → Config Keys
|
|
77
|
+
|
|
78
|
+
This field type has **three** separate configuration surfaces. Keep them distinct — they have different lifetimes and different clearing behaviour.
|
|
79
|
+
|
|
80
|
+
#### Surface 1 — the per-view field dialog
|
|
81
|
+
|
|
82
|
+
Settings stored per view. Every value arrives already resolved; see Condition Encoding.
|
|
83
|
+
|
|
84
|
+
| Configuration control | Emitted config key(s) | Value shape and notes |
|
|
85
|
+
| --------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| Label | `labelOption` + `label` | `labelOption` is `"default"` when the field's own name is kept, and the label is then plain text; it is `"custom"` when text is supplied, and the label then carries the localization marker. Always render the resolved `label`; never branch on `labelOption` |
|
|
87
|
+
| Required | `required` | See Condition Encoding |
|
|
88
|
+
| Disabled | `disabled` | See Condition Encoding |
|
|
89
|
+
| Visibility | `visibility` | See Condition Encoding. For a single record the control also offers "if not blank" and "if not zero", which compile to ordinary expressions against the field's own bound value. Those two choices are absent for a list of records, because a list has no single scalar value to test |
|
|
90
|
+
| Test ID | `testId` | A plain, non-localized string |
|
|
91
|
+
|
|
92
|
+
#### Surface 2 — the per-field-definition panel
|
|
93
|
+
|
|
94
|
+
Settings stored on the field definition itself, so they are shared by every view that uses the field. The sections present in this panel change with `mode` and `componentType`; a control that is absent does not clear the key it previously wrote.
|
|
95
|
+
|
|
96
|
+
| Configuration control | Emitted config key(s) | Value shape and notes |
|
|
97
|
+
| ------------------------------------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| Mode | `mode` | One of the four values in the matrix above |
|
|
99
|
+
| Display as | `componentType` | One of the values in the matrix above |
|
|
100
|
+
| Data page | `referenceList` | The rule name of the chosen data page, never its description. See Preview Metadata Hazards before trusting it |
|
|
101
|
+
| Parameters | `parameters` | A flat object keyed by the parameter names the chosen data page declares. Present only when that data page declares parameters, independent of presentation |
|
|
102
|
+
| Search mode | `matchPosition` | Absent for the default "contains" behaviour; `"start"` for prefix matching. The key is `matchPosition` — there is no `searchMode` key |
|
|
103
|
+
| Display field | `displayField` | The property shown to identify a record. Marker usage is mode-dependent — see Annotation Prefixes |
|
|
104
|
+
| Fields / Additional details | `secondaryFields` | A list of nested component descriptors. Emitted as an empty list when none are configured |
|
|
105
|
+
| Columns | `columns` | Either a list of nested component descriptors, or a single view reference. See Column Definitions |
|
|
106
|
+
| Hide field labels | `hideFieldLabels` | Boolean |
|
|
107
|
+
| Groups | `groupsFields` | A list of nested component descriptors used to group the option list |
|
|
108
|
+
| Show details | `detailsView` | The rule name of a view, never its description. The named view and everything it transitively references are delivered in the same payload |
|
|
109
|
+
| Allow creation of new records | `allowCreatingRecords` | Boolean |
|
|
110
|
+
| Allow user edit column visibility | `toggleFieldVisibility` | Boolean |
|
|
111
|
+
| Imagery | `imagePosition` | `"none"`, `"inline-start"`, `"block-start"`, or `"inline-end"` for the None, before-text, above-text and after-text choices respectively |
|
|
112
|
+
| Image size | `imageSize` | A lowercased size token such as `"flexible"` or `"small"` |
|
|
113
|
+
| Image field | `imageField` | Absent until a property is chosen, even though the control is marked required |
|
|
114
|
+
| Add image description / Description field | `showImageDescription` + `imageDescription` | Boolean, plus the property supplying the alternative text |
|
|
115
|
+
| Display inline | `inlineDisplay` | Boolean, used by the card presentation |
|
|
116
|
+
| Display horizontally | `inline` | Boolean, used by the checkbox-group presentation. A DIFFERENT key from `inlineDisplay` — see Key Lifecycle Rules |
|
|
117
|
+
| Link the selected reference | `linkReference` | Boolean. When false the read-only presentation must show plain text rather than a link |
|
|
118
|
+
| Link behavior | `linkBehavior` | Absent for the default; otherwise `"open"`, `"openInTab"`, or `"preview"`. Only meaningful when `linkReference` is true |
|
|
119
|
+
| "Search for" categories | `presets`, plus a child per category | Each category becomes a separate named view; the field node gains one deferred-load child per category. See View References |
|
|
120
|
+
| Search label | no key at the default | The custom setting's key has not been observed |
|
|
121
|
+
| Allow selection in read-only view | `allowAndPersistChangesInReviewMode` | Boolean. Enables changing the reference while the surrounding view is in a display mode |
|
|
122
|
+
| Location field | no key observed | The control was only ever offered an empty choice, so the key name is unconfirmed |
|
|
123
|
+
| Column to take remaining width, Filter by, Sort by, Group by, Row density, Max height | no keys at their defaults | Out of scope — both table presentations render as one simple table. Ignore these settings, including `filterExpression` inside a table preset |
|
|
124
|
+
|
|
125
|
+
Three further keys are emitted by the platform rather than chosen: `targetObjectClass` and `targetObjectType` identify what is being referenced, and `targetClassLabel` with `targetClassLabelOption` carry a display label for that class using the same default/custom pattern as the field label.
|
|
126
|
+
|
|
127
|
+
The binding keys differ by mode:
|
|
128
|
+
|
|
129
|
+
| Key | Single record | List of records |
|
|
130
|
+
| --------------- | ----------------------------------------------------------- | ----------------------------------------------------- |
|
|
131
|
+
| `value` | the path to the referenced record's identifying property | **absent** |
|
|
132
|
+
| `contextPage` | the path to the embedded page holding the referenced record | **absent** |
|
|
133
|
+
| `pagelistValue` | absent | the path to the case's own list of referenced records |
|
|
134
|
+
| `selectionKey` | absent | the identifying property on each row of that list |
|
|
135
|
+
|
|
136
|
+
#### Surface 3 — the per-descriptor dialog
|
|
137
|
+
|
|
138
|
+
Every entry in `secondaryFields`, `columns`, `groupsFields`, and the columns and search groups inside `presets` has its own configuration dialog. Its control set depends on **which list the descriptor lives in**, not on the active presentation.
|
|
139
|
+
|
|
140
|
+
| Descriptor lives in | Controls offered | Emitted keys |
|
|
141
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
142
|
+
| `secondaryFields` / `groupsFields` | Display as, Label, Format | the descriptor's own `type`, `label`, `labelOption`, `formatter` |
|
|
143
|
+
| `columns`, and columns in `presets` | the same, plus Show additional details and Column width | the above, plus `additionalDetails` |
|
|
144
|
+
| search groups inside `presets` | Display as, Label, Edit mode, Placeholder, Helper text, Show field input warning, Required, Disabled, Visibility, Test ID | the full editable-field key set |
|
|
145
|
+
|
|
146
|
+
That last row matters: search-group entries are real editable inputs used as search criteria, so the whole Condition Encoding contract applies recursively to them.
|
|
147
|
+
|
|
148
|
+
`formatter` carries the chosen format name with spaces removed, such as a work-status, email, percentage or phone format; it is omitted entirely when the format is left at its default. `additionalDetails` is described under Nested Field Descriptors.
|
|
149
|
+
|
|
150
|
+
### Raw and Resolved Configuration
|
|
151
|
+
|
|
152
|
+
This component reads its configuration from two places. Reading a key from the wrong one is the most common cause of a broken reference field, so decide the source for every key before writing any logic.
|
|
153
|
+
|
|
154
|
+
- **Resolved inputs** are what the runtime hands the component after replacing every marker with its current value. A property-reference marker becomes _the current value of that property_. That is right for text and conditions, and wrong for anything that names a property, a data page, a view or a column.
|
|
155
|
+
- **Raw configuration** is returned by `getPConnect().getRawMetadata().config`. It holds every key exactly as configured, markers included.
|
|
156
|
+
|
|
157
|
+
Read these from the resolved inputs: `label`, `required`, `disabled`, `visibility`, `readOnly`, `displayMode`, `hideLabel`, `testId`, `parameters`, `targetClassLabel`, `allowAndPersistChangesInReviewMode`, `additionalFields`, and `children`. Merge the inherited inputs returned by `getPConnect().getInheritedProps()` underneath them, so a label supplied by the surrounding view is honoured when this field has none of its own.
|
|
158
|
+
|
|
159
|
+
Read every structural key from the raw configuration: `mode`, `componentType`, `value`, `contextPage`, `pagelistValue`, `selectionKey`, `displayField`, `previewKey`, `referenceList`, `columns`, `secondaryFields`, `groupsFields`, `presets`, `detailsView`, `targetObjectClass`, `targetObjectType`, the imagery keys, `inline`, `inlineDisplay`, `matchPosition`, `allowCreatingRecords`, `hideFieldLabels`, `linkReference`, `localeReference`, and the raw form of `parameters` when it is handed on to a child.
|
|
160
|
+
|
|
161
|
+
Why it matters, by example: for a single record the raw `displayField` is a property path such as `@P .Customer.FullName`. The resolved `displayField` is that customer's full name — or an empty string before anything is selected. A picker built from the resolved value has no display column, and every option renders with an empty label.
|
|
162
|
+
|
|
163
|
+
Never modify the raw configuration in place. The runtime shares it with every later render. Take a copy, and derive each child configuration from the copy.
|
|
164
|
+
|
|
165
|
+
### Annotation Prefixes
|
|
166
|
+
|
|
167
|
+
Markers live in the raw configuration. When you build a child configuration and hand it to `getPConnect().createComponent` (see Implementation Structure), leave markers in place on every key the child binds to — the runtime resolves them for the child, against the child's own context. Strip a marker only where this skill tells you to derive a bare property name.
|
|
168
|
+
|
|
169
|
+
A **property reference** marker points at a property on the case or on a referenced record. A **localization** marker precedes user-facing text. A **locale reference** marker identifies the view's localization bundle. An **expression** marker precedes a computed condition. A **When Rule** marker names a decision rule. A **user reference** marker identifies an operator-valued property. An **associated datasource** marker points at an associated list. A **field metadata** marker points at a field's own metadata. A **class context** marker names a class. An **attachment** marker identifies an attachment-valued property. A **field label** marker resolves a property's configured label.
|
|
170
|
+
|
|
171
|
+
Wherever a configuration picker shows a friendly description — of a data page, a view, a decision rule, or a class — the stored value is the underlying rule or property NAME instead. Treat the two as unrelated strings; neither can be derived from the other.
|
|
172
|
+
|
|
173
|
+
Two marker rules are easy to get wrong, and both were observed repeatedly.
|
|
174
|
+
|
|
175
|
+
**Marker use is mode-dependent.** For a single record, the record-relative paths (`displayField`, `previewKey`, `imageDescription`) carry the property-reference marker and are expressed through the field's own path. For a list of records the same keys are emitted **bare** — no marker and no field prefix — because they address a property on each row rather than on one embedded record. `selectionKey` is always bare. Only `pagelistValue` keeps its marker in list mode.
|
|
176
|
+
|
|
177
|
+
**Marker use differs by node level within a single payload.** The same property can appear twice: bare as a field-level key, and marked inside a nested descriptor. Descriptors are resolved by the runtime as ordinary field components, so they carry markers; field-level keys are consumed directly by this component, so they do not. Never normalise one rule across both.
|
|
178
|
+
|
|
179
|
+
Because of both rules: never test whether a path carries a marker in order to decide what it means. Strip a leading marker if present, and otherwise use the value as given.
|
|
180
|
+
|
|
181
|
+
### Condition Encoding
|
|
182
|
+
|
|
183
|
+
State this once and apply it everywhere. `required`, `disabled`, `visibility`, and the same settings on any nested descriptor can each arrive in one of six shapes — absent, the boolean true, the boolean false, an empty string, an expression-marked string, or a When-Rule-marked string. All six are already resolved to a plain boolean by the time the component receives the input. Consequences:
|
|
184
|
+
|
|
185
|
+
- Treat each of these inputs as a plain boolean. Never inspect its raw string form, and never treat a non-empty string as automatically true — doing so would make every expression-based or rule-based setting permanently active.
|
|
186
|
+
- Treat absent, an empty string, and an explicitly-set default value as equivalent to the setting's documented default. Key presence alone never indicates that a setting was deliberately changed.
|
|
187
|
+
- The convenience visibility choices offered for a single record compile to ordinary expressions evaluated against the field's own bound value. They introduce no new shape.
|
|
188
|
+
- Never implement show/hide logic from `visibility`. A field whose visibility resolves to false is not rendered by the surrounding runtime at all.
|
|
189
|
+
|
|
190
|
+
### Preview Metadata Hazards
|
|
191
|
+
|
|
192
|
+
View metadata captured from the configuration UI is _preview_ metadata, and it substitutes placeholder values. This matters because tooling that discovers components or datasources by walking view metadata will read those placeholders as though they were real.
|
|
193
|
+
|
|
194
|
+
Placeholder property paths are named for a field **type**, not for a field. Consequences:
|
|
195
|
+
|
|
196
|
+
- Two different descriptors of the same type share one identical placeholder path. Only `label` distinguishes them, so never use a descriptor's bound path as an identity, a key, or a de-duplication criterion.
|
|
197
|
+
- A placeholder data page name appears in `referenceList` instead of the configured one. Changing the configured data page can leave the emitted value completely unchanged.
|
|
198
|
+
|
|
199
|
+
Substitution follows the **presentation family**, not the mode and not the reference type. The picker-style presentations (Combobox, Cards, Checkbox group, Map, and the read-only link) emit a placeholder data page name and a placeholder binding path. The table-style presentations and the generated search categories emit the real values. Within one payload, `selectionKey` and `previewKey` stay real even when the binding beside them is a placeholder.
|
|
200
|
+
|
|
201
|
+
Therefore: this hazard belongs to tooling that reads configuration-time preview metadata, not to the runtime component. At runtime the committed configuration carries the real data page, so take the data page name from the raw `referenceList`. Treat `parameters` as trustworthy in both — it reflects the configured data page even when a preview `referenceList` does not.
|
|
202
|
+
|
|
203
|
+
One more preview artifact: the generated search category view declares a single-selection mode even when the field selects multiple records. Never derive selection behaviour from that view; derive it from `mode`.
|
|
204
|
+
|
|
205
|
+
### Key Lifecycle Rules
|
|
206
|
+
|
|
207
|
+
The configuration UI does not clear keys consistently when a setting stops being relevant. Four distinct behaviours were observed:
|
|
208
|
+
|
|
209
|
+
1. Changing **Display as** leaves keys from the previous presentation in place, still carrying their old values.
|
|
210
|
+
2. Changing **Mode** clears the presentation keys.
|
|
211
|
+
3. Changing the **target class** rebuilds the nested field lists but leaves single-value settings untouched.
|
|
212
|
+
4. The clearing is asymmetric: switching into the read-only mode cleared presentation keys, while switching back out did not clear the read-only ones.
|
|
213
|
+
|
|
214
|
+
Emptiness is also encoded inconsistently: a list with nothing in it is emitted as an empty list, whereas a single-value setting at its default emits no key at all — and a control marked required still emits nothing while it is empty.
|
|
215
|
+
|
|
216
|
+
The single rule that follows from all of this: **decide which settings are active from `mode` and `componentType`, never from key presence.** A key that has no corresponding control in the current presentation is stale and must be ignored.
|
|
217
|
+
|
|
218
|
+
Finally, a section's name in the configuration UI is not a reliable guide to its key. Both "Fields" and "Additional details" write `secondaryFields`; "Columns" writes `columns`; "Groups" writes `groupsFields`; and "Search for" categories write `presets` together with child nodes.
|
|
219
|
+
|
|
220
|
+
### Generation Rules
|
|
221
|
+
|
|
222
|
+
1. Read structural keys from the raw configuration, and text and conditions from the resolved inputs — see Raw and Resolved Configuration. Never build a column, a datasource or a link from a resolved property value.
|
|
223
|
+
2. Build every presenting child with `getPConnect().createComponent`, giving it a configuration of its own. The two read-only templates and the search form are the only exceptions, and the decision tree says exactly what they receive. Never render a presenting component directly with this component's own accessor: the child would then read _this_ component's configuration, which lacks the structure the child expects — a table finds no presets and shows no columns, and a picker finds no datasource and shows no options.
|
|
224
|
+
3. Resolve the presentation from `componentType`, and map it to a component you actually provide. Do not pass `componentType` to the registry unchanged — several of its values have no component of that name, and an unresolved name degrades silently to a placeholder rather than raising an error.
|
|
225
|
+
4. Treat `mode` as four values. Derive three independent facts from it: whether one record or many are selected, whether the field is editable, and which binding keys apply.
|
|
226
|
+
5. Read the binding from `value` for a single record and from `pagelistValue` with `selectionKey` for a list. Never assume `value` exists — it is absent for every list-of-records field, and code that reads it unguarded will fail there.
|
|
227
|
+
6. Honour the per-presentation active-key set. Ignore any key whose control does not exist in the current presentation, however plausible its value looks.
|
|
228
|
+
7. Take the data page name from the raw `referenceList`. Forward parameters exactly as the decision tree specifies for each presentation — the raw form to a child built with `createComponent`, which resolves it, and the resolved flat map inside datasource metadata. Treat an empty-string parameter value as not provided.
|
|
229
|
+
8. Render every nested descriptor through the component registry using the descriptor's own `type`, honouring its own `label`, `labelOption`, `formatter` and `additionalDetails`. Descriptors are not limited to simple scalar fields.
|
|
230
|
+
9. Render this component's children. The search-and-select presentation delivers its categories as deferred-load child nodes, and dropping them leaves that presentation with nothing to show.
|
|
231
|
+
10. Pass `columns` through to the table unchanged, in either of its shapes. The table expands a primary-fields entry itself — see Column Definitions.
|
|
232
|
+
11. Apply mode precedence: while the field is read-only, ignore configured required, disabled and placeholder settings even when those keys are present.
|
|
233
|
+
12. Treat the table and simple-table presentations as one presentation, and ignore the table-only settings listed under the Mode and Presentation Matrix.
|
|
234
|
+
13. Give the record-change handler to every presenting child that can change the selection, not only to the pickers.
|
|
235
|
+
14. Implement the settings listed as unimplemented in Implementation Status rather than reproducing the gap. They are genuine configuration options, and a generated component should honour them.
|
|
236
|
+
15. Confirm every registry dependency exists before relying on it — see Registry Dependency Prerequisite.
|
|
18
237
|
|
|
19
238
|
## Inputs (component-specific)
|
|
20
239
|
|
|
21
|
-
>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
240
|
+
> Extends the project's field input contract but omits `value`, because the binding differs by mode — see the binding table under Surface 2.
|
|
241
|
+
|
|
242
|
+
For every input below, an absent value means the stated default. An empty string means the setting was never given a value and must be treated exactly like an absent one. An empty list means the list was configured and left empty, which is different from absent. A key belonging to a presentation other than the active one is stale and must be ignored regardless of its value.
|
|
243
|
+
|
|
244
|
+
| Input | Type | Default | Description |
|
|
245
|
+
| ------------------------------------ | -------------------- | -------- | ------------------------------------------------------------------------------------------------------------- |
|
|
246
|
+
| `getPConnect` | `any` | — | The PConnect accessor |
|
|
247
|
+
| `mode` | `string` | `''` | `single`, `readonly-single`, `multi`, or `readonly-multi` |
|
|
248
|
+
| `componentType` | `string` | — | The chosen presentation; see the Mode and Presentation Matrix |
|
|
249
|
+
| `targetObjectType` | `string` | — | `data` or `case`; compare case-insensitively |
|
|
250
|
+
| `targetObjectClass` | `string` | — | The class of the referenced record |
|
|
251
|
+
| `targetClassLabel` | `string` (optional) | — | Display label for that class, already resolved |
|
|
252
|
+
| `targetClassLabelOption` | `string` (optional) | — | `default` or `custom`; informational only |
|
|
253
|
+
| `value` | `string` (optional) | — | Single record only — path to the referenced record's identifying property |
|
|
254
|
+
| `contextPage` | `string` (optional) | — | Single record only — path to the embedded page holding the referenced record |
|
|
255
|
+
| `pagelistValue` | `string` (optional) | — | List of records only — path to the case's own list of referenced records |
|
|
256
|
+
| `selectionKey` | `string` (optional) | — | List of records only — identifying property on each row |
|
|
257
|
+
| `previewKey` | `string` (optional) | — | Case reference only — the `pzInsKey` instance handle used to open the referenced case |
|
|
258
|
+
| `displayField` | `string` (optional) | — | Property shown to identify a record; marker use is mode-dependent |
|
|
259
|
+
| `referenceList` | `string` (optional) | — | Configured data page name; untrustworthy in preview metadata |
|
|
260
|
+
| `parameters` | `object` (optional) | — | Flat map of the data page's own parameter names to values; empty string means not provided |
|
|
261
|
+
| `matchPosition` | `string` | contains | `start` for prefix matching; absent for the default |
|
|
262
|
+
| `secondaryFields` | `array` (optional) | `[]` | Nested component descriptors shown alongside the display field |
|
|
263
|
+
| `columns` | `array` (optional) | — | Either nested component descriptors or a single view reference — see Column Definitions |
|
|
264
|
+
| `groupsFields` | `array` (optional) | — | Nested component descriptors used to group the option list |
|
|
265
|
+
| `presets` | `array` (optional) | — | Search-and-select column definitions, held inside a generated category view |
|
|
266
|
+
| `detailsView` | `string` (optional) | — | Name of a view describing the referenced record in detail |
|
|
267
|
+
| `hideFieldLabels` | `boolean` (optional) | `false` | Suppresses labels on the secondary fields |
|
|
268
|
+
| `toggleFieldVisibility` | `boolean` (optional) | `false` | Out of scope — ignore; see the Mode and Presentation Matrix |
|
|
269
|
+
| `allowCreatingRecords` | `boolean` (optional) | `false` | Offers an affordance to create a new referenced record |
|
|
270
|
+
| `allowAndPersistChangesInReviewMode` | `boolean` (optional) | `false` | Allows changing the reference while the surrounding view is in a display mode, committing the change directly |
|
|
271
|
+
| `imagePosition` | `string` (optional) | — | `none`, `inline-start`, `block-start`, or `inline-end` |
|
|
272
|
+
| `imageSize` | `string` (optional) | — | A lowercased size token |
|
|
273
|
+
| `imageField` | `string` (optional) | — | Property supplying the image; absent until chosen |
|
|
274
|
+
| `showImageDescription` | `boolean` (optional) | `false` | Enables alternative text for the image |
|
|
275
|
+
| `imageDescription` | `string` (optional) | — | Property supplying that alternative text |
|
|
276
|
+
| `inlineDisplay` | `boolean` (optional) | `false` | Card presentation — lay cards out inline |
|
|
277
|
+
| `inline` | `boolean` (optional) | `false` | Checkbox-group presentation — lay choices out horizontally. A different setting from `inlineDisplay` |
|
|
278
|
+
| `linkReference` | `boolean` (optional) | `false` | Read-only presentation — render the value as a link rather than plain text |
|
|
279
|
+
| `linkBehavior` | `string` (optional) | — | `open`, `openInTab`, or `preview`; absent for the default. Meaningful only when `linkReference` is true |
|
|
280
|
+
| `displayMode` | `string` (optional) | — | Supplied by the surrounding view; a display-only value forces a read-only presentation |
|
|
281
|
+
| `readOnly` | `boolean` (optional) | `false` | Supplied by the surrounding view; see the Rendering Decision Tree for how it interacts with `displayMode` |
|
|
282
|
+
| `label` | `string` (optional) | `''` | Already resolved |
|
|
283
|
+
| `labelOption` | `string` (optional) | default | `default` or `custom`; informational only |
|
|
284
|
+
| `required` | `boolean` (optional) | `false` | Already-resolved boolean |
|
|
285
|
+
| `disabled` | `boolean` (optional) | `false` | Already-resolved boolean |
|
|
286
|
+
| `visibility` | `boolean` (optional) | `true` | Already-resolved boolean; the component is normally not rendered at all when false |
|
|
287
|
+
| `hideLabel` | `boolean` (optional) | `false` | |
|
|
288
|
+
| `testId` | `string` (optional) | `''` | Test identifier |
|
|
289
|
+
| `showPromotedFilters` | `boolean` (optional) | `false` | Offers the table presentations a filter bar |
|
|
290
|
+
| `additionalFields` | `array` (optional) | — | Extra fields for the read-only presentation |
|
|
291
|
+
| `children` | `any` (optional) | — | Deferred-load child nodes; present for the search-and-select presentation and MUST be rendered |
|
|
35
292
|
|
|
36
293
|
## Implementation Structure
|
|
37
294
|
|
|
38
|
-
|
|
295
|
+
An orchestrator. It resolves one presenting component, derives a configuration for it, and renders it inside a single full-width container. It draws no input control itself.
|
|
296
|
+
|
|
297
|
+
### Registry Dependency Prerequisite
|
|
298
|
+
|
|
299
|
+
> **Check this before writing the component.** Because this component only orchestrates others, it cannot work unless its dependencies are already generated and registered.
|
|
300
|
+
|
|
301
|
+
Tooling that discovers components by walking a case's view metadata will not find most of these, because they never appear there as fields — they are building blocks that only components like this one reach for at runtime. A discovery-driven generation pass can therefore produce this component while silently omitting everything it depends on, and a registry lookup that finds nothing degrades to a blank or placeholder render rather than raising an error.
|
|
302
|
+
|
|
303
|
+
The registry keys this component reaches for, by presentation: the search/typeahead component (`AutoComplete`), the dropdown/select component (`Dropdown`), the multi-select component (`Multiselect`), the multiple-choice component (`Checkbox`) and the single-choice component (`RadioButtons`) for the checkbox-group and card presentations, the card renderer those two delegate to (`SelectableCard`), the selectable-table component (`SimpleTableSelect`) and the manually-fed table it falls back to (`SimpleTableManual`), the link component (`SemanticLink`), the search-form component (`SearchForm`), and the two read-only reference templates (`SingleReferenceReadOnly` and `MultiReferenceReadOnly`). The last two, and the table components, are template components — their skills live alongside the template skills rather than the field skills.
|
|
304
|
+
|
|
305
|
+
The dependency is **transitive**. Every nested descriptor is rendered through the registry using its own type, so any field type that appears in a configured column, secondary field or search group is also a dependency — including other reference fields. Enumerate the descriptor types actually present in your metadata and check those too.
|
|
306
|
+
|
|
307
|
+
Before finishing this component: confirm each required key is registered or was generated earlier in the session; generate and register anything missing from its own skill file; only then wire up the lookups.
|
|
39
308
|
|
|
40
|
-
**Module Setup:** The component depends on the project's component registry
|
|
309
|
+
**Module Setup:** The component depends on the project's component registry, on the platform APIs listed under Pega Platform APIs, and on a small set of local helpers, each described under Behavioral Contract: one that derives the picker column definitions, one that collects composite keys, one that extracts a relationship context from a property path, one that builds the table preset, and one that creates a new referenced record. Define the input contract as an extension of the project's field input contract, omitting `value` and adding every input in the table above.
|
|
41
310
|
|
|
42
|
-
**Main Component Logic** —
|
|
311
|
+
**Main Component Logic** — in order:
|
|
43
312
|
|
|
44
|
-
1. **
|
|
45
|
-
2. **
|
|
46
|
-
3. **
|
|
47
|
-
4.
|
|
48
|
-
5.
|
|
49
|
-
6. **
|
|
313
|
+
1. **Registry lookups.** Resolve the presenting components you may need. See the prerequisite above.
|
|
314
|
+
2. **Read both configuration sources.** Take the resolved inputs, merged over the inherited inputs, and take a copy of the raw configuration from `getPConnect().getRawMetadata().config`. From here on, "raw" means that copy.
|
|
315
|
+
3. **Derive the reference type.** Compare the raw `targetObjectType` case-insensitively against `case`: the case value gives `Case`, anything else gives `Data`.
|
|
316
|
+
4. **Derive the reference property and its field metadata.** For a single record, the reference property is the first segment of the raw `value` after its marker — for `@P .Customer.pyGUID` it is `Customer`. For a list, it is the raw `pagelistValue` with its marker and leading separator removed. Pass it to `getPConnect().getFieldMetadata(...)`. The result carries the record descriptors used by the single-record pickers, `additionalInformation` for the additional-information accessor, and the data page parameters from which composite keys are derived. Using the wrong binding yields nothing, which is the most common cause of a silently empty picker.
|
|
317
|
+
5. **Normalise the presentation.** The combobox value is not a component. Map it to `Multiselect` for a list of records and to `AutoComplete` for a single record, on the raw copy, before any other decision.
|
|
318
|
+
6. **Apply the read-only coercion.** If the surrounding view is not already display-only but the field is read-only, a `Multiselect` presentation becomes `SemanticLink`, and every other presentation switches the display mode to display-only. This is why a field can reach the read-only branches without `mode` saying so.
|
|
319
|
+
7. **Compute the edit-in-review flag** — true only when `allowAndPersistChangesInReviewMode` is true _and_ the presentation is now `AutoComplete` or `Dropdown`.
|
|
320
|
+
8. **Load any parameterised option list.** When the presentation is `CheckboxGroup` and the raw configuration declares `parameters`, fetch the rows with `PCore.getDataApiUtils().getData(dataPageName, payload)`, passing the raw `referenceList` as the data page name and a payload that carries the resolved parameters under `dataViewParameters`. Do it when the component is first displayed and again whenever the configuration or the parameters change. Map each row to a key and a value taken from the property named by the last segment of `selectionKey`, and a text taken from the last segment of `displayField`, and drop rows without a key.
|
|
321
|
+
9. **Define the record-change handler** described under Selection and Commit.
|
|
322
|
+
10. **Build the presenting child** by following the Rendering Decision Tree.
|
|
323
|
+
11. **Wrap it** in a single full-width container, and expose the component with the re-render skipping described below, using whatever change-detection mechanism the target framework provides.
|
|
50
324
|
|
|
51
325
|
## Behavioral Contract
|
|
52
326
|
|
|
53
|
-
###
|
|
327
|
+
### Rendering decision tree
|
|
328
|
+
|
|
329
|
+
Evaluate in this order and stop at the first match. The order matters: the display-only test sits above the presentation tests, so a field in a display-only view takes the read-only path whatever its configured presentation.
|
|
330
|
+
|
|
331
|
+
Every value below comes from the raw copy unless it is named as resolved. "Created" means built with `getPConnect().createComponent`, passing a type and a configuration; the runtime resolves the markers in that configuration for the child. "Stripped" means with the leading property-reference marker and its following space removed, so `@P .Orders` becomes `.Orders`. The **table preset** is a list holding exactly one preset whose id is `P_`, whose name is `presets`, whose label is empty, whose template is `Table`, whose configuration is empty, and whose only child is a region named `Columns` holding the raw `columns` unchanged.
|
|
332
|
+
|
|
333
|
+
1. **`SemanticLink` presentation, and not editable in review.**
|
|
334
|
+
- **Single record, `linkReference` not false.** Create `SemanticLink`. Its configuration is the raw copy plus: `primaryField` and `text` set to the raw `displayField`; `caseClass` set to `targetObjectClass`; `caseID` set to the raw `value`; `contextPage` set to the property-reference marker followed by the relationship context of `displayField` (see Helpers); `resourceParams` holding `workID` set to the raw `value`; `resourcePayload` holding `caseClassName` set to `targetObjectClass`; and the resolved display mode, the reference type, `hideLabel`, and the relationship context. `previewKey` travels in the raw copy, which is how a case reference opens by its handle.
|
|
335
|
+
- **Single record, `linkReference` false.** Create `TextInput` with the raw `displayField` as its value, the resolved label, `hideLabel`, read-only set, and the resolved display mode.
|
|
336
|
+
- **List of records.** Render `MultiReferenceReadOnly` directly, with this component's accessor, the resolved label, `hideLabel`, the resolved display mode, `linkReference`, `readonlyMulti` as its presentation, and a configuration holding: `contextClass` set to `targetObjectClass`; `defaultRowHeight`; the resolved label; the table preset; `primaryField` set to the stripped `displayField`; `readonlyContextList` and `referenceList` both set to the raw `pagelistValue`; the reference type; `renderMode` set to `ReadOnly`; and `selectionKey`.
|
|
337
|
+
2. **Display-only, and not editable in review.**
|
|
338
|
+
- **List of records.** Take the list-of-records form of branch 1, whatever the presentation.
|
|
339
|
+
- **Single record.** Render `SingleReferenceReadOnly` directly, with this component's accessor, the resolved label, the presentation name as its type, `readonly` as its presentation, the resolved display mode, `targetObjectClass` as its class, the reference type, `hideLabel`, `linkReference`, the relationship context of `displayField`, and `additionalFields`. Give it a configuration built exactly like the single-record link configuration in branch 1 \u2014 including `text`, `caseID`, `caseClass`, `contextPage`, `resourceParams` and `resourcePayload` \u2014 **for every presentation**. A template that fills in the link text only for some presentations shows `--` for a Table, Cards or Search-and-select field on a review screen.
|
|
340
|
+
3. **`Cards` presentation.** Create `RadioButtons` for a single record, or `Checkbox` for a list. The configuration is the raw copy plus:
|
|
341
|
+
- `variant` set to `card`, `displayAs` set to `cards`, `readOnly` false, `renderMode` set to `ReadOnly` only when `mode` is `readonly-multi`, and the resolved `label`, `required` and `disabled`;
|
|
342
|
+
- `value` set to the raw `value` for a single record, and absent for a list;
|
|
343
|
+
- `contextClass` set to `targetObjectClass`, and the reference type;
|
|
344
|
+
- for a list: `selectionMode` set to `multi`, `selectionKey`, `selectionList` set to the stripped `pagelistValue`, and `readonlyContextList` set to the raw `pagelistValue`; for a single record: `selectionList` set to the stripped `contextPage`;
|
|
345
|
+
- a card preset: one preset whose id is `P_`, name `presets`, label empty, template `Cards`, configuration empty, and whose only child is a region named `AdditionalDetails` holding the raw `secondaryFields`;
|
|
346
|
+
- a `datasource` holding `source` set to the datasource marker followed by the data page name and `.pxResults`, `filterDownloadedFields` set to true, and `fields` whose `key` and `value` are the property-reference marker followed by `selectionKey` \u2014 or, for a single record, by a separator and the last segment of `value` \u2014 and whose `text` is the property-reference marker followed by a separator and the last segment of `displayField`;
|
|
347
|
+
- `primaryField` set to the raw `displayField`, and the relationship context of `displayField`;
|
|
348
|
+
- `inlineDisplay`, `hideFieldLabels`, `hideLabel`, `labelOption`, and the imagery keys `imagePosition`, `imageSize`, `showImageDescription` and `imageDescription`, with `imageField` passed as `image`;
|
|
349
|
+
- the record-change handler.
|
|
350
|
+
4. **Embedded insight table presentation.** Create `SimpleTableManual`. Derive one `TextInput` descriptor per entry of the insight model's query columns whose type is `column` and which carries a field, binding it to the property-reference marker followed by a separator and the field's identifier, and labelled by the field's name or, failing that, its identifier. Wrap them in a table preset. The configuration holds `contextClass` set to `targetObjectClass`, that preset, the resolved label, `readonlyContextList` and `referenceList` both set to the raw `pagelistValue`, `renderMode` set to `ReadOnly`, `dataPageName` set to `referenceList`, and `fieldMetadata` holding a datasource whose `parameters` are the raw parameters, or an empty map.
|
|
351
|
+
5. **`CheckboxGroup` presentation.** Create `Checkbox`. The configuration is the raw copy plus:
|
|
352
|
+
- `displayAs` set to `checkboxgroup`, `inline` (default false), `selectionMode` set to `mode`, and `readOnly` true unless `mode` is `single` or `multi`;
|
|
353
|
+
- a `datasource` whose `fields` map `key` and `value` to the property-reference marker followed by `selectionKey`, and `text` to the marker followed by `displayField`. Its `source` is the datasource marker followed by the data page name and `.pxResults` when the raw configuration declares no parameters, and otherwise the option list fetched in step 8 of the main logic;
|
|
354
|
+
- `primaryField` set to the stripped `displayField`, `selectionKey`, `selectionList` set to the stripped `pagelistValue`, and `readonlyContextList` set to the raw `pagelistValue`;
|
|
355
|
+
- `contextClass` set to `targetObjectClass`, `referenceType` set to the raw `targetObjectType`, the resolved label, `hideLabel`, and the resolved `required`, `disabled` and `visibility`;
|
|
356
|
+
- the record-change handler.
|
|
357
|
+
6. **`Table` or `SimpleTable` presentation.** Create `SimpleTableSelect`. Its `displayAs` is the presentation name in lower camel form \u2014 `table` or `simpleTable`. Both render identically, as one simple table; see the Mode and Presentation Matrix. Its configuration always holds: the table preset; `referenceList`; `contextClass` set to `targetObjectClass`; `defaultRowHeight`; `localeReference`; `rowHeader`; the reference type; the resolved label, `required`, `visibility` and `disabled`; and `hideLabel` false. Then:
|
|
358
|
+
- **`readonly-multi`:** add `readOnly` true, `renderMode` set to `ReadOnly`, `selectionMode` set to `multi`, and `readonlyContextList` and `referenceList` both set to the raw `pagelistValue` \u2014 the second replacing the data page name.
|
|
359
|
+
- **Otherwise:** add `readOnly` false, `inline` false, `showPromotedFilters` false, `selectionMode` set to `mode`, the raw `parameters`, the record-change handler, and `selectionList` and `dataRelationshipContext` both set to the stripped `contextPage` for a single record or the stripped `pagelistValue` for a list. For a single record also add `selectionKey` and `value` both set to the raw `value`, and `contextPage`. For a list also add `readonlyContextList` set to the raw `pagelistValue`.
|
|
360
|
+
7. **Every other presentation is a picker** \u2014 `AutoComplete`, `Dropdown`, `Multiselect` or `SearchAndSelect`. First prepare the raw copy:
|
|
361
|
+
1. Generate the picker column definitions and record the composite keys \u2014 see Column Definitions. This can rewrite the copy's `value`.
|
|
362
|
+
2. Set `deferDatasource` to true and `listType` to `datapage`.
|
|
363
|
+
3. For `AutoComplete` and `Dropdown` with no placeholder, set the placeholder to `@L Select...`.
|
|
364
|
+
4. Unless the field is editable in review, set the copy's `displayMode` to the resolved display mode.
|
|
365
|
+
5. Build the **datasource metadata**: an object holding one `datasource` whose `name` is the data page name, whose `parameters` are the resolved parameters when the raw configuration declares any and an empty map otherwise, and whose `propertyForDisplayText` and `propertyForValue` are the `text` and `value` entries of the datasource field map just generated, each stripped.
|
|
366
|
+
6. Decide whether to offer record creation: the configuration must allow it and the user must be permitted to. See Create-Record Affordance.
|
|
367
|
+
|
|
368
|
+
Then:
|
|
369
|
+
- **`SearchAndSelect`:** render `SearchForm` directly, with this component's accessor, the resolved label, `ObjectReference` as its type, a cache key for the search state, and this component's children inside it. Supply it, through a context that the generated category views read, with: the selection mode; the additional-information accessor; the record descriptors for a single record; the resolved `required`, `visibility`, `disabled` and label; `displayAs` set to `advancedSearch`; `readOnly` false; `matchPosition`; for a single record the reference type, the raw `value` and the raw `contextPage`; for a list `selectionList` set to the stripped `pagelistValue`, `readonlyContextList` set to the raw `pagelistValue`, and the reference type; the relationship context, which is the list or context path without its leading separator when a target class is configured; `hideLabel`; the record-change handler; the create-record function when creation is offered; and `inline`.
|
|
370
|
+
- **`Multiselect`:** create `Multiselect` with the prepared copy plus: the record descriptors; the datasource metadata; `selectionList` set to the stripped `pagelistValue`; `readonlyContextList` set to the raw `pagelistValue`; `selectionKey`; `selectionMode` set to `multi`; the resolved `required`, `visibility`, `disabled` and label; the raw `parameters`; `readOnly` false; `localeReference`; the reference type; `contextClass` set to `targetObjectClass`; `primaryField` set to the stripped `displayField`; `dataRelationshipContext` set to the `pagelistValue` with its marker and leading separator removed; `hideLabel`; the record-change handler; the create-record function when creation is offered; `inline`; and `columnsFormatter` set to the raw `secondaryFields`.
|
|
371
|
+
- **`AutoComplete` or `Dropdown`:** create it with the prepared copy plus: the record descriptors for a single record; the datasource metadata; the resolved `required`, `visibility`, `disabled` and label; the raw `parameters`; `readOnly` false; `localeReference`; the reference type for a single record; `contextClass` set to `targetObjectClass`; `primaryField` set to the raw `displayField`; the relationship context of `displayField`; `hideLabel`; the record-change handler; the create-record function when creation is offered; `inline`; `columnsFormatter` set to the raw `secondaryFields`; the additional-information accessor; and, for `AutoComplete` only, `linkReference`.
|
|
372
|
+
|
|
373
|
+
Finally, wrap whatever was produced in a single full-width container.
|
|
374
|
+
|
|
375
|
+
### Helpers
|
|
376
|
+
|
|
377
|
+
- **Relationship context of a path.** The segment between the first and the last separator: for `@P .Customer.FullName` it is `Customer`. Empty when the path has fewer than two separators.
|
|
378
|
+
- **Additional-information accessor.** Given this component's accessor and the display field, it reads the field metadata of that path's relationship context and returns an object whose `content` is the metadata's `additionalInformation`, or nothing when there is none.
|
|
379
|
+
- **Composite keys.** Read the data page parameters from the field metadata of the reference property. Every parameter whose bound path points back into the reference property itself is a composite key; the key's name is the last segment of that path.
|
|
380
|
+
|
|
381
|
+
### Create-Record Affordance
|
|
382
|
+
|
|
383
|
+
Offer "create new" only when both hold:
|
|
384
|
+
|
|
385
|
+
- the configuration allows it: `allowCreatingRecords` when present, otherwise the form feature `isCreateNewReferenceEnabled` reported by `PCore.getEnvironmentInfo()`;
|
|
386
|
+
- the user may create records of the target class: `PCore.getAccessPrivilege().hasCreateAccess(targetObjectClass)`, and also the form feature when the environment reports form features at all.
|
|
387
|
+
|
|
388
|
+
The create-record function takes the target class and the reference type. For a data reference it opens the create view with `getPConnect().getActionsApi().showDataObjectCreateView(targetObjectClass)`. For a case reference it calls `getPConnect().getActionsApi().createWork(targetObjectClass, ...)` with the case view closed after creation and starting fields that, unless the environment's `disableStartingFieldsForReference` form feature is set, carry the current case's identifier under the add-case-context page property. The presenting picker owns what happens once the new record exists.
|
|
389
|
+
|
|
390
|
+
### Column definitions
|
|
391
|
+
|
|
392
|
+
The name `columns` denotes four incompatible structures across this field type. Identify which one you are holding before reading it.
|
|
393
|
+
|
|
394
|
+
| Shape | Where it appears | How to consume it |
|
|
395
|
+
| ----------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
396
|
+
| Flat column definitions carrying key, display, primary and search flags | produced by this component for the picker presentations | read the flags; see the note on their types below |
|
|
397
|
+
| A list of nested component descriptors | the table and simple-table presentations | pass through unchanged inside the table preset |
|
|
398
|
+
| A columns region nested inside a table preset | the search-and-select presentation | reach through the preset to the region, then render each descriptor |
|
|
399
|
+
| A single entry whose value names the primary-fields view | a list of records before columns are configured | pass through unchanged inside the table preset |
|
|
400
|
+
|
|
401
|
+
The fourth shape is the default state for a list of records: the field points at the referenced class's primary-fields view. Configuring columns explicitly replaces it with the second shape. Both shapes travel to the table unchanged, and **the table expands the primary-fields entry itself**, replacing it with the data page's primary fields as reported by its data view metadata and skipping any already configured explicitly. This component never resolves that view and never alters the column list for a table.
|
|
402
|
+
|
|
403
|
+
**Generated column definitions.** For the picker presentations, derive the definitions yourself, on the raw copy:
|
|
404
|
+
|
|
405
|
+
- Take the display property as the last segment of the raw `displayField`, and the value property as the last segment of `selectionKey` for a list or of the raw `value` for a single record.
|
|
406
|
+
- Determine the reference property: for a list, the raw `pagelistValue` with its marker and leading separator removed; for a single record, the raw `value` with its marker, its leading separator and its final segment removed.
|
|
407
|
+
- Collect the composite keys of that reference property — see Helpers.
|
|
408
|
+
- Emit a display column for the display property: displayed, primary, and usable for search.
|
|
409
|
+
- Emit a key column marked as the key, whose set-property target is `Associated property`. If the value property is among the composite keys, use it. Otherwise use the first composite key when one exists, or the value property when none does, and rewrite the copy's `value` to the property-reference marker followed by a separator, the reference property, a separator and that key.
|
|
410
|
+
- Build a datasource field map on the copy whose `key` and `value` are a separator followed by the last segment of the copy's `value`, and whose `text` is a separator followed by the display property.
|
|
411
|
+
- **For a case reference only,** emit one extra secondary column carrying the mapped name of `pyID`, displayed and searchable.
|
|
412
|
+
- Emit one hidden, non-searchable secondary column for each remaining composite key, whose set-property target is the reference property followed by a separator and that key. On selection, the picker writes the chosen record's value into every such target — without them, a record identified by more than one key is only partly referenced.
|
|
413
|
+
- Record the composite key parameters on the copy as `compositeKeys`, and store the definitions as the copy's `columns`.
|
|
414
|
+
|
|
415
|
+
**A type trap in those definitions:** the displayed, primary, secondary and key flags are the _strings_ `"true"` and `"false"`, whereas the search flag is a real boolean. Every consumer compares the first four against strings. Emit them exactly this way and compare them the same way.
|
|
416
|
+
|
|
417
|
+
### Nested field descriptors
|
|
418
|
+
|
|
419
|
+
Every entry in `secondaryFields`, `columns`, `groupsFields` and the lists inside `presets` is a complete component node carrying its own type and its own configuration. Render each one through the component registry using its own type. Never infer a descriptor's rendering from the parent field.
|
|
54
420
|
|
|
55
|
-
|
|
56
|
-
2. `rawViewMetadata = pConn.getRawMetadata()` — the raw component metadata from Pega config
|
|
57
|
-
3. `refFieldMetadata = pConn.getFieldMetadata(rawViewMetadata?.config?.value?.split('.', 2)[1])`
|
|
58
|
-
4. `propsToUse = { ...pConn.getInheritedProps(), ...componentInputs }` — merged inherited + local inputs
|
|
59
|
-
5. `isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY'`
|
|
60
|
-
6. `canBeChangedInReviewMode = editableInReview && ['Autocomplete', 'Dropdown'].includes(rawViewMetadata.config.componentType)`
|
|
421
|
+
Descriptors are not restricted to simple scalar fields. A descriptor can be another reference field carrying its own data page and its own markers, or a choice field bound to an associated list with its own metadata reference. Treat the list as arbitrary and recursive.
|
|
61
422
|
|
|
62
|
-
|
|
423
|
+
Each descriptor carries its own `label` and `labelOption`, following the same rule as the field label. It may carry `formatter`, naming a display format such as a work-status, email, percentage or phone format; the key is omitted when the format is left at its default. It may carry `additionalDetails`, which takes one of two forms: a display-as-link form carrying an empty parameter object, or an open-view form carrying a modal mode and, as its parameters, a complete view reference. Note that the class recorded on that view reference is the host case's class rather than the referenced record's class, so do not use it to determine the target class — use `targetObjectClass`.
|
|
63
424
|
|
|
64
|
-
|
|
65
|
-
Build a SemanticLink config from rawViewMetadata and call `getPConnect().createComponent({ type: 'SemanticLink', config: {...} })`. Config includes:
|
|
425
|
+
The configuration UI shows at most four descriptors for the combobox presentation and five for cards. The metadata is never truncated, and no current implementation applies the cap — render every configured descriptor.
|
|
66
426
|
|
|
67
|
-
|
|
68
|
-
- `value` → `caseID`
|
|
69
|
-
- `resourceParams: { workID: value }`, `resourcePayload: { caseClassName: caseClass }`
|
|
70
|
-
- `displayMode`, `referenceType`, `hideLabel`, `dataRelationshipContext`
|
|
427
|
+
### View references and deferred loading
|
|
71
428
|
|
|
72
|
-
|
|
73
|
-
Render `<SingleReferenceReadonly>` with config from `rawViewMetadata.config`, passing:
|
|
429
|
+
Four different mechanisms reference another view, and they differ in whether the referenced view arrives with the payload.
|
|
74
430
|
|
|
75
|
-
|
|
431
|
+
| Mechanism | Referenced view delivered? | Resolution |
|
|
432
|
+
| ----------------------------------------- | ------------------------------------------- | ---------------------------------- |
|
|
433
|
+
| `detailsView` | yes, together with everything it references | eagerly, from the payload |
|
|
434
|
+
| A view reference inside `columns` | yes | eagerly, from the payload |
|
|
435
|
+
| A deferred-load child node | no | on demand, by name |
|
|
436
|
+
| An open-view entry in `additionalDetails` | no | lazily, when the user activates it |
|
|
76
437
|
|
|
77
|
-
|
|
438
|
+
The search-and-select presentation is the only one that gives this component children: one deferred-load node per configured search category, each naming a generated view that holds that category's data page, search groups and columns. **Those children must be rendered.** Dropping them leaves the presentation with nothing to display, and nothing reports an error.
|
|
78
439
|
|
|
79
|
-
|
|
440
|
+
### Selection and commit
|
|
80
441
|
|
|
81
|
-
|
|
82
|
-
- Set `rawViewMetadata.config.deferDatasource = true`
|
|
83
|
-
- Set `rawViewMetadata.config.listType = 'datapage'`
|
|
84
|
-
- Set default placeholder `'@L Select...'` for Dropdown/AutoComplete if missing
|
|
442
|
+
The presenting child writes the selection into the case itself — each presenting component's skill says how. This component's record-change handler runs afterwards, and every presenting child that can change the selection must receive it. When called, it does the following in order.
|
|
85
443
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
444
|
+
1. Build refresh options carrying an automatic-detection flag set to true and, as the property name, the raw `value`.
|
|
445
|
+
2. Unless the field is editable in review and the surrounding view reports a current tab view — or unless the implicit-refresh default for data references, read from `PCore.getFieldDefaultUtils()`, is set — and only when this node carries a view name, refresh the case view with `getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pageReference, refreshOptions)`. The case key comes from `getPConnect().getCaseInfo().getKey()`, and the page reference is `getPConnect().getPageReference()` with its `caseInfo.content` prefix removed.
|
|
446
|
+
3. Read the selected value from the event, accepting either an identifier carried on the event or a value carried on its target.
|
|
447
|
+
4. Determine the property to write: for the multiple-selection table presentation, the stripped selection list; otherwise the raw `value`. Resolve either with `PCore.getAnnotationUtils().getPropertyName(...)` rather than trimming the marker by hand.
|
|
448
|
+
5. Only when a value was selected, the field is editable in review, and the surrounding view is display-only, persist the change directly: take an edit lock on the case, build a nested commit object by walking first the page reference segments and then the property segments, send it with the lock's entity tag and the current context, and afterwards update the parent's last-update time and the related context's entity tag from the response.
|
|
89
449
|
|
|
90
|
-
|
|
450
|
+
### Re-render optimization
|
|
91
451
|
|
|
92
|
-
|
|
452
|
+
Re-create the presenting child only when something that affects it has changed: the raw datasource source, the resolved parameters, the fetched option list, the resolved required and disabled states, and the current page reference. Express this with whatever change-detection mechanism the target framework offers — the comparison list is the contract, not the mechanism.
|
|
93
453
|
|
|
94
|
-
|
|
454
|
+
## Worked Traces
|
|
95
455
|
|
|
96
|
-
|
|
456
|
+
Three end-to-end walkthroughs, built from real configuration. Each names the raw keys, what is derived, and what the created child receives.
|
|
97
457
|
|
|
98
|
-
|
|
99
|
-
2. If `!canBeChangedInReviewMode || !pConn.getValue('__currentPageTabViewName')`: call `getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pgRef, refreshOptions)`.
|
|
100
|
-
3. Extract `propValue = event?.id || event?.target?.value`.
|
|
101
|
-
4. For multi mode (`SimpleTableSelect`): `propName = getPropertyName(rawViewMetadata.config.selectionList)`, else `propName = getPropertyName(rawViewMetadata.config.value)`.
|
|
102
|
-
5. If `propValue && canBeChangedInReviewMode && isDisplayModeEnabled`:
|
|
103
|
-
- Get edit lock via `PCore.getCaseUtils().getCaseEditLock(caseKey, '')`
|
|
104
|
-
- Build commit data from page reference path
|
|
105
|
-
- Call `PCore.getCaseUtils().updateCaseEditFieldsData(...)` to persist the change
|
|
106
|
-
- Update container's last update time and etag
|
|
458
|
+
**Single record, combobox presentation.** Raw configuration: `mode` `single`, `componentType` `Combobox`, `value` `@P .Account.pyGUID`, `contextPage` a property-reference path, `displayField` `@P .Account.ActivityDate`, `referenceList` `D_AccountList`, `allowCreatingRecords` true, `detailsView` `pyReview`, `targetObjectType` `data`, and four `secondaryFields` descriptors — Description, Globally unique ID and Status as text, and Amount as currency.
|
|
107
459
|
|
|
108
|
-
|
|
460
|
+
1. The presentation normalises to `AutoComplete`.
|
|
461
|
+
2. The reference property is `Account`, the display property `ActivityDate`, and the value property `pyGUID`. With no composite keys, the key stays `pyGUID` and `value` is unchanged.
|
|
462
|
+
3. Generated columns: a display column for `ActivityDate`, and a key column for `pyGUID` targeting `Associated property`. The datasource field map is `.pyGUID`, `.ActivityDate`, `.pyGUID`.
|
|
463
|
+
4. The datasource metadata is named `D_AccountList`, has empty parameters, and gives `.ActivityDate` as the display text and `.pyGUID` as the value.
|
|
464
|
+
5. The placeholder becomes `@L Select...`, and creation is offered if the user may create records of the class.
|
|
465
|
+
6. Create `AutoComplete` with that configuration, `columnsFormatter` holding the four descriptors, and the record-change handler.
|
|
109
466
|
|
|
110
|
-
|
|
467
|
+
The result: an option per data page row, labelled with its activity date, with a second line reading `Description: … · Globally unique ID: … · Status: … · Amount: $777.33`, and "Create new" at the foot of the list. Choosing one writes its `pyGUID` into `.Account.pyGUID`. Had the resolved `displayField` been used instead, every label would be empty.
|
|
468
|
+
|
|
469
|
+
**List of records, simple-table presentation.** Raw configuration: `mode` `multi`, `componentType` `SimpleTable`, `pagelistValue` `@P .Activities`, `selectionKey` `.pyGUID`, `referenceList` `D_ActivityList`, `displayField` `.ActivityDate`, and four `columns` descriptors — Confirmation Number, Create System ID, Description, and Amount as currency. There is no `value` and no `contextPage`.
|
|
470
|
+
|
|
471
|
+
1. Build the table preset around the four descriptors, unchanged.
|
|
472
|
+
2. Create `SimpleTableSelect` with `displayAs` `simpleTable`, the preset, `referenceList` `D_ActivityList`, `selectionMode` `multi`, `selectionList` and `dataRelationshipContext` both `.Activities`, `readonlyContextList` `@P .Activities`, the raw parameters, and the record-change handler.
|
|
473
|
+
|
|
474
|
+
The result: exactly four columns in configured order — including Create System ID, whose property begins with `px` — a checkbox on every row, and the rows already in the list shown as checked. `displayField` plays no part in a table.
|
|
475
|
+
|
|
476
|
+
**List of records, read-only link presentation.** `mode` `readonly-multi` and `componentType` `SemanticLink`, so the first branch matches. Render `MultiReferenceReadOnly` with `readonlyContextList` and `referenceList` both set to the raw `pagelistValue`, `primaryField` set to the stripped `displayField`, `selectionKey`, and the table preset. This is the one read-only presentation that still carries a column list, because a list of records needs columns to render; the single-record read-only presentation does not.
|
|
111
477
|
|
|
112
478
|
## Display Mode Rendering
|
|
113
479
|
|
|
114
|
-
Display mode
|
|
480
|
+
Display mode reaches this component from the surrounding view, and it is not the same thing as the read-only values of `mode`. Either can force a read-only presentation.
|
|
115
481
|
|
|
116
|
-
|
|
482
|
+
A display-only value takes the second branch of the decision tree for every presentation except the link one, which is handled first. A read-only field in a view that is _not_ display-only is coerced first: a multi-select presentation becomes the link presentation, and every other presentation switches the view into display-only so the same branch handles it. Implement that coercion before the decision tree, or read-only fields will fall through to their editable presentations.
|
|
483
|
+
|
|
484
|
+
Once a read-only branch is taken, the resolved display mode is handed to the presenting component, which renders it. This component adds nothing of its own.
|
|
117
485
|
|
|
118
|
-
|
|
486
|
+
## Visual Specifications
|
|
119
487
|
|
|
120
|
-
|
|
488
|
+
This component contributes only a single full-width container holding one child. Everything visible is produced by the presenting component.
|
|
121
489
|
|
|
122
|
-
|
|
490
|
+
| Property | Value |
|
|
491
|
+
| ---------- | ------------------------------------------------ |
|
|
492
|
+
| Container | Full width, single column, no padding of its own |
|
|
493
|
+
| Appearance | Entirely delegated to the presenting component |
|
|
123
494
|
|
|
124
495
|
## Edge Cases & Special Logic
|
|
125
496
|
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
497
|
+
- **A list of records has no single-record binding.** Any lookup that reads the single-record binding must be guarded, or it will yield nothing for every list-of-records field.
|
|
498
|
+
- **The combobox presentation is not a component.** Map it before anything else, or the lookup fails.
|
|
499
|
+
- **Stale keys look valid.** A key from a previous presentation carries a real, plausible value. Decide from `mode` and `componentType`.
|
|
500
|
+
- **Both inline settings can be present at once,** one active and one stale, because they come from different presentations and are cleared at different times. Choose the one belonging to the active presentation: the card setting for cards, the horizontal setting for checkbox groups.
|
|
501
|
+
- **Empty means different things per key type.** Lists emit an empty list; single-value settings at their default emit no key; a required control that has not been filled in also emits no key.
|
|
502
|
+
- **Placeholder paths collide.** Two descriptors of the same type can share one identical bound path in preview metadata. Use the label, never the path, to tell them apart.
|
|
503
|
+
- **The generated search category view reports single selection** even for a list field. Derive selection behaviour from `mode`.
|
|
504
|
+
- **A missing registry entry degrades silently.** It renders a placeholder rather than raising, so an omitted dependency looks like a styling problem.
|
|
505
|
+
- **The configuration is read from the component's own raw metadata,** which several presentations then modify before handing it on. Derive a fresh configuration for the child from a copy rather than modifying shared metadata in place, so repeated renders stay consistent.
|
|
506
|
+
- **A resolved property path is a value, not a name.** The resolved `displayField` of a single record is the selected record's display text, and an empty string before anything is selected. Build nothing structural from it.
|
|
507
|
+
- **A child rendered with this component's accessor reads this component's configuration.** It finds none of the structure it expects and renders empty, with no error. Create every child with `createComponent` except the three named exceptions.
|
|
508
|
+
|
|
509
|
+
## Implementation Status
|
|
510
|
+
|
|
511
|
+
Some settings the configuration UI can produce are not currently honoured anywhere, and some behaviours of the current implementation are defects. Both are listed here so a generated component **implements them correctly** rather than reproducing the gap. The decision tree above already specifies the corrected behaviour where one is given.
|
|
512
|
+
|
|
513
|
+
| Setting or behaviour | Current behaviour | What a generated component should do |
|
|
514
|
+
| --------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
515
|
+
| Display-only single record | Link text is filled in only for the picker presentations, so others show `--` | Build the full link configuration for every presentation — decision tree branch 2 |
|
|
516
|
+
| Record-change handler | Given to the pickers only | Give it to every child that can change the selection, including tables, cards and checkbox groups |
|
|
517
|
+
| Composite keys on a picker | The generated key and hidden composite-key columns are replaced by the picker | Keep them, and write every set-property target on selection — see the AutoComplete skill |
|
|
518
|
+
| Parameters inside datasource metadata | Consumers expect name/value pairs but receive a flat map, so parameters are lost | Accept both shapes — see the AutoComplete skill |
|
|
519
|
+
| `hideFieldLabels` on the combobox | Not read; secondary labels always show | Omit the label from each secondary entry |
|
|
520
|
+
| `inlineDisplay`, `imageSize`, `imagePosition` | Not read by the card presentation, which uses a fixed grid and a fixed image size | Lay cards out inline when set; size and place the image as configured |
|
|
521
|
+
| `linkBehavior` | Not read. The activation behaviour is fixed | Map each value to a distinct behaviour: same view, new tab, or preview |
|
|
522
|
+
| `linkReference` | Honoured on the read-only path only | Honour it everywhere a reference is rendered as a link |
|
|
523
|
+
| `detailsView` | Not read, though the named view is delivered | Resolve the named view and present the selected record's details beneath the picker |
|
|
524
|
+
| `additionalDetails` | Only the display-as-link form is honoured, and only in one table | Honour both forms, including the open-view form and its modal mode |
|
|
525
|
+
| `formatter` on a descriptor | Honoured only by the decimal field | Apply the named format wherever the descriptor is rendered |
|
|
526
|
+
| `Map` presentation | Not registered | Present the referenced records on a map, using the configured location property |
|
|
527
|
+
|
|
528
|
+
**Out of scope, deliberately.** Filter by, Group by, Sort by, Row density, Max height, Column to take remaining width, and Allow user edit column visibility apply only to a full table. Both table presentations render as one simple table, so ignore these settings and their keys — including `filterExpression`, `toggleFieldVisibility` and `fillAvailableSpace`. Do not implement them. The simple table still keeps its own interactive sort and its own bounded, scrollable body, which are part of its skill rather than configuration.
|
|
131
529
|
|
|
132
530
|
## Dependencies
|
|
133
531
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
532
|
+
> Every registry dependency must be generated and registered before this component can render — see Registry Dependency Prerequisite.
|
|
533
|
+
|
|
534
|
+
- The project's component registry, resolving each presenting component named in the prerequisite, plus the type of every nested descriptor present in the metadata.
|
|
535
|
+
- Local helpers for deriving column definitions, extracting a relationship context from a property path, collecting composite keys, and creating a new referenced record.
|
|
536
|
+
- The target framework's change-detection mechanism, for skipping redundant re-renders.
|
|
537
|
+
- The Pega Platform APIs listed below.
|
|
538
|
+
|
|
539
|
+
## Pega Platform APIs
|
|
540
|
+
|
|
541
|
+
All of these are reached through the global `PCore` object, which the SDK runtime installs before any component renders, or through the accessor returned by `getPConnect()`. Never import them from a package — read them at the point of use.
|
|
542
|
+
|
|
543
|
+
**`getPConnect().getRawMetadata()`** — takes nothing. Returns this node's metadata before resolution; its `config` holds every configured key with markers intact. The source of every structural key — see Raw and Resolved Configuration.
|
|
544
|
+
|
|
545
|
+
**`getPConnect().createComponent(meta)`** — takes an object holding a registry `type` and a `config`. Returns a rendered child whose own accessor has that configuration as its component configuration, resolved against this node's context. The only correct way to hand a presenting component its configuration.
|
|
546
|
+
|
|
547
|
+
**`getPConnect().getFieldMetadata(propertyName)`** — takes a bare property name. Returns that property's field metadata: record descriptors, `additionalInformation`, and a `datasource` whose `parameters` define the composite keys. Returns nothing for a wrong name, so derive the name exactly as the main logic describes.
|
|
548
|
+
|
|
549
|
+
**`getPConnect().getInheritedProps()`** — returns the inputs inherited from the surrounding view, such as a label. Merge them underneath this component's own resolved inputs.
|
|
550
|
+
|
|
551
|
+
**`getPConnect().getActionsApi()`** — returns the actions interface. This component uses `refreshCaseView(caseKey, viewName, pageReference, options)` after a selection, and the create-record function uses `showDataObjectCreateView(className)` and `createWork(className, options)`.
|
|
552
|
+
|
|
553
|
+
**`PCore.getConstants()`** — returns an object of platform constants. Read the list selection modes from it rather than writing the selection strings by hand.
|
|
554
|
+
|
|
555
|
+
**`PCore.getAnnotationUtils().getPropertyName(value)`** — takes a marker-prefixed property path and returns the bare property name. Use it wherever a stored path must become a property name, instead of trimming the marker yourself.
|
|
556
|
+
|
|
557
|
+
**`PCore.getDataApiUtils().getData(dataPageName, payload, context)`** — takes the data page rule name, a payload carrying the data page's parameters, and the current context name. Returns a promise resolving to a response whose rows are at the nested data array. Used to fetch the option list for the checkbox-group presentation when the data page declares parameters; guard against a null row set.
|
|
558
|
+
|
|
559
|
+
**`PCore.getCaseUtils().getCaseEditLock(caseKey, '')`** — takes the case key and an empty string. Returns a promise resolving to a response whose headers carry an entity tag. Required before committing a change from a display-only view.
|
|
560
|
+
|
|
561
|
+
**`PCore.getCaseUtils().updateCaseEditFieldsData(caseKey, data, etag, contextName)`** — takes the case key, an object keyed by that case key whose value is the nested commit data, the entity tag from the edit lock, and the current context name. Returns a promise resolving to a response carrying the updated case information and a fresh entity tag.
|
|
562
|
+
|
|
563
|
+
**`PCore.getContainerUtils().updateParentLastUpdateTime(contextName, lastUpdateTime)`** and **`PCore.getContainerUtils().updateRelatedContextEtag(contextName, etag)`** — take the current context name together with the last-update time and the entity tag from the commit response. Call both after a successful commit, or the surrounding container will hold stale data.
|
|
564
|
+
|
|
565
|
+
**`PCore.getAccessPrivilege().hasCreateAccess(className)`** — takes the target class name and returns whether the current user may create instances of it. Combine it with the configured setting before offering a create affordance.
|
|
566
|
+
|
|
567
|
+
**`PCore.getEnvironmentInfo()`** — returns environment information. Two features matter here: whether creating a new referenced record is enabled, and whether starting fields are disabled for references.
|
|
568
|
+
|
|
569
|
+
**`PCore.getFieldDefaultUtils()`** — returns field defaults. Read the implicit-refresh default for this field type to decide whether a selection should always refresh the view.
|
|
570
|
+
|
|
571
|
+
**`PCore.getMetadataUtils().resolveView(viewName)`** — takes a view name and returns that view's metadata. Use it to resolve the view named by `detailsView`. Never use it to expand a primary-fields entry in `columns` — the table does that from the data page's own metadata.
|
|
572
|
+
|
|
573
|
+
The view's own change handler, the case key, the page reference and the context name all come from the PConnect accessor rather than from `PCore`.
|
|
138
574
|
|
|
139
575
|
## Design System Mapping
|
|
140
576
|
|
|
141
|
-
**UI control type:**
|
|
577
|
+
**UI control type:** Reference picker — an orchestrator that delegates to a picker, table, card list, search form, or link.
|
|
142
578
|
|
|
143
579
|
When implementing in a specific design system, map the following:
|
|
144
580
|
|
|
145
|
-
- **
|
|
146
|
-
- **
|
|
147
|
-
- **
|
|
148
|
-
- **
|
|
149
|
-
- **
|
|
581
|
+
- **Combobox presentation** → the design system's typeahead or combobox, for a single record; its multi-select equivalent with removable tokens for a list
|
|
582
|
+
- **Dropdown presentation** → the design system's select control
|
|
583
|
+
- **Table and simple-table presentations** → a data table with row selection: a single-choice control per row for one record, a multiple-choice control per row for a list
|
|
584
|
+
- **Checkbox-group presentation** → a group of multiple-choice controls, laid out horizontally when the horizontal setting is on
|
|
585
|
+
- **Card presentation** → a selectable card or tile, with the image placed according to the imagery setting and the card laid out inline when that setting is on
|
|
586
|
+
- **Search-and-select presentation** → a search form with one tab per configured category, each containing its search criteria and a result table
|
|
587
|
+
- **Read-only link presentation** → a hyperlink for a single record, or a list or table of links for a list; plain text when linking is switched off
|
|
588
|
+
- **Display-only presentation** → the design system's read-only value display
|
|
589
|
+
- **Container** → a plain full-width wrapper; add no styling of your own
|
|
590
|
+
|
|
591
|
+
## Generation Self-Check
|
|
592
|
+
|
|
593
|
+
Before considering the component finished, confirm each of the following.
|
|
594
|
+
|
|
595
|
+
- Every value of `componentType` in the matrix is handled, and none is passed to the registry unchanged.
|
|
596
|
+
- All four values of `mode` are handled, and the read-only coercion runs before the decision tree.
|
|
597
|
+
- Every structural key is read from the raw configuration, and no column, datasource or link text is built from a resolved property value.
|
|
598
|
+
- Every presenting child is built with `createComponent`, except the two read-only templates and the search form.
|
|
599
|
+
- The single-record binding is never read for a list of records, and the list binding is never read for a single record.
|
|
600
|
+
- `columns` reaches the table unchanged inside a table preset whose only region is named `Columns`, in either shape.
|
|
601
|
+
- The table shows exactly the configured columns, in configured order, with configured labels and formats.
|
|
602
|
+
- The Table and Simple table presentations produce the same child, and no filter, group, sort, density or column-visibility setting is read.
|
|
603
|
+
- A combobox option carries a non-empty label from the display property, and a secondary line rendered from the configured descriptors.
|
|
604
|
+
- A display-only single record shows its display text for every presentation, never `--`.
|
|
605
|
+
- Nested descriptors are rendered through the registry using their own type, with their own label, format and additional-details settings.
|
|
606
|
+
- The component's children are rendered for the search-and-select presentation.
|
|
607
|
+
- Keys belonging to other presentations are ignored, and no decision is made from key presence alone.
|
|
608
|
+
- The data page name comes from the raw `referenceList`, and parameters are forwarded as each branch specifies, with empty values treated as absent.
|
|
609
|
+
- The generated column flags use strings for the displayed, primary, secondary and key flags and a boolean for the search flag.
|
|
610
|
+
- A case reference contributes its extra case-id column, and a data reference does not.
|
|
611
|
+
- Every child that can change the selection receives the record-change handler.
|
|
612
|
+
- Every registry key the component reaches for is registered, including the types of all nested descriptors.
|