pict-section-recordset 1.9.6 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +38 -0
  2. package/package.json +2 -2
  3. package/source/Pict-Section-RecordSet.js +1 -0
  4. package/source/providers/Column-Data-Provider.js +219 -0
  5. package/source/providers/RecordSet-RecordProvider-Base.js +64 -1
  6. package/source/providers/RecordSet-RecordProvider-MeadowEndpoints.js +92 -16
  7. package/source/services/RecordsSet-MetaController.js +23 -1
  8. package/source/templates/Pict-Template-FilterInstanceViews.js +4 -0
  9. package/source/views/RecordSet-Filters.js +140 -3
  10. package/source/views/filters/RecordSet-Filter-DistinctSelectedValueList.js +233 -0
  11. package/source/views/filters/index.js +2 -0
  12. package/source/views/list/RecordSet-List-ColumnChooser.js +345 -0
  13. package/source/views/list/RecordSet-List-RecordListEntry.js +4 -1
  14. package/source/views/list/RecordSet-List.js +390 -15
  15. package/source/views/read/RecordSet-Read.js +65 -6
  16. package/types/Pict-Section-RecordSet.d.ts +1 -0
  17. package/types/providers/Column-Data-Provider.d.ts +115 -0
  18. package/types/providers/Column-Data-Provider.d.ts.map +1 -0
  19. package/types/providers/RecordSet-DynamicRecordsetSolver.d.ts +3 -0
  20. package/types/providers/RecordSet-DynamicRecordsetSolver.d.ts.map +1 -1
  21. package/types/providers/RecordSet-RecordProvider-Base.d.ts +110 -0
  22. package/types/providers/RecordSet-RecordProvider-Base.d.ts.map +1 -1
  23. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts +51 -1
  24. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts.map +1 -1
  25. package/types/providers/RecordSet-Router.d.ts +1 -0
  26. package/types/providers/RecordSet-Router.d.ts.map +1 -1
  27. package/types/services/RecordsSet-MetaController.d.ts.map +1 -1
  28. package/types/templates/Pict-Template-FilterInstanceViews.d.ts.map +1 -1
  29. package/types/views/RecordSet-Filters.d.ts +61 -0
  30. package/types/views/RecordSet-Filters.d.ts.map +1 -1
  31. package/types/views/RecordSet-RecordBaseView.d.ts +1 -0
  32. package/types/views/RecordSet-RecordBaseView.d.ts.map +1 -1
  33. package/types/views/filters/RecordSet-Filter-EntityReference-Base.d.ts.map +1 -1
  34. package/types/views/list/RecordSet-List-ColumnChooser.d.ts +68 -0
  35. package/types/views/list/RecordSet-List-ColumnChooser.d.ts.map +1 -0
  36. package/types/views/list/RecordSet-List-RecordListEntry.d.ts.map +1 -1
  37. package/types/views/list/RecordSet-List.d.ts +167 -2
  38. package/types/views/list/RecordSet-List.d.ts.map +1 -1
  39. package/types/views/read/RecordSet-Read.d.ts +8 -0
  40. package/types/views/read/RecordSet-Read.d.ts.map +1 -1
