@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.
Files changed (48) hide show
  1. package/package.json +1 -1
  2. package/templates/angular-sdk-reference/angular.json +2 -1
  3. package/templates/angular-sdk-reference/package.json +1 -0
  4. package/templates/angular-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
  5. package/templates/angular-sdk-reference/src/app/app.component.ts +232 -15
  6. package/templates/angular-sdk-reference/src/components/component-map.ts +90 -0
  7. package/templates/angular-sdk-reference/src/components/fields/auto-complete/auto-complete.component.ts +267 -0
  8. package/templates/angular-sdk-reference/src/components/fields/checkbox/checkbox.component.ts +84 -0
  9. package/templates/angular-sdk-reference/src/components/fields/currency/currency.component.ts +97 -0
  10. package/templates/angular-sdk-reference/src/components/fields/date-input/date-input.component.ts +88 -0
  11. package/templates/angular-sdk-reference/src/components/fields/dropdown/dropdown.component.ts +101 -0
  12. package/templates/angular-sdk-reference/src/components/fields/email/email.component.ts +91 -0
  13. package/templates/angular-sdk-reference/src/components/fields/integer/integer.component.ts +93 -0
  14. package/templates/angular-sdk-reference/src/components/fields/phone/phone.component.ts +91 -0
  15. package/templates/angular-sdk-reference/src/components/fields/radio-buttons/radio-buttons.component.ts +102 -0
  16. package/templates/angular-sdk-reference/src/components/fields/text-area/text-area.component.ts +98 -0
  17. package/templates/angular-sdk-reference/src/components/fields/text-input/text-input.component.ts +97 -0
  18. package/templates/angular-sdk-reference/src/components/fields/url-input/url-input.component.ts +94 -0
  19. package/templates/angular-sdk-reference/src/components/infra/assignment/assignment.component.ts +206 -0
  20. package/templates/angular-sdk-reference/src/components/infra/case-summary/case-summary.component.ts +76 -0
  21. package/templates/angular-sdk-reference/src/components/infra/case-view/case-view.component.ts +114 -0
  22. package/templates/angular-sdk-reference/src/components/infra/flow-container/flow-container.component.ts +411 -0
  23. package/templates/angular-sdk-reference/src/components/infra/reference/reference.component.ts +158 -0
  24. package/templates/angular-sdk-reference/src/components/infra/region/region.component.ts +39 -0
  25. package/templates/angular-sdk-reference/src/components/infra/root-container/root-container.component.ts +193 -0
  26. package/templates/angular-sdk-reference/src/components/infra/stages/stages.component.ts +78 -0
  27. package/templates/angular-sdk-reference/src/components/infra/view/view.component.ts +139 -0
  28. package/templates/angular-sdk-reference/src/components/infra/view-container/view-container.component.ts +191 -0
  29. package/templates/angular-sdk-reference/src/components/templates/default-form/default-form.component.ts +101 -0
  30. package/templates/angular-sdk-reference/src/components/templates/narrow-wide/narrow-wide.component.ts +37 -0
  31. package/templates/angular-sdk-reference/src/components/templates/one-column/one-column.component.ts +37 -0
  32. package/templates/angular-sdk-reference/src/components/templates/two-column/two-column.component.ts +37 -0
  33. package/templates/angular-sdk-reference/src/components/templates/wide-narrow/wide-narrow.component.ts +37 -0
  34. package/templates/angular-sdk-reference/src/helpers/event-utils.ts +18 -0
  35. package/templates/angular-sdk-reference/src/helpers/utils.ts +38 -0
  36. package/templates/angular-sdk-reference/src/helpers/versionHelpers.ts +14 -0
  37. package/templates/angular-sdk-reference/tsconfig.json +5 -2
  38. package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +11 -4
  39. package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +7 -0
  40. package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +3 -1
  41. package/templates/react-sdk-reference/.ai-common/skills/field-components.md +75 -29
  42. package/templates/react-sdk-reference/.ai-common/skills/field-skills/AutoComplete.md +133 -101
  43. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedData.md +385 -0
  44. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedDataMulti.md +506 -0
  45. package/templates/react-sdk-reference/.ai-common/skills/field-skills/ObjectReference.md +549 -86
  46. package/templates/react-sdk-reference/.ai-common/skills/field-skills/UserReference.md +181 -83
  47. package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListView.md +125 -153
  48. package/templates/react-sdk-reference/.ai-common/skills/template-skills/SimpleTable.md +90 -81
@@ -1,56 +1,51 @@
1
1
  # Skill: ListView
2
2
 
3
- Full-featured list view template. Renders a data table with sorting, pagination, global search, single/multi selection, column menu, and filter dialog.
3
+ Data table template. Renders the rows of a data page as a table with configured columns, sorting, paging, search, and single or multiple selection.
4
4
 
5
5
  > **Prerequisite skill:** [`template-components.md`](../template-components.md) — covers architecture, child rendering patterns, and registration conventions common to ALL template components.
