pict-section-recordset 1.8.0 → 1.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-recordset",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Pict dynamic record set management views",
5
5
  "main": "source/Pict-Section-RecordSet.js",
6
6
  "files": [
@@ -477,6 +477,43 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
477
477
  return pRecord;
478
478
  }
479
479
 
480
+ /**
481
+ * The "list entry" display template for an entity — how one of its records should read as a single line
482
+ * in a picker option / selected chip. Returns a pict template string (rendered against the raw record by
483
+ * the picker's TextTemplate), or null to fall back to a single display field.
484
+ *
485
+ * This is deliberately a small, overridable seam: today it hard-knows `User` (whose name lives across
486
+ * NameFull / NameFirst+NameLast and needs an Email/LoginID disambiguator), but the intent is that this
487
+ * eventually reads a per-entity template off the Stricture schema instead of branching here.
488
+ *
489
+ * @param {string} pEntityName - The entity (e.g. 'User').
490
+ * @return {string|null}
491
+ */
492
+ getEntityListEntryTemplate(pEntityName)
493
+ {
494
+ // Register the User branching fall-backs once. addTemplate is idempotent (keyed by hash), so the
495
+ // guard is just to avoid the churn of re-registering on every descriptor build.
496
+ if (!this._entityListEntryTemplatesRegistered)
497
+ {
498
+ this._entityListEntryTemplatesRegistered = true;
499
+ // Name fallback: when NameFull is empty, compose it from the parts.
500
+ this.pict.TemplateProvider.addTemplate('RSP-EntityListEntry-User-NameParts', '{~D:Record.NameFirst~} {~D:Record.NameLast~}');
501
+ // Disambiguator fallback: when Email is empty, use the LoginID.
502
+ this.pict.TemplateProvider.addTemplate('RSP-EntityListEntry-User-Login', '{~D:Record.LoginID~}');
503
+ }
504
+
505
+ switch (pEntityName)
506
+ {
507
+ case 'User':
508
+ // "<name> (<email>)" — name is NameFull, else NameFirst+NameLast; the parenthetical is Email,
509
+ // else LoginID. Stable across the three name-field variations and unique enough to tell apart
510
+ // many same-named users.
511
+ return '{~DWTF:Record.NameFull:RSP-EntityListEntry-User-NameParts~} ({~DWTF:Record.Email:RSP-EntityListEntry-User-Login~})';
512
+ default:
513
+ return null;
514
+ }
515
+ }
516
+
480
517
  /**
481
518
  * @param {string} pSchemaField - The schema field name.
482
519
  * @param {Record<string, any>} pColumn - The full column definition from the schema.
@@ -508,8 +545,11 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
508
545
  {
509
546
  "Label": `${ fieldName }`,
510
547
  "Type": "InternalJoinSelectedValueList",
511
- "ExternalFilterByColumns": remoteTableName === 'User' ? [ 'NameFirst', 'NameLast' ] : [ 'Name' ],
548
+ "ExternalFilterByColumns": remoteTableName === 'User' ? [ 'NameFirst', 'NameLast', 'Email', 'LoginID' ] : [ 'Name' ],
512
549
  "ExternalRecordDisplayTemplate": remoteTableName === 'User' ? '{~D:Record.Data.NameFirst~} {~D:Record.Data.NameLast~}' : '{~D:Record.Name~}',
550
+ // The picker's option/selected display: a per-entity "list entry" template (the seam that
551
+ // will eventually live on the Stricture schema). Disambiguates beyond a single column.
552
+ "EntityListEntryTemplate": this.getEntityListEntryTemplate(remoteTableName),
513
553
  "CoreConnectionColumn": pSchemaField,
514
554
  "RemoteTable": `${ remoteTableName }`,
515
555
  "JoinExternalConnectionColumn": `ID${ remoteTableName }`,
@@ -683,6 +683,9 @@ class ViewRecordSetSUBSETFilters extends libPictView
683
683
  ValueField: tmpDescriptor.JoinExternalConnectionColumn || `ID${tmpDescriptor.RemoteTable}`,
684
684
  SearchFields: tmpSearchFields,
685
685
  TextField: tmpSearchFields[0],
686
+ // Composed, disambiguated option/chip label (e.g. "Brian Smith (brian@…)") — falls back to
687
+ // TextField when the entity has no list-entry template.
688
+ TextTemplate: tmpDescriptor.EntityListEntryTemplate || undefined,
686
689
  Placeholder: `Select ${pMount.Label}…`,
687
690
  OnChange: (pValue) => this.applyQuickFilterEntity(pRecordSet, pViewContext, pMount.Field, pMount.ClauseKey, pValue),
688
691
  });
@@ -156,6 +156,9 @@ class ViewRecordSetSUBSETFilterEntityReferenceBase extends ViewRecordSetSUBSETFi
156
156
  pRecord.ClauseDescriptor.PictForm.Multiple = this.isMultiSelect();
157
157
  pRecord.ClauseDescriptor.PictForm.SearchFields = pRecord.ClauseDescriptor.PictForm.SearchFields
158
158
  || pRecord.ExternalFilterByColumns || (pRecord.ExternalFilterByColumn ? [ pRecord.ExternalFilterByColumn ] : [ 'Name' ]);
159
+ // Composed, disambiguated option/chip label (the entity's "list entry" template); falls back to a
160
+ // single display field when unset.
161
+ pRecord.ClauseDescriptor.PictForm.TextTemplate = pRecord.ClauseDescriptor.PictForm.TextTemplate || pRecord.EntityListEntryTemplate;
159
162
  pRecord.ClauseDescriptor.PictForm.ValueArrayAddress = pRecord.ClauseValuesAddress;
160
163
  pRecord.ClauseDescriptor.PictForm.GetContextScopeFilter = () => this.getContextScopeFilter(this.getInformaryScopedValue(pRecord.ClauseAddress) || pRecord);
161
164
  // JoinEntity compound display (host opt-in on the clause): show each searched row joined to a