@@ -0,0 +1,345 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ /**
4
+ * The list's column chooser: a small right-aligned "Columns" button above the table that opens a
5
+ * popover of checkbox rows — the host-curated columns first, then the entity's remaining scalar
6
+ * schema columns — letting the user show/hide columns per record set. Choices persist through the
7
+ * ColumnDataProvider and repaint body-only through the list view (the filter bar is never touched).
8
+ *
9
+ * Renders nothing unless the active record set's configuration sets RecordSetListColumnChooser: true
10
+ * (the list view only populates Record.ColumnChooserSlot when the flag is on).
11
+ */
12
+
13
+ /** @type {Record<string, any>} */
14
+ const _DEFAULT_CONFIGURATION_List_ColumnChooser = (
15
+ {
16
+ ViewIdentifier: 'PRSP-List-ColumnChooser',
17
+
18
+ DefaultRenderable: 'PRSP_Renderable_ColumnChooser',
19
+ DefaultDestinationAddress: '#PRSP_ColumnChooser_Container',
20
+ DefaultTemplateRecordAddress: false,
21
+
22
+ AutoInitialize: false,
23
+ AutoInitializeOrdinal: 0,
24
+
25
+ AutoRender: false,
26
+ AutoRenderOrdinal: 0,
27
+
28
+ AutoSolveWithApp: false,
29
+ AutoSolveOrdinal: 0,
30
+
31
+ // Mirrors the add-filter popover chrome (fixed + JS-positioned so no ancestor overflow can
32
+ // clip it; transparent backdrop catches outside clicks) with its own class namespace.
33
+ CSS: /*css*/`
34
+ .prsp-colchooser-bar { display: flex; justify-content: flex-end; margin: 0 0 0.35rem; }
35
+ .prsp-colchooser-trigger { display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; font: inherit; font-size: 0.88rem;
36
+ padding: 0.3rem 0.65rem; border: 1px solid var(--theme-color-border-default, #d7dce3); border-radius: 7px;
37
+ background: var(--theme-color-background-panel, #fff); color: var(--theme-color-text-secondary, #45505f); }
38
+ .prsp-colchooser-trigger:hover { background: var(--theme-color-background-tertiary, #eceef2); color: var(--theme-color-text-primary, #1f2733); }
39
+ .prsp-colchooser-pop { position: fixed; z-index: 30; min-width: 260px; max-width: 340px; display: none; }
40
+ .prsp-colchooser-pop.open { display: block; }
41
+ .prsp-colchooser-backdrop { position: fixed; inset: 0; z-index: 0; }
42
+ .prsp-colchooser-panel { position: relative; z-index: 1; display: flex; flex-direction: column; max-height: min(70vh, 460px);
43
+ background: var(--theme-color-background-panel, #fff); border: 1px solid var(--theme-color-border-default, #d7dce3);
44
+ border-radius: 10px; box-shadow: 0 10px 28px rgba(17, 24, 39, 0.14); overflow: hidden; }
45
+ .prsp-colchooser-search { flex: 0 0 auto; display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--theme-color-border-light, #e8ebf0); }
46
+ .prsp-colchooser-search-ic { display: inline-flex; color: var(--theme-color-text-muted, #6b7686); font-size: 0.9rem; }
47
+ .prsp-colchooser-search input { flex: 1 1 auto; min-width: 0; font: inherit; font-size: 0.9rem; border: none; outline: none; background: transparent; color: var(--theme-color-text-primary, #1f2733); }
48
+ .prsp-colchooser-list { flex: 1 1 auto; overflow-y: auto; padding: 0.25rem 0; }
49
+ .prsp-colchooser-empty { padding: 0.7rem 0.8rem; color: var(--theme-color-text-muted, #6b7686); font-size: 0.86rem; }
50
+ .prsp-colchooser-group { padding: 0.45rem 0.8rem 0.2rem; font-size: 0.72rem; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase; color: var(--theme-color-text-muted, #6b7686); }
51
+ .prsp-colchooser-row { display: flex; align-items: center; gap: 0.5rem; width: 100%; font: inherit; font-size: 0.9rem; text-align: left; cursor: pointer;
52
+ padding: 0.4rem 0.8rem; border: none; background: transparent; color: var(--theme-color-text-primary, #1f2733); }
53
+ .prsp-colchooser-row:hover { background: var(--theme-color-background-tertiary, #eceef2); }
54
+ .prsp-colchooser-check { display: inline-flex; flex: 0 0 auto; font-size: 0.85rem; color: var(--theme-color-brand-primary, #156dd1); visibility: hidden; }
55
+ .prsp-colchooser-row.is-checked .prsp-colchooser-check { visibility: visible; }
56
+ .prsp-colchooser-footer { flex: 0 0 auto; display: flex; justify-content: flex-end; padding: 0.45rem 0.7rem; border-top: 1px solid var(--theme-color-border-light, #e8ebf0); }
57
+ .prsp-colchooser-reset { font: inherit; font-size: 0.84rem; cursor: pointer; border: none; background: transparent; color: var(--theme-color-text-muted, #6b7686); padding: 0.15rem 0.3rem; border-radius: 5px; }
58
+ .prsp-colchooser-reset:hover { color: var(--theme-color-text-primary, #1f2733); background: var(--theme-color-background-tertiary, #eceef2); }
59
+ `,
60
+ CSSPriority: 500,
61
+
62
+ Templates:
63
+ [
64
+ {
65
+ // The {~V:~} slot in PRSP-List-Template renders this with the full list data as Record;
66
+ // the one-or-zero-element ColumnChooserSlot array gates the whole control on the
67
+ // RecordSetListColumnChooser flag with no JS branch.
68
+ Hash: 'PRSP-List-ColumnChooser-Template',
69
+ Template: /*html*/`
70
+ <!-- DefaultPackage pict view template: [PRSP-List-ColumnChooser-Template] -->
71
+ {~TS:PRSP-List-ColumnChooser-Button:Record.ColumnChooserSlot~}
72
+ <!-- DefaultPackage end view template: [PRSP-List-ColumnChooser-Template] -->
73
+ `
74
+ },
75
+ {
76
+ Hash: 'PRSP-List-ColumnChooser-Button',
77
+ Template: /*html*/`
78
+ <div class="prsp-colchooser-bar">
79
+ <button type="button" class="prsp-colchooser-trigger" id="PRSP_ColumnChooser_Trigger" title="Choose which columns to show" onclick="_Pict.views['PRSP-List-ColumnChooser'].toggleColumnChooser(event, '{~D:Record.RecordSet~}')">{~I:Settings~} Columns</button>
80
+ <div class="prsp-colchooser-pop" id="PRSP_ColumnChooser_Popover"></div>
81
+ </div>
82
+ `
83
+ },
84
+ {
85
+ Hash: 'PRSP-ColumnChooser-Popover',
86
+ Template: /*html*/`
87
+ <!-- DefaultPackage pict view template: [PRSP-ColumnChooser-Popover] -->
88
+ <div class="prsp-colchooser-backdrop" onclick="_Pict.views['PRSP-List-ColumnChooser'].closeColumnChooser()"></div>
89
+ <div class="prsp-colchooser-panel">
90
+ <div class="prsp-colchooser-search">
91
+ <span class="prsp-colchooser-search-ic">{~I:Search~}</span>
92
+ <input type="text" id="PRSP_ColumnChooser_Search" placeholder="Search columns…" autocomplete="off" value="{~D:AppData.PRSPColumnChooser.Search~}" oninput="_Pict.views['PRSP-List-ColumnChooser'].searchColumnChooser(this.value)" onkeydown="if (event.key === 'Escape') { event.preventDefault(); _Pict.views['PRSP-List-ColumnChooser'].closeColumnChooser(); }">
93
+ </div>
94
+ <div class="prsp-colchooser-list" id="PRSP_ColumnChooser_List">
95
+ {~T:PRSP-ColumnChooser-List~}
96
+ </div>
97
+ <div class="prsp-colchooser-footer">
98
+ <button type="button" class="prsp-colchooser-reset" onclick="_Pict.views['PRSP-List-ColumnChooser'].resetColumns()">Reset to defaults</button>
99
+ </div>
100
+ </div>
101
+ <!-- DefaultPackage end view template: [PRSP-ColumnChooser-Popover] -->
102
+ `
103
+ },
104
+ {
105
+ Hash: 'PRSP-ColumnChooser-List',
106
+ Template: /*html*/`
107
+ <!-- DefaultPackage pict view template: [PRSP-ColumnChooser-List] -->
108
+ {~TS:PRSP-ColumnChooser-Row:AppData.PRSPColumnChooser.CuratedRows~}
109
+ {~NE:AppData.PRSPColumnChooser.HasSchemaRows^<div class="prsp-colchooser-group">More columns</div>~}
110
+ {~TS:PRSP-ColumnChooser-Row:AppData.PRSPColumnChooser.SchemaRows~}
111
+ {~NE:AppData.PRSPColumnChooser.HasAuditRows^<div class="prsp-colchooser-group">Audit columns</div>~}
112
+ {~TS:PRSP-ColumnChooser-Row:AppData.PRSPColumnChooser.AuditRows~}
113
+ {~NE:AppData.PRSPColumnChooser.IsEmpty^<div class="prsp-colchooser-empty">No columns found.</div>~}
114
+ <!-- DefaultPackage end view template: [PRSP-ColumnChooser-List] -->
115
+ `
116
+ },
117
+ {
118
+ Hash: 'PRSP-ColumnChooser-Row',
119
+ Template: /*html*/`
120
+ <button type="button" class="prsp-colchooser-row {~D:Record.CheckedClass~}" onclick="_Pict.views['PRSP-List-ColumnChooser'].toggleColumn('{~D:Record.Key~}')">
121
+ <span class="prsp-colchooser-check">{~I:Check~}</span>
122
+ <span class="prsp-colchooser-name">{~D:Record.DisplayName~}</span>
123
+ </button>
124
+ `
125
+ }
126
+ ],
127
+
128
+ Renderables:
129
+ [
130
+ {
131
+ RenderableHash: 'PRSP_Renderable_ColumnChooser',
132
+ TemplateHash: 'PRSP-List-ColumnChooser-Template',
133
+ ContentDestinationAddress: '#PRSP_ColumnChooser_Container',
134
+ RenderMethod: 'replace'
135
+ },
136
+ {
137
+ RenderableHash: 'PRSP_ColumnChooser_Popover',
138
+ TemplateHash: 'PRSP-ColumnChooser-Popover',
139
+ ContentDestinationAddress: '#PRSP_ColumnChooser_Popover',
140
+ RenderMethod: 'replace'
141
+ },
142
+ {
143
+ RenderableHash: 'PRSP_ColumnChooser_List',
144
+ TemplateHash: 'PRSP-ColumnChooser-List',
145
+ ContentDestinationAddress: '#PRSP_ColumnChooser_List',
146
+ RenderMethod: 'replace'
147
+ }
148
+ ],
149
+
150
+ Manifests: {}
151
+ });
152
+
153
+ class viewRecordSetListColumnChooser extends libPictView
154
+ {
155
+ constructor(pFable, pOptions, pServiceHash)
156
+ {
157
+ let tmpOptions = Object.assign({}, _DEFAULT_CONFIGURATION_List_ColumnChooser, pOptions);
158
+ super(pFable, tmpOptions, pServiceHash);
159
+
160
+ this._chooserRecordSet = null;
161
+ this._chooserSearch = '';
162
+ }
163
+
164
+ /**
165
+ * Open/close the chooser popover (the trigger button's handler).
166
+ *
167
+ * Open/closed is derived from the popover's DOM class, not an instance flag — a full list
168
+ * re-render replaces the popover element (visually closed), so a flag would go stale and
169
+ * demand a double-click to reopen.
170
+ *
171
+ * @param {Event} pEvent - The DOM click event
172
+ * @param {string} pRecordSet - The record set whose columns to manage
173
+ */
174
+ toggleColumnChooser(pEvent, pRecordSet)
175
+ {
176
+ if (pEvent) { pEvent.preventDefault(); }
177
+ const tmpPopoverElements = this.pict.ContentAssignment.getElement('#PRSP_ColumnChooser_Popover');
178
+ if (tmpPopoverElements.length && tmpPopoverElements[0].classList.contains('open'))
179
+ {
180
+ return this.closeColumnChooser();
181
+ }
182
+ this._chooserRecordSet = pRecordSet;
183
+ this._chooserSearch = '';
184
+ this._buildColumnChooserRows();
185
+ this.render('PRSP_ColumnChooser_Popover', undefined, { RecordSet: pRecordSet });
186
+ this._paintColumnChooserOpenState(true);
187
+ }
188
+
189
+ /** Close the chooser popover. */
190
+ closeColumnChooser()
191
+ {
192
+ this._paintColumnChooserOpenState(false);
193
+ }
194
+
195
+ /**
196
+ * Filter the chooser's column list by a search term, re-rendering only the list so the
197
+ * search input keeps focus.
198
+ * @param {string} pValue - The search term.
199
+ */
200
+ searchColumnChooser(pValue)
201
+ {
202
+ this._chooserSearch = pValue || '';
203
+ this._buildColumnChooserRows();
204
+ this.render('PRSP_ColumnChooser_List', undefined, { RecordSet: this._chooserRecordSet });
205
+ }
206
+
207
+ /**
208
+ * Flip a column's visibility (a chooser row's handler). Delegates to the list view — which
209
+ * persists the override and repaints the rows body-only — then repaints the chooser rows
210
+ * truthfully (the list view may have refused, e.g. hiding the last visible column).
211
+ * @param {string} pKey - The column key to toggle.
212
+ */
213
+ toggleColumn(pKey)
214
+ {
215
+ const tmpListView = this.pict.views['RSP-RecordSet-List'];
216
+ if (!tmpListView || !tmpListView._lastRecordListData || !Array.isArray(tmpListView._lastRecordListData.ColumnCandidates))
217
+ {
218
+ return;
219
+ }
220
+ const tmpCandidate = tmpListView._lastRecordListData.ColumnCandidates.find((pCandidate) => pCandidate.Key === pKey);
221
+ if (!tmpCandidate)
222
+ {
223
+ return;
224
+ }
225
+ const tmpColumnProvider = this.pict.providers.ColumnDataProvider;
226
+ const tmpOverrides = tmpColumnProvider ? tmpColumnProvider.getColumnVisibilityOverrides(this._chooserRecordSet, 'List') : {};
227
+ const tmpCurrentlyVisible = tmpListView._effectiveColumnVisibility(tmpCandidate, tmpOverrides);
228
+ tmpListView.setColumnVisibility(this._chooserRecordSet, pKey, !tmpCurrentlyVisible);
229
+ this._buildColumnChooserRows();
230
+ this.render('PRSP_ColumnChooser_List', undefined, { RecordSet: this._chooserRecordSet });
231
+ }
232
+
233
+ /** Clear all overrides for the record set and repaint with default visibility (footer button). */
234
+ resetColumns()
235
+ {
236
+ const tmpListView = this.pict.views['RSP-RecordSet-List'];
237
+ if (!tmpListView)
238
+ {
239
+ return;
240
+ }
241
+ tmpListView.resetColumnVisibility(this._chooserRecordSet);
242
+ this._buildColumnChooserRows();
243
+ this.render('PRSP_ColumnChooser_List', undefined, { RecordSet: this._chooserRecordSet });
244
+ }
245
+
246
+ /**
247
+ * (Re)build the chooser's row models into AppData from the list view's pristine column
248
+ * candidates (single source of truth) + the current overrides, honouring the search term.
249
+ */
250
+ _buildColumnChooserRows()
251
+ {
252
+ const tmpListView = this.pict.views['RSP-RecordSet-List'];
253
+ const tmpListData = tmpListView && tmpListView._lastRecordListData;
254
+ const tmpCandidates = (tmpListData && tmpListData.RecordSet === this._chooserRecordSet && Array.isArray(tmpListData.ColumnCandidates))
255
+ ? tmpListData.ColumnCandidates : [];
256
+ const tmpColumnProvider = this.pict.providers.ColumnDataProvider;
257
+ const tmpOverrides = tmpColumnProvider ? tmpColumnProvider.getColumnVisibilityOverrides(this._chooserRecordSet, 'List') : {};
258
+ const tmpSearch = (this._chooserSearch || '').toLowerCase();
259
+ const fSearchMatch = (pCandidate) => !tmpSearch || String(pCandidate.DisplayName || pCandidate.Key).toLowerCase().includes(tmpSearch);
260
+ const fMapRow = (pCandidate) => (
261
+ {
262
+ Key: pCandidate.Key,
263
+ DisplayName: pCandidate.DisplayName || pCandidate.Key,
264
+ CheckedClass: tmpListView._effectiveColumnVisibility(pCandidate, tmpOverrides) ? 'is-checked' : '',
265
+ });
266
+ const tmpCuratedRows = tmpCandidates.filter((pCandidate) => pCandidate.Source === 'Curated').filter(fSearchMatch).map(fMapRow);
267
+ const tmpSchemaRows = tmpCandidates.filter((pCandidate) => pCandidate.Source === 'Schema').filter(fSearchMatch).map(fMapRow);
268
+ const tmpAuditRows = tmpCandidates.filter((pCandidate) => pCandidate.Source === 'Audit').filter(fSearchMatch).map(fMapRow);
269
+ this.pict.AppData.PRSPColumnChooser =
270
+ {
271
+ RecordSet: this._chooserRecordSet,
272
+ Search: this._chooserSearch || '',
273
+ CuratedRows: tmpCuratedRows,
274
+ SchemaRows: tmpSchemaRows,
275
+ AuditRows: tmpAuditRows,
276
+ // A group divider only earns its place when rows are showing above it.
277
+ HasSchemaRows: (tmpSchemaRows.length > 0) && (tmpCuratedRows.length > 0),
278
+ HasAuditRows: (tmpAuditRows.length > 0) && ((tmpCuratedRows.length + tmpSchemaRows.length) > 0),
279
+ IsEmpty: (tmpCuratedRows.length + tmpSchemaRows.length + tmpAuditRows.length) === 0,
280
+ };
281
+ }
282
+
283
+ /**
284
+ * Reflect the popover's open/closed state on its container element.
285
+ * @param {boolean} pOpen - Whether the popover should be open.
286
+ */
287
+ _paintColumnChooserOpenState(pOpen)
288
+ {
289
+ const tmpPopoverElements = this.pict.ContentAssignment.getElement('#PRSP_ColumnChooser_Popover');
290
+ if (!tmpPopoverElements.length)
291
+ {
292
+ return;
293
+ }
294
+ tmpPopoverElements[0].classList.toggle('open', !!pOpen);
295
+ if (pOpen)
296
+ {
297
+ this._positionColumnChooserPopover(tmpPopoverElements[0]);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Position the (fixed) popover against the trigger button, flipping above when there's more
303
+ * room there — same approach as the filters view's add-filter popover, so no ancestor
304
+ * overflow:hidden can clip it.
305
+ *
306
+ * @param {HTMLElement} pPopover - the #PRSP_ColumnChooser_Popover element (already display:block).
307
+ */
308
+ _positionColumnChooserPopover(pPopover)
309
+ {
310
+ const tmpTriggerElements = this.pict.ContentAssignment.getElement('#PRSP_ColumnChooser_Trigger');
311
+ if (!tmpTriggerElements.length)
312
+ {
313
+ return;
314
+ }
315
+ const tmpPanel = /** @type {HTMLElement} */ (pPopover.querySelector('.prsp-colchooser-panel'));
316
+ const tmpRect = tmpTriggerElements[0].getBoundingClientRect();
317
+ const tmpGap = 6;
318
+ const tmpMargin = 8;
319
+ const tmpVH = window.innerHeight;
320
+ const tmpVW = window.innerWidth;
321
+ const tmpWidth = pPopover.offsetWidth || 280;
322
+ // Right-align the popover to the (right-aligned) trigger, clamped into the viewport.
323
+ pPopover.style.left = `${Math.round(Math.max(tmpMargin, Math.min(tmpRect.right - tmpWidth, tmpVW - tmpWidth - tmpMargin)))}px`;
324
+ pPopover.style.right = 'auto';
325
+ const tmpSpaceBelow = tmpVH - tmpRect.bottom - tmpGap - tmpMargin;
326
+ const tmpSpaceAbove = tmpRect.top - tmpGap - tmpMargin;
327
+ // Prefer the natural downward direction; only flip above when the room below is genuinely cramped.
328
+ if (tmpSpaceBelow >= 220 || tmpSpaceBelow >= tmpSpaceAbove)
329
+ {
330
+ pPopover.style.top = `${Math.round(tmpRect.bottom + tmpGap)}px`;
331
+ pPopover.style.bottom = 'auto';
332
+ if (tmpPanel) { tmpPanel.style.maxHeight = `${Math.max(160, Math.min(tmpSpaceBelow, 460))}px`; }
333
+ }
334
+ else
335
+ {
336
+ pPopover.style.top = 'auto';
337
+ pPopover.style.bottom = `${Math.round(tmpVH - tmpRect.top + tmpGap)}px`;
338
+ if (tmpPanel) { tmpPanel.style.maxHeight = `${Math.max(160, Math.min(tmpSpaceAbove, 460))}px`; }
339
+ }
340
+ }
341
+ }
342
+
343
+ module.exports = viewRecordSetListColumnChooser;
344
+
345
+ module.exports.default_configuration = _DEFAULT_CONFIGURATION_List_ColumnChooser;
@@ -29,6 +29,9 @@ const _DEFAULT_CONFIGURATION_List_RecordListEntry = (
29
29
  top-aligned, which read as off next to the centered action cell). */
30
30
  #PRSP_List_Table td { vertical-align: middle; }
31
31
 
32
+ /* Deleted rows (visible via the show-deleted filter) read as ghosts of themselves. */
33
+ .prsp-list-row.prsp-row-deleted td { opacity: 0.55; }
34
+
32
35
  /* Row-as-button (opt-in via the RowClickOpensRecord record-set config flag): clicking anywhere in the
33
36
  row — except the action cell — follows the record's default link. */
34
37
  .prsp-list-row.prsp-row-clickable { cursor: pointer; }
@@ -72,7 +75,7 @@ const _DEFAULT_CONFIGURATION_List_RecordListEntry = (
72
75
  // default link makes the row click a harmless no-op.
73
76
  Template: /*html*/`
74
77
  <!-- DefaultPackage pict view template: [PRSP-List-RecordListEntry-Template] -->
75
- <tr class="prsp-list-row{~NE:Record.Payload.RecordSetConfiguration.RowClickOpensRecord^ prsp-row-clickable~}" onclick="if (this.classList.contains('prsp-row-clickable') &amp;&amp; !event.target.closest('.prsp-row-actions')) { var tmpDefaultLink = this.querySelector('.prsp-row-actions a[data-prsp-default]'); if (tmpDefaultLink) { tmpDefaultLink.click(); } }">
78
+ <tr class="prsp-list-row{~NE:Record.Payload.RecordSetConfiguration.RowClickOpensRecord^ prsp-row-clickable~}{~NE:Record.Data.Deleted^ prsp-row-deleted~}" onclick="if (this.classList.contains('prsp-row-clickable') &amp;&amp; !event.target.closest('.prsp-row-actions')) { var tmpDefaultLink = this.querySelector('.prsp-row-actions a[data-prsp-default]'); if (tmpDefaultLink) { tmpDefaultLink.click(); } }">
76
79
  {~TSWP:PRSP-List-RecordListEntry-Template-Row-Cell:Record.Payload.TableCells:Record.Data~}
77
80
  {~T:PRSP-List-RecordListHeader-Template-Extra-Row~}
78
81
  {~T:PRSP-List-RecordListAction-Template-Cell~}