6
6
 
7
7
  ---
8
8
 
9
- > ⚠️ **CRITICAL — `referenceList` is a STRING, not an array**
9
+ > ⚠️ **CRITICAL — `referenceList` names a data page; it is not a list of rows**
10
10
  >
11
- > The `referenceList` prop is a **data page reference string** (e.g., `".D_pyMyWorkList.pxResults"`) — NOT an array of data rows. You MUST:
12
- >
13
- > 1. Check `typeof referenceList === 'string'` before using it
14
- > 2. Call `PCore.getDataApiUtils().getData(referenceList, payload)` to fetch actual row data
15
- > 3. Initialize row state as empty array
16
- > 4. NEVER put `referenceList` directly into state or call `.filter()` on it
17
- >
18
- > Do NOT initialize row state directly from `referenceList` (e.g. as the initial state value) — this crashes later with "rows.filter is not a function" because `referenceList` is a string, not an array. Instead, initialize rows as an empty array and populate them inside a lifecycle effect keyed on `referenceList`: if `referenceList` happens to already be an array, use it directly; otherwise resolve a `dataRef` from `referenceList` (falling back to `dataPageName`) and, when present, call `PCore.getDataApiUtils().getData(dataRef, payload ?? {})`, storing the resolved rows from `response?.data?.data ?? response?.data?.pxResults ?? []` on success, or an empty array on failure.
11
+ > `referenceList` holds the **name of a data page**, such as `D_pyMyWorkList`. It is never the rows themselves. Start with an empty row list, fetch the rows from the data page as described under Data Fetching, and only then populate the table. Treating the name as a list — storing it as the rows, or filtering it — fails as soon as the table first renders.
19
12
 
20
13
  ---
21
14
 
22
- > ⚠️ **CRITICAL — Column definitions MUST come from PConnect presets metadata**
23
- >
24
- > The table must render ONLY the columns configured in the Pega view metadata — NOT all fields from the raw data response. Raw responses contain 20+ internal fields (`pzInsKey`, `pxRefObjectClass`, `pyAssignmentStatus`, etc.) that should never be shown.
15
+ > ⚠️ **CRITICAL — Columns come from this table's own presets, in configured order, and nowhere else**
25
16
  >
26
- > **How to extract configured columns:**
17
+ > The table shows exactly the columns configured in the view — no more, no fewer, in the configured order, with the configured labels. It never looks at the data rows to decide what to show.
27
18
  >
28
- > 1. Get column fields from presets: `getPConnect().getComponentConfig().presets[0].children[0].children`
29
- > 2. Get field definitions (labels, types) from metadata: `PCore.getAnalyticsUtils().getDataViewMetadata(referenceList, false)`
30
- > 3. Map each preset column to its field definition to build `{id, label, type, displayAsLink}` headers
19
+ > Work out the columns in this order:
31
20
  >
32
- > Do NOT derive columns by taking `Object.keys(rows[0])` and mapping each key to `{ id: key, label: key }` — that shows every raw data key, including internal fields like `pzInsKey` and `pxRefObjectClass`. Instead, extract the configured columns from PConnect presets plus the analytics metadata: read `componentConfig = getPConnect().getComponentConfig()`; read `columnFields = componentConfig.presets[0].children[0].children`; await `metaResponse = PCore.getAnalyticsUtils().getDataViewMetadata(referenceList, false)` and take `fieldDefs = metaResponse?.data?.fields ?? []`; then map each entry in `columnFields` (with its index) to a column definition: strip the annotation prefix from `field.config.value` (format `"@P .pyID"`, take the substring after the first space, then strip a leading `.` if present) to get `fieldId`; read `additionalDetails` from `field.config` (default `{}`) and compute `displayAsLink` as true when `additionalDetails.type === 'DISPLAY_LINK'` or when `field.config.displayAsLink` is set; build `{ id: fieldId, label: fieldDefs[index]?.label ?? field.config.label ?? fieldId, type: field.type, displayAsLink, classID: fieldDefs.find(f => f.name === fieldId)?.classID }`.
21
+ > 1. **Read the configured fields** from this table's own configuration: the children of the first region of the first preset, in the raw configuration returned by `getPConnect().getRawMetadata().config`. The same list is reachable through `getPConnect().getComponentConfig()`. The presets are put there by whoever created this table — a reference field or a list page — through `getPConnect().createComponent`. **If there are no presets, the parent wired the table wrongly.** Render nothing, report the missing presets, and never guess columns.
22
+ > 2. **Fetch the metadata** with `PCore.getAnalyticsUtils().getDataViewMetadata(referenceList, showDynamicFields)`. Its `data` carries `fields`, `classID`, `isQueryable` and `primaryFields`. Also fetch the report columns with `PCore.getAnalyticsUtils().getFieldsForDataSource(referenceList, false, contextName)`, treating a failure as an empty list; each entry names a field in `pyFieldName`.
23
+ > 3. **Expand a primary-fields entry.** A configured entry whose value is `pyPrimaryFields`, or its namespace-qualified form, stands for the data page's primary fields. Replace it, in place, with one descriptor for each name in `primaryFields` that is not already configured, built from the matching metadata field. When there are no primary fields, simply remove the entry.
24
+ > 4. **Build one column definition per configured field**, in order:
25
+ > - **Name:** the field's value with its marker and following space removed, then its leading separator — `@P .ConfirmationNumber` becomes `ConfirmationNumber`. The name is the row key for the cell.
26
+ > - **Label:** a field-label marker (`@FL`) is resolved by looking the property up with `PCore.getMetadataUtils().getPropertyMetadata(propertyName, classID)` and taking its label or caption. Localize that with `PCore.getLocaleUtils().getLocaleValue(label, localeKey, bundle)`, where the locale key is the property's defining class — falling back to its class, then the metadata's class — joined to the property name by a separator, and the bundle is `PCore.getLocaleUtils().FIELD_LABELS_BUNDLE_KEY`. A localization marker (`@L `) is removed. Plain text is used as it is. Then localize the header once more with `PCore.getLocaleUtils().getLocaleValue(label, localeReference)`.
27
+ > - **Type:** the descriptor's own `type`. It decides the cell format and whether the column is numeric.
28
+ > - **Shown:** the descriptor's `show` flag, default true, and never when the descriptor is marked hidden.
29
+ > 5. **Extra fields are for the query only.** Metadata fields that are not configured but appear in the report columns are added to the query's select list when the data page is queryable, so that dependent data arrives. They are never displayed.
33
30
  >
34
- > **Key points:**
35
- >
36
- > - `field.config.value` has format `"@P .pyID"` — strip annotation prefix to get field name
37
- > - `fieldDefs[index].label` provides the localized display label
38
- > - `displayAsLink` determines if the cell renders as a clickable navigation link
39
- > - If `presets` is unavailable (fallback), use first ~6 fields from `fieldDefs` — NEVER use raw data keys
31
+ > Never filter configured columns by name or prefix: `px` and `py` properties such as `pxCreateSystemID` are valid, configured columns. Never map a column to a metadata field by position — the metadata's field order has nothing to do with the configured order.
40
32
 
41
33
  ---
42
34
 
43
- > ⚠️ **CRITICAL — Data fetching differs by `bInForm`**
35
+ > ⚠️ **CRITICAL — Data Fetching depends on whether the table sits inside a form**
36
+ >
37
+ > `bInForm` defaults to true.
44
38
  >
45
- > The data API to call depends on whether the ListView is inside a form or on a standalone page: for page-level use (`bInForm = false`, e.g. a worklist landing page), await `PCore.getDataApiUtils().getData(referenceList, payload ?? {})` and read rows from `result?.data?.data ?? []`; for form-level use (`bInForm = true`, e.g. an embedded list in a case form), resolve `context = getPConnect().getContextName()`, await `PCore.getDataPageUtils().getDataAsync(referenceList, context, parameters, null, query)`, and read rows from `result?.data ?? []`.
39
+ > - **Inside a form** (`bInForm` true — a reference field, an embedded list): call `PCore.getDataPageUtils().getDataAsync(referenceList, contextName, parameters, paging, query)`, with the accessor's context name, the parameters, no paging, and the query described below. The rows are at the response's `data`.
40
+ > - **On a page** (`bInForm` false — a worklist or landing page): call `PCore.getDataApiUtils().getData(referenceList, payload)`, passing the payload input or an empty one. The rows are at the response's `data.data`.
46
41
  >
47
- > Using the wrong API will return empty data or fail silently.
42
+ > When the data page is queryable, the query's select list names every column definition, the extra fields, any fields needed for links, and the composite keys. When it is not, send no query. Calling the wrong API returns nothing and fails silently. On failure, show an empty table.
48
43
 
49
44
  ---
50
45
 
51
46
  ## Component Purpose
52
47
 
53
- The primary data table component. Renders a sortable, paginated, filterable, and selectable table from a PConnect data source. Supports both standalone page use (`bInForm: false`) and embedded form use (`bInForm: true`). Columns are configurable, and the table supports row-level selection with callback.
48
+ The project's data table. It shows the rows of one data page with the columns its creator configured, and lets the user sort, page through, search and — when a selection mode is given — select rows. It is used both inside forms, where a reference field or an embedded list creates it, and on pages such as worklists.
54
49
 
55
50
  ## Pega Metadata
56
51
 
@@ -60,175 +55,152 @@ The primary data table component. Renders a sortable, paginated, filterable, and
60
55
 
61
56
  ## Inputs
62
57
 
63
- | Prop | Type | Required | Description |
64
- | ----------------------- | ---------- | -------- | ----------------------------------------------------------------------------- |
65
- | `bInForm` | `boolean` | No | Whether rendered inside a form (affects toolbar and padding). Default `false` |
66
- | `selectionMode` | `string` | No | `'single'` (radio) or `'multi'` (checkbox) or absent (no selection) |
67
- | `dataPageName` | `string` | No | Name of data page to fetch records from |
68
- | `referenceList` | `array` | No | In-memory data array (used when data is already available) |
69
- | `compositeKeys` | `object` | No | Key fields for unique row identification |
70
- | `columns` | `array` | No | Column definition objects `{ fieldName, label, sortable, filterable }` |
71
- | `additionalTableConfig` | `object` | No | Extra config merged with column/sort/filter settings |
72
- | `isSearchable` | `boolean` | No | Whether global search input is shown |
73
- | `payload` | `object` | No | Query payload for data page requests |
74
- | `getPConnect` | `function` | Yes | PConnect getter |
58
+ Most inputs arrive through this component's own configuration, set by whoever created it with `getPConnect().createComponent`. The column list is never an input — it lives in the presets of that configuration.
59
+
60
+ | Name | Type | Default | Description |
61
+ | --------------------- | -------------------- | ------- | --------------------------------------------------------------------------------------- |
62
+ | `getPConnect` | accessor | — | The PConnect accessor |
63
+ | `referenceList` | `string` | — | The data page name |
64
+ | `bInForm` | `boolean` (optional) | `true` | Inside a form, or on a page. Chooses the data API and tightens the layout |
65
+ | `parameters` | `object` (optional) | — | Data page parameters, a flat map from name to value |
66
+ | `payload` | `object` (optional) | — | Request payload for the page-level data API |
67
+ | `selectionMode` | `string` (optional) | — | `single`, `multi`, or absent for no selection |
68
+ | `compositeKeys` | `list` (optional) | — | Property names that together identify a row |
69
+ | `selectedValues` | `list` (optional) | — | Records already selected, used to pre-check rows in multi-selection |
70
+ | `readonlyContextList` | `list` (optional) | — | Fallback for `selectedValues` |
71
+ | `value` | `string` (optional) | — | The bound identity in single selection, used to preselect a row |
72
+ | `referenceType` | `string` (optional) | — | `Data` or `Case`; decides the default row identity |
73
+ | `globalSearch` | `boolean` (optional) | — | Shows the search input above the table |
74
+ | `title` | `string` (optional) | — | The heading shown above the table |
75
+ | `localeReference` | `string` (optional) | — | The localization bundle used for column headers |
76
+ | `showDynamicFields` | `boolean` (optional) | `false` | Passed to the metadata call; also makes every metadata field eligible as an extra field |
77
+ | `viewName` | `string` (optional) | — | Identifies the table for search-and-select events |
78
+ | `displayAs` | `string` (optional) | — | The presentation that created the table; only `advancedSearch` changes behaviour |
75
79
 
76
80
  ## Implementation Structure
77
81
 
78
- > ⚠️ **CRITICAL — USE THE PROJECT'S DESIGN SYSTEM FOR TABLE RENDERING**
79
- >
80
- > This component MUST use the **installed design system's table components** — NOT plain HTML `<table>/<thead>/<tbody>`.
81
- > Check the project's dependencies for the installed design system and use its table primitives. The table MUST look like a proper data grid with:
82
- >
83
- > - Column headers with field labels (from PConnect presets metadata)
84
- > - Paginated rows (not all rows at once)
85
- > - Clickable link cells for navigation
86
- > - Search toolbar (when `globalSearch !== false`)
87
- >
88
- > Do NOT render raw `Object.values(row)` or dump all data keys as columns, and do NOT use plain HTML when a design system is installed.
89
-
90
- This is the largest template component. The implementation MUST include these critical sections.
82
+ > ⚠️ **Use the project's design system for the table** when one is installed — its table, pagination, search input, selection controls and links. When none is installed, use the platform's native table elements, applying the containment rules under Visual Specifications. Either way the result is a data grid with column headers, paged rows and, where configured, link cells and a search input.
91
83
 
92
- **Module Setup:** The component depends on local state management, lifecycle effects, and a cached callback. Declare a constant `AssignDashObjects = ['Assign-Worklist', 'Assign-WorkBasket']` (classes whose links should open as assignments rather than plain work items). Define the input contract as an extension of the project's base component interface with optional `bInForm`, `globalSearch`, `referenceList`, `selectionMode`, `referenceType`, `payload`, `parameters`, `compositeKeys`, and `localeReference` fields.
84
+ **Module Setup:** The component depends on the project's component registry and on the platform APIs named in this skill. It holds, across re-renders: the rows, the column definitions, the current page and page size (default 10), the sort column and direction, the search text, and the set of selected row identities.
93
85
 
94
- **Main Component Logic** — steps in order:
86
+ **Main Component Logic** — in order:
95
87
 
96
- 1. Receive inputs: `getPConnect`, `bInForm` (default `true`), `globalSearch`, `referenceList`, `payload`, `parameters`, and `localeReference`. Declare local state: `arRows` (array, default `[]`), `arColumns` (array, default `[]`), `page` (default `1`), `pageSize` (default `10`), `searchValue` (default `''`), and `title` (default `''`).
97
- 2. Call `getPConnect()` once into `thePConn`; read `componentConfig = thePConn.getComponentConfig()` and `resolvedConfigProps = thePConn.getConfigProps()`.
98
- 3. **Extract column definitions from PConnect presets** — define a memoized/cached `getHeaderCells(columnFields, fieldDefs)` callback that maps each `columnFields` entry (with its index) to a header descriptor: strip the annotation prefix from `field.config.value` to get `theField` (take the substring after the first space, then strip a leading `.`); find the matching field definition's index in `fieldDefs` via `.findIndex(ele => ele.name === theField)` as `colIndex`; read `additionalDetails` from `field.config` (default `{}`) and compute `displayAsLink` as true when `additionalDetails.type === 'DISPLAY_LINK'` or when `field.config.displayAsLink` is set; return `{ id: theField, type: field.type, displayAsLink, label: fieldDefs[index]?.label ?? field.config.label ?? theField, classID: colIndex > -1 ? fieldDefs[colIndex].classID : undefined, isAssignmentLink: displayAsLink && AssignDashObjects.includes(fieldDefs[colIndex]?.classID) }`.
99
- 4. **Fetch metadata + data** in a lifecycle effect keyed on `[referenceList, bInForm, payload, parameters]`, using an `isActive` flag to guard against updates after unmount:
100
- - Await field definitions via `PCore.getAnalyticsUtils().getDataViewMetadata(referenceList, false)`, reading `fieldDefs` from `metaResponse?.data?.fields ?? []`.
101
- - Read configured columns from `componentConfig?.presets?.[0]?.children?.[0]?.children ?? []`; when non-empty, build `myColumns` via `getHeaderCells(columnFields, fieldDefs)`, localize each column's `label` through `PCore.getLocaleUtils().getLocaleValue` when `localeReference` is set, and store the result via `setColumns`.
102
- - Fetch the row data using the API appropriate to `bInForm` (see the CRITICAL note above): for `!bInForm`, await `PCore.getDataApiUtils().getData(referenceList, payload ?? {})`; for `bInForm`, resolve `context = thePConn.getContextName()` and await `PCore.getDataPageUtils().getDataAsync(referenceList, context, parameters, null, null)`. Extract `tableData` from `dataResult?.data?.data ?? []` (page mode) or `dataResult?.data ?? []` (form mode), and store it via `setRows` (defaulting to `[]` when not an array).
103
- 5. **Link click handling** — define `handleLinkClick(row, column)`: when `column.isAssignmentLink`, destructure `pxRefObjectClass` and `pzInsKey` from `row` and call `thePConn.getActionsApi().openAssignment(pzInsKey, pxRefObjectClass, { containerName: thePConn.getContainerName(), channelName: '' })`; otherwise, resolve `pxRefObjectKey` from `row.pxRefObjectKey ?? row.pzInsKey` and `pxRefObjectClass` from `row.pxRefObjectClass ?? row.pxObjClass`, and when both are present, call `thePConn.getActionsApi().openWorkByHandle(pxRefObjectKey, pxRefObjectClass)`.
104
- 6. Beyond these mandatory sections, a full implementation also needs search, pagination, sort, selection, and rendering logic (see the Behavioral Contract below for each).
105
-
106
- > **Note:** The sections above show the MANDATORY patterns. Full implementations will also include sorting, selection, filter dialog, column menus, and PubSub subscriptions for dashboard filters. But the three critical sections above (column extraction, data fetching, link handling) MUST be present for the table to render correctly.
88
+ 1. **Receive inputs,** each defaulted as documented.
89
+ 2. **Read the configuration.** Take the component configuration from `getComponentConfig()` and the raw configuration from `getRawMetadata().config` on the accessor.
90
+ 3. **Derive the row identity** — see Selection.
91
+ 4. **Load once, when first displayed:** fetch the metadata and the report columns, build the column definitions as the CRITICAL note on columns describes, then fetch the rows as Data Fetching describes. Store both. Ignore any result that arrives after the component has been removed.
92
+ 5. **Reload** when the parameters change, and when a dashboard filter event or a promoted-filter update arrives — see Dashboard Filters.
93
+ 6. **Pre-check selected rows** once rows arrive — see Selection.
94
+ 7. **Render** the heading, the search input when `globalSearch` is set, the table, and the paging controls — see the Behavioral Contract.
107
95
 
108
96
  ## Behavioral Contract
109
97
 
110
- ### Initialization
111
-
112
- The initialization utility (invoked with `getPConnect`, `columns`, `dataPageName`, and `payload`):
113
-
114
- 1. Calls `initializeColumns(getPConnect, columns)` to build `configFields`.
115
- 2. Calls `buildFieldsForTable(configFields)` to produce display column definitions.
116
- 3. Calls `getConfigFields(configFields)` for sort/filter metadata.
117
- 4. Fetches initial data via `PCore.getDataApiUtils().getDataAsync(dataPageName, payload)`.
118
- 5. Returns `{ tableDataRows, configFields, totalCount }`.
119
-
120
98
  ### Sorting
121
99
 
122
- - `<TableSortLabel>` in each sortable column header.
123
- - On click: call `PCore.getDataApiUtils().getDataAsync(dataPageName, { ...payload, sortBy, sortOrder })`.
124
- - `sortBy` = column field name, `sortOrder` = `'ASC'` or `'DESC'`.
100
+ Each column header offers sorting. Activating it sorts the loaded rows by that column — ascending first, and descending when activated again — keeping rows with equal values in their existing order. Sorting never re-fetches.
125
101
 
126
- ### Pagination
102
+ ### Paging
127
103
 
128
- - `<TablePagination>` component below the table.
129
- - `rowsPerPageOptions`: `[5, 10, 25]`.
130
- - On page/rows change: re-fetch with `startIndex` and `maxResults` params.
104
+ The paging control sits below the table, offers 10, 25 and 100 rows per page, and starts at 10. Changing the page size returns to the first page. Paging acts on the loaded rows and never re-fetches.
131
105
 
132
- ### Global Search
106
+ ### Search
133
107
 
134
- - Shown when `isSearchable === true`.
135
- - `<TextField>` input above the table (toolbar area).
136
- - On submit/debounce: re-fetch with `searchText` param.
108
+ Shown when `globalSearch` is set. As the user types, show only the loaded rows in which some displayed column's value, as text, contains the typed text, ignoring case. Hidden and query-only fields are not searched.
137
109
 
138
110
  ### Selection
139
111
 
140
- | `selectionMode` | Control per row | Callback |
141
- | --------------- | --------------- | ---------------------------- |
142
- | `'single'` | `<Radio>` | `onRowSelect(rowData)` |
143
- | `'multi'` | `<Checkbox>` | `onRowsSelect(selectedRows)` |
144
- | absent | None | None |
112
+ When `selectionMode` is `single`, each row starts with a single-choice control. When it is `multi`, each row starts with a multiple-choice control, and the header carries one that selects or clears every row — shown as partly selected when some rows are. When it is absent, rows have no selection control.
145
113
 
146
- - Select-all checkbox in the header for multi-selection.
147
- - Selected rows highlighted with `selected` row class.
114
+ **Row identity.** Use the single composite key when exactly one is supplied; otherwise `pyGUID` for a data reference and `pyID` for a case reference.
148
115
 
149
- ### Column Menu
116
+ **Writing the selection.** Selection is written through the list actions of `getPConnect().getListActions()`, never by editing rows directly.
150
117
 
151
- - `<MoreVertIcon>` button in each column header.
152
- - Opens `<Menu>` with options: Show/Hide column, Pin column.
153
- - Column visibility stored in local state `columnVisibility`.
118
+ - **Single:** call `setSelectedRows` with a one-entry list holding the chosen row's identity — or, with more than one composite key, every composite key's value taken from the fetched row.
119
+ - **Multi, one row toggled:** call `setSelectedRows` with a one-entry list holding the row's identity as above plus a `$selected` flag saying whether it is now checked.
120
+ - **Select all:** clear first with `clearSelectedRows` when some rows were already checked, then call `setSelectedRows` with an entry for every row, each flagged as selected. **Clear all:** `clearSelectedRows`.
121
+ - **Preselection:** rows whose identity appears in the selected values supplied by the parent start checked, for multi-selection; for single selection, the row whose identity equals the bound value starts selected.
154
122
 
155
- ### Filter Dialog
123
+ The filter and group settings of a full table are not supported: both table presentations of a reference field render through this one simple table. Ignore any configured filter expression and grouping.
156
124
 
157
- - Filter icon in toolbar or column header.
158
- - Opens `<Dialog>` with filter form fields for each filterable column.
159
- - On apply: re-fetch with filter params.
160
- - `filterData(filters, configFields)` formats filter objects for the API.
125
+ ### Column Menu and Filter Dialog — page-level only
161
126
 
162
- ### Link Rendering (Navigation)
127
+ On a page (`bInForm` false), each column header also offers a menu whose filter entry opens a dialog. For a text column the dialog offers a comparison — such as contains — and a value; for a date, date-time or time column it offers a date comparison and a date. Applying it filters the loaded rows by every column filter currently set, re-applies the current sort, and marks the column's header as filtered while its value is non-empty. Column filters never re-fetch. Inside a form there is no column menu.
163
128
 
164
- Columns configured with `displayAsLink: true` (or `additionalDetails.type === 'DISPLAY_LINK'`) render as clickable links that navigate to assignments or work items.
129
+ These are the user's own interactive filters. Configured filters and grouping are a separate matter, and are not supported — see Selection.
165
130
 
166
- **Detection logic:**
131
+ ### Dashboard Filters
167
132
 
168
- A column is a link when `column.displayAsLink` is true. It's specifically an assignment link when its `classID` is one of the worklist/workbasket classes in `AssignDashObjects = ['Assign-Worklist', 'Assign-WorkBasket']` (i.e. `AssignDashObjects.includes(column.classID)`).
133
+ Once the metadata is loaded, subscribe with `PCore.getPubSubUtils().subscribe(...)` to the dashboard-filter-change and dashboard-filter-clear-all events from `PCore.getConstants().PUB_SUB_EVENTS`, scoped to the accessor's context name, and to the promoted-filters update event from `PCore.getEvents().getTransientEvent()`. A change records the filter by its identifier and re-fetches; clear-all forgets every filter and re-fetches; a promoted-filter update converts each entered value into a filter — contains for text, equals otherwise — and re-fetches. Unsubscribe from all three when the component is removed.
169
134
 
170
- **Click handling:**
135
+ ### Link Rendering
171
136
 
172
- | Link type | API call | Parameters |
173
- | --------------- | --------------------------------------------------------------------- | ---------------------------------------------- |
174
- | Assignment link | `getActionsApi().openAssignment(pzInsKey, pxRefObjectClass, options)` | `options = { containerName, channelName: '' }` |
175
- | Work item link | `getActionsApi().openWorkByHandle(pxRefObjectKey, pxRefObjectClass)` | — |
137
+ A column is a link when its descriptor's `additionalDetails` has the type `DISPLAY_LINK`, or when the descriptor sets `displayAsLink`. A link column is an **assignment link** when its class is `Assign-Worklist` or `Assign-WorkBasket`, and an **association link** when its value carries the case-association marker. Two column names are links even without either setting: `pxTaskLabel`, when the row has a class and an instance key, and `pxRefObjectInsName`, when the row has a class and a reference key.
176
138
 
177
- **Legacy column IDs** that also render as links (even without `displayAsLink`):
139
+ On activation, through the accessor's actions interface:
178
140
 
179
- - `pxTaskLabel` → opens assignment (if `pxRefObjectClass` + `pzInsKey` exist on the row)
180
- - `pxRefObjectInsName` → opens work item (if `pxRefObjectClass` + `pxRefObjectKey` exist)
141
+ - An assignment link calls `openAssignment(instanceKey, objectClass, options)`, with the row's `pzInsKey` and `pxObjClass` and options naming the primary container and an empty channel.
142
+ - Any other configured link calls `openWorkByHandle(instanceKey, objectClass)`. For an association link, the instance key comes from the row's field formed by the association's category, a colon, and `pzInsKey`.
143
+ - `pxTaskLabel` opens the assignment named by the row's `pzInsKey` and `pxRefObjectClass`, in the accessor's own container. On failure, show a brief error message.
144
+ - `pxRefObjectInsName` opens the work item named by the row's `pxRefObjectKey` and its `pxRefObjectClass` — or, failing that, its `pxObjClass` — when both are present.
181
145
 
182
- ### Snackbar Toast
146
+ On a page, link cells render as links. Inside a form, cells show formatted values only.
183
147
 
184
- - Shown on fetch errors or action feedback.
185
- - Auto-hides after 3000ms.
148
+ ### Error Messages
149
+
150
+ Show fetch and action failures as a brief, dismissible message that hides itself after a few seconds.
186
151
 
187
152
  ## Visual Specifications
188
153
 
189
- | Element | Description |
190
- | -------------- | -------------------------------------------------------- |
191
- | Toolbar | Search input + filter button + (optional) action buttons |
192
- | Table head | Sticky header with sort labels and column menu |
193
- | Table body | Striped rows, hover state, selected state |
194
- | Pagination bar | Below table, page size selector + page nav |
154
+ | Element | Description |
155
+ | ----------- | ----------------------------------------------------------------------------------------------- |
156
+ | Heading | The title, with the search input beside it when shown |
157
+ | Table head | Stays visible while the body scrolls; carries the sort controls and, on a page, the column menu |
158
+ | Table body | Hover and selected states on rows |
159
+ | Paging | Below the table: a page-size choice and page navigation |
160
+ | Empty state | The localized message "No records found." when there are no rows |
161
+
162
+ **Cell values.** Each cell shows the row's value under the column's name. Format by the column's type: dates and date-times with the locale's long date format (plus the time for a date-time), currency with the locale's currency options, and the numeric types — Decimal, Integer, Percentage, Currency — right-aligned. An empty value shows `---`.
195
163
 
196
- **CSS-only implementation notes:**
164
+ **Containment.** The table must never widen or lengthen its surroundings. Put it in its own scrolling region: it scrolls horizontally when the columns are wider than the space available, and vertically beyond a maximum height, with the header staying in view. The region itself must be allowed to shrink to the width its container gives it, however wide its content — otherwise one wide table widens every field around it.
197
165
 
198
- - Table container: `overflow-x: auto`.
199
- - Header row: `background: var(--table-header-bg); font-weight: 600`.
200
- - Selected row: `background: var(--selection-highlight-bg)`.
201
- - Hover row: `background: var(--hover-bg)`.
202
- - Sticky header: `position: sticky; top: 0; z-index: 1`.
166
+ **Theme tokens.** Take the header background, the selected-row highlight and the hover highlight from the project's theme tokens rather than fixed colours, and give the header a heavier font weight than the body.
203
167
 
204
168
  ## Edge Cases & Special Logic
205
169
 
206
- - `bInForm: true` — remove outer padding, hide some toolbar elements.
207
- - Empty result set — show empty state message `"No records found"`.
208
- - `compositeKeys` — used for unique row key generation when no single ID field exists.
209
- - Column visibility changes are local state only — not persisted by default.
210
- - Large datasets — pagination is mandatory; do not load all rows at once.
170
+ - **Inside a form,** remove the outer padding and the page-level column menu.
171
+ - **No rows:** show the empty-state message.
172
+ - **Composite keys** identify a row when no single identifying property exists — see Selection.
173
+ - **Missing presets** mean the parent wired the table wrongly: render nothing and report it.
174
+ - **A row without `pyGUID` or `pyID`** cannot be selected reliably; report it when a selection mode is set.
175
+ - **Search, sort, paging and column filters** all act on the loaded rows. Only a parameter change, a dashboard filter or a promoted-filter update re-fetches.
211
176
 
212
177
  ## Dependencies
213
178
 
214
- - Local utility helpers: an initialization utility, `filterData`, `buildFieldsForTable`, `getConfigFields`, `initializeColumns`.
215
- - `PCore.getDataApiUtils().getData()` and `PCore.getDataPageUtils().getDataAsync()` — data fetching.
216
- - `PCore.getAnalyticsUtils().getDataViewMetadata()` — column metadata.
217
- - The design system's table, pagination, dialog, search, and link components.
179
+ - `PCore.getAnalyticsUtils().getDataViewMetadata(...)` and `PCore.getAnalyticsUtils().getFieldsForDataSource(...)` — column metadata and report columns.
180
+ - `PCore.getDataPageUtils().getDataAsync(...)` and `PCore.getDataApiUtils().getData(...)` — rows.
181
+ - `PCore.getMetadataUtils().getPropertyMetadata(...)` and `PCore.getLocaleUtils().getLocaleValue(...)` — labels.
182
+ - The accessor's list actions and actions interface — selection and links.
183
+ - `PCore.getPubSubUtils()` — dashboard and promoted filters.
184
+ - The design system's table, paging, search input, selection controls, dialog and link, or native equivalents.
218
185
 
219
186
  ## Design System Mapping
220
187
 
221
- **UI control type:** Full-featured data table with sorting, pagination, search, selection, and filtering.
222
-
223
- When implementing in a specific design system, map the following:
224
-
225
- - **Table** → use the DS's data table component with header/body/row/cell sub-components
226
- - **Pagination** → use the DS's pagination component (page size selector + page navigation)
227
- - **Search toolbar** → use the DS's search/text-input component in a toolbar area above the table
228
- - **Link cells** → use the DS's link component for `displayAsLink` columns
229
- - **Selection** → use radio (single) or checkbox (multi) components per row
230
- - **Dialog/Modal** → use the DS's dialog for filter dialogs and column menu
231
- - **Sorting** → use the DS's sort indicator on column headers (e.g., up/down arrows)
232
- - `bInForm` affects layout — tighten spacing and remove outer chrome when `true`
233
- - Sorting, pagination, and search all trigger data re-fetches — do not filter client-side for server-paged data
234
- - Selection mode (`single`/`multi`) requires different controls and callbacks
188
+ **UI control type:** Data table with sorting, paging, search and selection.
189
+
190
+ - **Table** → the design system's data table, with its header, body, row and cell parts
191
+ - **Paging** → the design system's pagination, with a page-size choice and page navigation
192
+ - **Search** → the design system's search or text input beside the heading
193
+ - **Link cells** → the design system's link
194
+ - **Selection** → a single-choice control per row for single selection, a multiple-choice control per row and in the header for multi-selection
195
+ - **Filter dialog** → the design system's dialog
196
+ - **Sorting** → the design system's sort indicator on each header
197
+ - **Inside a form** → tighter spacing and no outer chrome
198
+
199
+ ## Generation Self-Check
200
+
201
+ - Columns come only from this table's own presets, in configured order, and never from the rows.
202
+ - No column is filtered by name or prefix, and no label is taken from metadata by position.
203
+ - The data API matches `bInForm`, and the rows are read from the matching response path.
204
+ - Selection is written through `setSelectedRows` and `clearSelectedRows`, with composite keys when supplied.
205
+ - Configured filters and grouping are ignored; the user's own sort, paging, search and column filters act on the loaded rows.
206
+ - The table scrolls inside its own region and never widens the form around it.