@memberjunction/ng-entity-viewer 6.2.0-edge.0 → 6.2.0-edge.1
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/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts +22 -0
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts.map +1 -1
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +57 -13
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js.map +1 -1
- package/dist/lib/entity-cards/entity-cards.component.d.ts +67 -5
- package/dist/lib/entity-cards/entity-cards.component.d.ts.map +1 -1
- package/dist/lib/entity-cards/entity-cards.component.js +202 -71
- package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +159 -16
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.js +446 -147
- package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
- package/dist/lib/entity-data-grid/events/grid-events.js +67 -67
- package/dist/lib/entity-data-grid/events/grid-events.js.map +1 -1
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.d.ts +112 -8
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.d.ts.map +1 -1
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +245 -61
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts +6 -0
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.js +28 -9
- package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
- package/dist/lib/pill/pill.component.d.ts +13 -3
- package/dist/lib/pill/pill.component.d.ts.map +1 -1
- package/dist/lib/pill/pill.component.js +34 -10
- package/dist/lib/pill/pill.component.js.map +1 -1
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.d.ts +29 -3
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.d.ts.map +1 -1
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +173 -114
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.js.map +1 -1
- package/dist/lib/recycle-bin/recycle-bin.component.d.ts +4 -0
- package/dist/lib/recycle-bin/recycle-bin.component.d.ts.map +1 -1
- package/dist/lib/recycle-bin/recycle-bin.component.js +10 -2
- package/dist/lib/recycle-bin/recycle-bin.component.js.map +1 -1
- package/dist/lib/utils/highlight.util.d.ts +6 -0
- package/dist/lib/utils/highlight.util.d.ts.map +1 -1
- package/dist/lib/utils/highlight.util.js +23 -11
- package/dist/lib/utils/highlight.util.js.map +1 -1
- package/dist/lib/utils/record.util.d.ts +10 -0
- package/dist/lib/utils/record.util.d.ts.map +1 -1
- package/dist/lib/utils/record.util.js +20 -4
- package/dist/lib/utils/record.util.js.map +1 -1
- package/dist/lib/view-config-panel/view-config-panel.component.d.ts +17 -1
- package/dist/lib/view-config-panel/view-config-panel.component.d.ts.map +1 -1
- package/dist/lib/view-config-panel/view-config-panel.component.js +39 -6
- package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
- package/dist/lib/view-selector/view-selector.component.js +2 -2
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +15 -3
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js +33 -5
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +70 -2
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js +155 -33
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +16 -2
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/map-view-renderer.component.js +37 -9
- package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/view-type.contracts.d.ts +8 -0
- package/dist/lib/view-types/view-type.contracts.d.ts.map +1 -1
- package/dist/lib/view-types/view-type.contracts.js.map +1 -1
- package/dist/lib/view-workspace/view-workspace.component.d.ts +243 -25
- package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -1
- package/dist/lib/view-workspace/view-workspace.component.js +631 -180
- package/dist/lib/view-workspace/view-workspace.component.js.map +1 -1
- package/package.json +21 -20
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
2
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
3
3
|
import { EntityInfo, RunView, EntityFieldValueListType, IsDateOnlySQLType, FormatDateOnly } from '@memberjunction/core';
|
|
4
|
-
import {
|
|
4
|
+
import { BuildCompositeKey, BuildPkString } from '../utils/record.util';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
import * as i1 from "@memberjunction/ng-shared-generic";
|
|
7
7
|
import * as i2 from "@memberjunction/ng-ui-components";
|
|
@@ -393,21 +393,109 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
393
393
|
entity = null;
|
|
394
394
|
record = null;
|
|
395
395
|
close = new EventEmitter();
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
396
|
+
OpenRecord = new EventEmitter();
|
|
397
|
+
/**
|
|
398
|
+
* @deprecated Use {@link OpenRecord}.
|
|
399
|
+
*
|
|
400
|
+
* The same emitter under the old binding name, so a template still binding
|
|
401
|
+
* (openRecord) keeps working. Must stay AFTER OpenRecord: class fields
|
|
402
|
+
* initialise in order, and the other way round this captures undefined.
|
|
403
|
+
*/
|
|
404
|
+
openRecord = this.OpenRecord;
|
|
405
|
+
NavigateToRelated = new EventEmitter();
|
|
406
|
+
/**
|
|
407
|
+
* @deprecated Use {@link NavigateToRelated}.
|
|
408
|
+
*
|
|
409
|
+
* The same emitter under the old binding name, so a template still binding
|
|
410
|
+
* (navigateToRelated) keeps working. Must stay AFTER NavigateToRelated: class fields
|
|
411
|
+
* initialise in order, and the other way round this captures undefined.
|
|
412
|
+
*/
|
|
413
|
+
navigateToRelated = this.NavigateToRelated;
|
|
414
|
+
OpenRelatedRecord = new EventEmitter();
|
|
415
|
+
/**
|
|
416
|
+
* @deprecated Use {@link OpenRelatedRecord}.
|
|
417
|
+
*
|
|
418
|
+
* The same emitter under the old binding name, so a template still binding
|
|
419
|
+
* (openRelatedRecord) keeps working. Must stay AFTER OpenRelatedRecord: class fields
|
|
420
|
+
* initialise in order, and the other way round this captures undefined.
|
|
421
|
+
*/
|
|
422
|
+
openRelatedRecord = this.OpenRelatedRecord;
|
|
423
|
+
OpenForeignKeyRecord = new EventEmitter();
|
|
424
|
+
/**
|
|
425
|
+
* @deprecated Use {@link OpenForeignKeyRecord}.
|
|
426
|
+
*
|
|
427
|
+
* The same emitter under the old binding name, so a template still binding
|
|
428
|
+
* (openForeignKeyRecord) keeps working. Must stay AFTER OpenForeignKeyRecord: class fields
|
|
429
|
+
* initialise in order, and the other way round this captures undefined.
|
|
430
|
+
*/
|
|
431
|
+
openForeignKeyRecord = this.OpenForeignKeyRecord;
|
|
400
432
|
// Related entity counts
|
|
401
|
-
|
|
402
|
-
|
|
433
|
+
RelatedEntities = [];
|
|
434
|
+
/** @deprecated Use {@link RelatedEntities}. */
|
|
435
|
+
get relatedEntities() {
|
|
436
|
+
return this.RelatedEntities;
|
|
437
|
+
}
|
|
438
|
+
/** @deprecated Use {@link RelatedEntities}. */
|
|
439
|
+
set relatedEntities(value) {
|
|
440
|
+
this.RelatedEntities = value;
|
|
441
|
+
}
|
|
442
|
+
IsLoadingRelationships = false;
|
|
443
|
+
/** @deprecated Use {@link IsLoadingRelationships}. */
|
|
444
|
+
get isLoadingRelationships() {
|
|
445
|
+
return this.IsLoadingRelationships;
|
|
446
|
+
}
|
|
447
|
+
/** @deprecated Use {@link IsLoadingRelationships}. */
|
|
448
|
+
set isLoadingRelationships(value) {
|
|
449
|
+
this.IsLoadingRelationships = value;
|
|
450
|
+
}
|
|
403
451
|
// Organic key match counts
|
|
404
|
-
|
|
405
|
-
|
|
452
|
+
OrganicKeyMatches = [];
|
|
453
|
+
/** @deprecated Use {@link OrganicKeyMatches}. */
|
|
454
|
+
get organicKeyMatches() {
|
|
455
|
+
return this.OrganicKeyMatches;
|
|
456
|
+
}
|
|
457
|
+
/** @deprecated Use {@link OrganicKeyMatches}. */
|
|
458
|
+
set organicKeyMatches(value) {
|
|
459
|
+
this.OrganicKeyMatches = value;
|
|
460
|
+
}
|
|
461
|
+
IsLoadingOrganicKeys = false;
|
|
462
|
+
/** @deprecated Use {@link IsLoadingOrganicKeys}. */
|
|
463
|
+
get isLoadingOrganicKeys() {
|
|
464
|
+
return this.IsLoadingOrganicKeys;
|
|
465
|
+
}
|
|
466
|
+
/** @deprecated Use {@link IsLoadingOrganicKeys}. */
|
|
467
|
+
set isLoadingOrganicKeys(value) {
|
|
468
|
+
this.IsLoadingOrganicKeys = value;
|
|
469
|
+
}
|
|
406
470
|
metadata = this.ProviderToUse;
|
|
407
471
|
// Sections expanded state
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
472
|
+
DetailsSectionExpanded = true;
|
|
473
|
+
/** @deprecated Use {@link DetailsSectionExpanded}. */
|
|
474
|
+
get detailsSectionExpanded() {
|
|
475
|
+
return this.DetailsSectionExpanded;
|
|
476
|
+
}
|
|
477
|
+
/** @deprecated Use {@link DetailsSectionExpanded}. */
|
|
478
|
+
set detailsSectionExpanded(value) {
|
|
479
|
+
this.DetailsSectionExpanded = value;
|
|
480
|
+
}
|
|
481
|
+
RelationshipsSectionExpanded = true;
|
|
482
|
+
/** @deprecated Use {@link RelationshipsSectionExpanded}. */
|
|
483
|
+
get relationshipsSectionExpanded() {
|
|
484
|
+
return this.RelationshipsSectionExpanded;
|
|
485
|
+
}
|
|
486
|
+
/** @deprecated Use {@link RelationshipsSectionExpanded}. */
|
|
487
|
+
set relationshipsSectionExpanded(value) {
|
|
488
|
+
this.RelationshipsSectionExpanded = value;
|
|
489
|
+
}
|
|
490
|
+
OrganicKeysSectionExpanded = true;
|
|
491
|
+
/** @deprecated Use {@link OrganicKeysSectionExpanded}. */
|
|
492
|
+
get organicKeysSectionExpanded() {
|
|
493
|
+
return this.OrganicKeysSectionExpanded;
|
|
494
|
+
}
|
|
495
|
+
/** @deprecated Use {@link OrganicKeysSectionExpanded}. */
|
|
496
|
+
set organicKeysSectionExpanded(value) {
|
|
497
|
+
this.OrganicKeysSectionExpanded = value;
|
|
498
|
+
}
|
|
411
499
|
constructor(cdr, ngZone) {
|
|
412
500
|
super();
|
|
413
501
|
this.cdr = cdr;
|
|
@@ -425,20 +513,20 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
425
513
|
async loadRelationshipCounts() {
|
|
426
514
|
if (!this.entity || !this.record)
|
|
427
515
|
return;
|
|
428
|
-
this.
|
|
429
|
-
this.
|
|
516
|
+
this.IsLoadingRelationships = true;
|
|
517
|
+
this.RelatedEntities = [];
|
|
430
518
|
// Get relationships where this entity is the related entity (foreign keys pointing TO this record)
|
|
431
519
|
const relationships = this.entity.RelatedEntities;
|
|
432
520
|
if (relationships.length === 0) {
|
|
433
|
-
this.
|
|
521
|
+
this.IsLoadingRelationships = false;
|
|
434
522
|
return;
|
|
435
523
|
}
|
|
436
524
|
// Build a CompositeKey for the current record
|
|
437
|
-
const compositeKey =
|
|
525
|
+
const compositeKey = BuildCompositeKey(this.record, this.entity);
|
|
438
526
|
// Get the first PK value for the join field filter
|
|
439
527
|
const pkValue = compositeKey.KeyValuePairs[0]?.Value;
|
|
440
528
|
if (!pkValue) {
|
|
441
|
-
this.
|
|
529
|
+
this.IsLoadingRelationships = false;
|
|
442
530
|
return;
|
|
443
531
|
}
|
|
444
532
|
// Build batch query params for all relationships
|
|
@@ -451,7 +539,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
451
539
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
452
540
|
const results = await rv.RunViews(viewParams);
|
|
453
541
|
// Map results back to relationship data
|
|
454
|
-
this.
|
|
542
|
+
this.RelatedEntities = relationships.map((rel, index) => {
|
|
455
543
|
const result = results[index];
|
|
456
544
|
return {
|
|
457
545
|
relationship: rel,
|
|
@@ -466,7 +554,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
466
554
|
catch (error) {
|
|
467
555
|
console.warn('Failed to load relationship counts:', error);
|
|
468
556
|
// Initialize with zero counts on error
|
|
469
|
-
this.
|
|
557
|
+
this.RelatedEntities = relationships.map(rel => ({
|
|
470
558
|
relationship: rel,
|
|
471
559
|
relatedEntityName: rel.RelatedEntity,
|
|
472
560
|
count: 0,
|
|
@@ -477,7 +565,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
477
565
|
}
|
|
478
566
|
finally {
|
|
479
567
|
this.ngZone.run(() => {
|
|
480
|
-
this.
|
|
568
|
+
this.IsLoadingRelationships = false;
|
|
481
569
|
this.cdr.detectChanges();
|
|
482
570
|
});
|
|
483
571
|
}
|
|
@@ -491,7 +579,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
491
579
|
return;
|
|
492
580
|
const organicKeys = this.entity.OrganicKeys;
|
|
493
581
|
if (!organicKeys || organicKeys.length === 0) {
|
|
494
|
-
this.
|
|
582
|
+
this.OrganicKeyMatches = [];
|
|
495
583
|
return;
|
|
496
584
|
}
|
|
497
585
|
// Flatten all organic key related entities
|
|
@@ -502,11 +590,11 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
502
590
|
}
|
|
503
591
|
}
|
|
504
592
|
if (allPairs.length === 0) {
|
|
505
|
-
this.
|
|
593
|
+
this.OrganicKeyMatches = [];
|
|
506
594
|
return;
|
|
507
595
|
}
|
|
508
|
-
this.
|
|
509
|
-
this.
|
|
596
|
+
this.IsLoadingOrganicKeys = true;
|
|
597
|
+
this.OrganicKeyMatches = [];
|
|
510
598
|
// Build a mock BaseEntity-like object for BuildOrganicKeyViewParams
|
|
511
599
|
// The static method only calls record.Get(fieldName), so we can duck-type it
|
|
512
600
|
const mockRecord = {
|
|
@@ -522,7 +610,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
522
610
|
try {
|
|
523
611
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
524
612
|
const results = await rv.RunViews(viewParams);
|
|
525
|
-
this.
|
|
613
|
+
this.OrganicKeyMatches = allPairs.map((pair, index) => {
|
|
526
614
|
const result = results[index];
|
|
527
615
|
return {
|
|
528
616
|
organicKey: pair.organicKey,
|
|
@@ -537,7 +625,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
537
625
|
}
|
|
538
626
|
catch (error) {
|
|
539
627
|
console.warn('Failed to load organic key counts:', error);
|
|
540
|
-
this.
|
|
628
|
+
this.OrganicKeyMatches = allPairs.map(pair => ({
|
|
541
629
|
organicKey: pair.organicKey,
|
|
542
630
|
relatedEntity: pair.relatedEntity,
|
|
543
631
|
relatedEntityName: pair.relatedEntity.DisplayName || pair.relatedEntity.RelatedEntity,
|
|
@@ -549,7 +637,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
549
637
|
}
|
|
550
638
|
finally {
|
|
551
639
|
this.ngZone.run(() => {
|
|
552
|
-
this.
|
|
640
|
+
this.IsLoadingOrganicKeys = false;
|
|
553
641
|
this.cdr.detectChanges();
|
|
554
642
|
});
|
|
555
643
|
}
|
|
@@ -557,13 +645,17 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
557
645
|
/**
|
|
558
646
|
* Get only organic key matches that have records (count > 0)
|
|
559
647
|
*/
|
|
648
|
+
get OrganicKeyMatchesWithRecords() {
|
|
649
|
+
return this.OrganicKeyMatches.filter(m => m.count > 0);
|
|
650
|
+
}
|
|
651
|
+
/** @deprecated Use {@link OrganicKeyMatchesWithRecords}. */
|
|
560
652
|
get organicKeyMatchesWithRecords() {
|
|
561
|
-
return this.
|
|
653
|
+
return this.OrganicKeyMatchesWithRecords;
|
|
562
654
|
}
|
|
563
655
|
/**
|
|
564
656
|
* Toggle expansion of an organic key match section and load records if needed
|
|
565
657
|
*/
|
|
566
|
-
async
|
|
658
|
+
async ToggleOrganicKeyExpansion(match, event) {
|
|
567
659
|
event.stopPropagation();
|
|
568
660
|
if (match.count === 0)
|
|
569
661
|
return;
|
|
@@ -572,6 +664,10 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
572
664
|
await this.loadOrganicKeyRecords(match);
|
|
573
665
|
}
|
|
574
666
|
}
|
|
667
|
+
/** @deprecated Use {@link ToggleOrganicKeyExpansion}. */
|
|
668
|
+
async toggleOrganicKeyExpansion(match, event) {
|
|
669
|
+
return this.ToggleOrganicKeyExpansion(match, event);
|
|
670
|
+
}
|
|
575
671
|
/**
|
|
576
672
|
* Load actual records for an organic key match
|
|
577
673
|
*/
|
|
@@ -616,17 +712,21 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
616
712
|
/**
|
|
617
713
|
* Handle click on an organic key record
|
|
618
714
|
*/
|
|
619
|
-
|
|
715
|
+
OnOrganicKeyRecordClick(match, record, event) {
|
|
620
716
|
event.stopPropagation();
|
|
621
|
-
this.
|
|
717
|
+
this.OpenRelatedRecord.emit({
|
|
622
718
|
entityName: match.relatedEntity.RelatedEntity,
|
|
623
719
|
record,
|
|
624
720
|
});
|
|
625
721
|
}
|
|
722
|
+
/** @deprecated Use {@link OnOrganicKeyRecordClick}. */
|
|
723
|
+
onOrganicKeyRecordClick(match, record, event) {
|
|
724
|
+
return this.OnOrganicKeyRecordClick(match, record, event);
|
|
725
|
+
}
|
|
626
726
|
/**
|
|
627
727
|
* Navigate to view all organic key matched records
|
|
628
728
|
*/
|
|
629
|
-
|
|
729
|
+
OnViewAllOrganicKey(match, event) {
|
|
630
730
|
event.stopPropagation();
|
|
631
731
|
if (!this.record || !this.entity)
|
|
632
732
|
return;
|
|
@@ -635,15 +735,19 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
635
735
|
EntityInfo: this.entity,
|
|
636
736
|
};
|
|
637
737
|
const params = EntityInfo.BuildOrganicKeyViewParams(mockRecord, match.relatedEntity, match.organicKey);
|
|
638
|
-
this.
|
|
738
|
+
this.NavigateToRelated.emit({
|
|
639
739
|
entityName: match.relatedEntity.RelatedEntity,
|
|
640
740
|
filter: String(params.ExtraFilter || ''),
|
|
641
741
|
});
|
|
642
742
|
}
|
|
743
|
+
/** @deprecated Use {@link OnViewAllOrganicKey}. */
|
|
744
|
+
onViewAllOrganicKey(match, event) {
|
|
745
|
+
return this.OnViewAllOrganicKey(match, event);
|
|
746
|
+
}
|
|
643
747
|
/**
|
|
644
748
|
* Get display name for an organic key record
|
|
645
749
|
*/
|
|
646
|
-
|
|
750
|
+
GetOrganicKeyRecordDisplayName(match, record) {
|
|
647
751
|
const entityInfo = this.metadata.Entities.find(e => e.Name === match.relatedEntity.RelatedEntity);
|
|
648
752
|
if (entityInfo?.NameField) {
|
|
649
753
|
const name = record[entityInfo.NameField.Name];
|
|
@@ -651,14 +755,18 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
651
755
|
return String(name);
|
|
652
756
|
}
|
|
653
757
|
if (entityInfo) {
|
|
654
|
-
return
|
|
758
|
+
return BuildPkString(record, entityInfo);
|
|
655
759
|
}
|
|
656
760
|
return 'Record';
|
|
657
761
|
}
|
|
762
|
+
/** @deprecated Use {@link GetOrganicKeyRecordDisplayName}. */
|
|
763
|
+
getOrganicKeyRecordDisplayName(match, record) {
|
|
764
|
+
return this.GetOrganicKeyRecordDisplayName(match, record);
|
|
765
|
+
}
|
|
658
766
|
/**
|
|
659
767
|
* Get subtitle for an organic key record
|
|
660
768
|
*/
|
|
661
|
-
|
|
769
|
+
GetOrganicKeyRecordSubtitle(match, record) {
|
|
662
770
|
const entityInfo = this.metadata.Entities.find(e => e.Name === match.relatedEntity.RelatedEntity);
|
|
663
771
|
if (!entityInfo)
|
|
664
772
|
return '';
|
|
@@ -674,20 +782,28 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
674
782
|
}
|
|
675
783
|
return '';
|
|
676
784
|
}
|
|
785
|
+
/** @deprecated Use {@link GetOrganicKeyRecordSubtitle}. */
|
|
786
|
+
getOrganicKeyRecordSubtitle(match, record) {
|
|
787
|
+
return this.GetOrganicKeyRecordSubtitle(match, record);
|
|
788
|
+
}
|
|
677
789
|
/**
|
|
678
790
|
* Get icon for an organic key matched entity
|
|
679
791
|
*/
|
|
680
|
-
|
|
792
|
+
GetOrganicKeyEntityIcon(match) {
|
|
681
793
|
const entityInfo = this.metadata.Entities.find(e => e.Name === match.relatedEntity.RelatedEntity);
|
|
682
794
|
if (entityInfo?.Icon) {
|
|
683
795
|
return this.formatEntityIcon(entityInfo.Icon);
|
|
684
796
|
}
|
|
685
797
|
return 'fa-solid fa-link';
|
|
686
798
|
}
|
|
799
|
+
/** @deprecated Use {@link GetOrganicKeyEntityIcon}. */
|
|
800
|
+
getOrganicKeyEntityIcon(match) {
|
|
801
|
+
return this.GetOrganicKeyEntityIcon(match);
|
|
802
|
+
}
|
|
687
803
|
/**
|
|
688
804
|
* Get key fields to display in details section, categorized by type
|
|
689
805
|
*/
|
|
690
|
-
get
|
|
806
|
+
get DisplayFields() {
|
|
691
807
|
if (!this.entity || !this.record)
|
|
692
808
|
return [];
|
|
693
809
|
const fields = [];
|
|
@@ -736,6 +852,10 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
736
852
|
}
|
|
737
853
|
return fields;
|
|
738
854
|
}
|
|
855
|
+
/** @deprecated Use {@link DisplayFields}. */
|
|
856
|
+
get displayFields() {
|
|
857
|
+
return this.DisplayFields;
|
|
858
|
+
}
|
|
739
859
|
/**
|
|
740
860
|
* Build display info for a foreign key field
|
|
741
861
|
* Uses RelatedEntityNameFieldMap to get the human-readable name
|
|
@@ -831,7 +951,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
831
951
|
/**
|
|
832
952
|
* Get record title
|
|
833
953
|
*/
|
|
834
|
-
get
|
|
954
|
+
get RecordTitle() {
|
|
835
955
|
if (!this.entity || !this.record)
|
|
836
956
|
return 'Record';
|
|
837
957
|
if (this.entity.NameField) {
|
|
@@ -839,26 +959,38 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
839
959
|
if (name)
|
|
840
960
|
return String(name);
|
|
841
961
|
}
|
|
842
|
-
return
|
|
962
|
+
return BuildPkString(this.record, this.entity);
|
|
963
|
+
}
|
|
964
|
+
/** @deprecated Use {@link RecordTitle}. */
|
|
965
|
+
get recordTitle() {
|
|
966
|
+
return this.RecordTitle;
|
|
843
967
|
}
|
|
844
968
|
/**
|
|
845
969
|
* Handle close button click
|
|
846
970
|
*/
|
|
847
|
-
|
|
971
|
+
OnClose() {
|
|
848
972
|
this.close.emit();
|
|
849
973
|
}
|
|
974
|
+
/** @deprecated Use {@link OnClose}. */
|
|
975
|
+
onClose() {
|
|
976
|
+
return this.OnClose();
|
|
977
|
+
}
|
|
850
978
|
/**
|
|
851
979
|
* Handle open record button click
|
|
852
980
|
*/
|
|
853
|
-
|
|
981
|
+
OnOpenRecord() {
|
|
854
982
|
if (this.record) {
|
|
855
|
-
this.
|
|
983
|
+
this.OpenRecord.emit(this.record);
|
|
856
984
|
}
|
|
857
985
|
}
|
|
986
|
+
/** @deprecated Use {@link OnOpenRecord}. */
|
|
987
|
+
onOpenRecord() {
|
|
988
|
+
return this.OnOpenRecord();
|
|
989
|
+
}
|
|
858
990
|
/**
|
|
859
991
|
* Copy primary key value to clipboard
|
|
860
992
|
*/
|
|
861
|
-
|
|
993
|
+
CopyToClipboard(value, event) {
|
|
862
994
|
event.stopPropagation();
|
|
863
995
|
navigator.clipboard.writeText(value).then(() => {
|
|
864
996
|
// Could add a toast notification here
|
|
@@ -867,31 +999,43 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
867
999
|
console.error('Failed to copy:', err);
|
|
868
1000
|
});
|
|
869
1001
|
}
|
|
1002
|
+
/** @deprecated Use {@link CopyToClipboard}. */
|
|
1003
|
+
copyToClipboard(value, event) {
|
|
1004
|
+
return this.CopyToClipboard(value, event);
|
|
1005
|
+
}
|
|
870
1006
|
/**
|
|
871
1007
|
* Open a foreign key record (FK link click)
|
|
872
1008
|
* Emits openForeignKeyRecord event for parent to handle opening the record
|
|
873
1009
|
*/
|
|
874
|
-
|
|
1010
|
+
OnForeignKeyClick(field, event) {
|
|
875
1011
|
event.stopPropagation();
|
|
876
1012
|
if (field.relatedEntityName && field.relatedRecordId) {
|
|
877
|
-
this.
|
|
1013
|
+
this.OpenForeignKeyRecord.emit({
|
|
878
1014
|
entityName: field.relatedEntityName,
|
|
879
1015
|
recordId: field.relatedRecordId
|
|
880
1016
|
});
|
|
881
1017
|
}
|
|
882
1018
|
}
|
|
1019
|
+
/** @deprecated Use {@link OnForeignKeyClick}. */
|
|
1020
|
+
onForeignKeyClick(field, event) {
|
|
1021
|
+
return this.OnForeignKeyClick(field, event);
|
|
1022
|
+
}
|
|
883
1023
|
/**
|
|
884
1024
|
* Check if a FK display value is different from the raw ID (i.e., we have a name to show)
|
|
885
1025
|
*/
|
|
886
|
-
|
|
1026
|
+
HasFriendlyName(field) {
|
|
887
1027
|
return field.type === 'foreign-key' &&
|
|
888
1028
|
field.displayValue !== undefined &&
|
|
889
1029
|
field.displayValue !== field.value;
|
|
890
1030
|
}
|
|
1031
|
+
/** @deprecated Use {@link HasFriendlyName}. */
|
|
1032
|
+
hasFriendlyName(field) {
|
|
1033
|
+
return this.HasFriendlyName(field);
|
|
1034
|
+
}
|
|
891
1035
|
/**
|
|
892
1036
|
* Toggle expansion of related entity section and load records if needed
|
|
893
1037
|
*/
|
|
894
|
-
async
|
|
1038
|
+
async ToggleRelatedEntityExpansion(relEntity, event) {
|
|
895
1039
|
event.stopPropagation();
|
|
896
1040
|
if (relEntity.count === 0)
|
|
897
1041
|
return;
|
|
@@ -901,13 +1045,17 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
901
1045
|
await this.loadRelatedRecords(relEntity);
|
|
902
1046
|
}
|
|
903
1047
|
}
|
|
1048
|
+
/** @deprecated Use {@link ToggleRelatedEntityExpansion}. */
|
|
1049
|
+
async toggleRelatedEntityExpansion(relEntity, event) {
|
|
1050
|
+
return this.ToggleRelatedEntityExpansion(relEntity, event);
|
|
1051
|
+
}
|
|
904
1052
|
/**
|
|
905
1053
|
* Load actual records for a related entity
|
|
906
1054
|
*/
|
|
907
1055
|
async loadRelatedRecords(relEntity) {
|
|
908
1056
|
if (!this.record || !this.entity)
|
|
909
1057
|
return;
|
|
910
|
-
const compositeKey =
|
|
1058
|
+
const compositeKey = BuildCompositeKey(this.record, this.entity);
|
|
911
1059
|
const pkValue = compositeKey.KeyValuePairs[0]?.Value;
|
|
912
1060
|
if (!pkValue)
|
|
913
1061
|
return;
|
|
@@ -946,33 +1094,41 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
946
1094
|
/**
|
|
947
1095
|
* Handle click on individual related record - opens in new tab
|
|
948
1096
|
*/
|
|
949
|
-
|
|
1097
|
+
OnRelatedRecordClick(relEntity, record, event) {
|
|
950
1098
|
event.stopPropagation();
|
|
951
|
-
this.
|
|
1099
|
+
this.OpenRelatedRecord.emit({
|
|
952
1100
|
entityName: relEntity.relatedEntityName,
|
|
953
1101
|
record
|
|
954
1102
|
});
|
|
955
1103
|
}
|
|
1104
|
+
/** @deprecated Use {@link OnRelatedRecordClick}. */
|
|
1105
|
+
onRelatedRecordClick(relEntity, record, event) {
|
|
1106
|
+
return this.OnRelatedRecordClick(relEntity, record, event);
|
|
1107
|
+
}
|
|
956
1108
|
/**
|
|
957
1109
|
* Navigate to view all related records (when count > 10)
|
|
958
1110
|
*/
|
|
959
|
-
|
|
1111
|
+
OnViewAllRelated(relEntity, event) {
|
|
960
1112
|
event.stopPropagation();
|
|
961
1113
|
if (!this.record || !this.entity)
|
|
962
1114
|
return;
|
|
963
|
-
const compositeKey =
|
|
1115
|
+
const compositeKey = BuildCompositeKey(this.record, this.entity);
|
|
964
1116
|
const pkValue = compositeKey.KeyValuePairs[0]?.Value;
|
|
965
1117
|
if (!pkValue)
|
|
966
1118
|
return;
|
|
967
|
-
this.
|
|
1119
|
+
this.NavigateToRelated.emit({
|
|
968
1120
|
entityName: relEntity.relatedEntityName,
|
|
969
1121
|
filter: `${relEntity.relationship.RelatedEntityJoinField}='${pkValue}'`
|
|
970
1122
|
});
|
|
971
1123
|
}
|
|
1124
|
+
/** @deprecated Use {@link OnViewAllRelated}. */
|
|
1125
|
+
onViewAllRelated(relEntity, event) {
|
|
1126
|
+
return this.OnViewAllRelated(relEntity, event);
|
|
1127
|
+
}
|
|
972
1128
|
/**
|
|
973
1129
|
* Get display name for a related record
|
|
974
1130
|
*/
|
|
975
|
-
|
|
1131
|
+
GetRelatedRecordDisplayName(relEntity, record) {
|
|
976
1132
|
const entityInfo = this.metadata.Entities.find(e => e.Name === relEntity.relatedEntityName);
|
|
977
1133
|
if (entityInfo?.NameField) {
|
|
978
1134
|
const name = record[entityInfo.NameField.Name];
|
|
@@ -980,14 +1136,18 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
980
1136
|
return String(name);
|
|
981
1137
|
}
|
|
982
1138
|
if (entityInfo) {
|
|
983
|
-
return
|
|
1139
|
+
return BuildPkString(record, entityInfo);
|
|
984
1140
|
}
|
|
985
1141
|
return 'Record';
|
|
986
1142
|
}
|
|
1143
|
+
/** @deprecated Use {@link GetRelatedRecordDisplayName}. */
|
|
1144
|
+
getRelatedRecordDisplayName(relEntity, record) {
|
|
1145
|
+
return this.GetRelatedRecordDisplayName(relEntity, record);
|
|
1146
|
+
}
|
|
987
1147
|
/**
|
|
988
1148
|
* Get subtitle/secondary info for a related record
|
|
989
1149
|
*/
|
|
990
|
-
|
|
1150
|
+
GetRelatedRecordSubtitle(relEntity, record) {
|
|
991
1151
|
const entityInfo = this.metadata.Entities.find(e => e.Name === relEntity.relatedEntityName);
|
|
992
1152
|
if (!entityInfo)
|
|
993
1153
|
return '';
|
|
@@ -1004,31 +1164,47 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
1004
1164
|
}
|
|
1005
1165
|
return '';
|
|
1006
1166
|
}
|
|
1167
|
+
/** @deprecated Use {@link GetRelatedRecordSubtitle}. */
|
|
1168
|
+
getRelatedRecordSubtitle(relEntity, record) {
|
|
1169
|
+
return this.GetRelatedRecordSubtitle(relEntity, record);
|
|
1170
|
+
}
|
|
1007
1171
|
/**
|
|
1008
1172
|
* Get only related entities that have records (count > 0)
|
|
1009
1173
|
*/
|
|
1174
|
+
get RelatedEntitiesWithRecords() {
|
|
1175
|
+
return this.RelatedEntities.filter(r => r.count > 0);
|
|
1176
|
+
}
|
|
1177
|
+
/** @deprecated Use {@link RelatedEntitiesWithRecords}. */
|
|
1010
1178
|
get relatedEntitiesWithRecords() {
|
|
1011
|
-
return this.
|
|
1179
|
+
return this.RelatedEntitiesWithRecords;
|
|
1012
1180
|
}
|
|
1013
1181
|
/**
|
|
1014
1182
|
* Get icon for related entity by looking up EntityInfo from Metadata
|
|
1015
1183
|
*/
|
|
1016
|
-
|
|
1184
|
+
GetRelatedEntityIcon(relEntity) {
|
|
1017
1185
|
const entityInfo = this.metadata.Entities.find(e => e.Name === relEntity.relatedEntityName);
|
|
1018
1186
|
if (entityInfo?.Icon) {
|
|
1019
1187
|
return this.formatEntityIcon(entityInfo.Icon);
|
|
1020
1188
|
}
|
|
1021
1189
|
return 'fa-solid fa-table';
|
|
1022
1190
|
}
|
|
1191
|
+
/** @deprecated Use {@link GetRelatedEntityIcon}. */
|
|
1192
|
+
getRelatedEntityIcon(relEntity) {
|
|
1193
|
+
return this.GetRelatedEntityIcon(relEntity);
|
|
1194
|
+
}
|
|
1023
1195
|
/**
|
|
1024
1196
|
* Get the icon class for the current entity
|
|
1025
1197
|
*/
|
|
1026
|
-
|
|
1198
|
+
GetEntityIconClass() {
|
|
1027
1199
|
if (!this.entity?.Icon) {
|
|
1028
1200
|
return 'fa-solid fa-table';
|
|
1029
1201
|
}
|
|
1030
1202
|
return this.formatEntityIcon(this.entity.Icon);
|
|
1031
1203
|
}
|
|
1204
|
+
/** @deprecated Use {@link GetEntityIconClass}. */
|
|
1205
|
+
getEntityIconClass() {
|
|
1206
|
+
return this.GetEntityIconClass();
|
|
1207
|
+
}
|
|
1032
1208
|
/**
|
|
1033
1209
|
* Format entity icon to ensure proper Font Awesome class format
|
|
1034
1210
|
*/
|
|
@@ -1051,7 +1227,7 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
1051
1227
|
return `fa-solid fa-${icon}`;
|
|
1052
1228
|
}
|
|
1053
1229
|
static ɵfac = function EntityRecordDetailPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || EntityRecordDetailPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
|
|
1054
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordDetailPanelComponent, selectors: [["mj-entity-record-detail-panel"]], inputs: { entity: "entity", record: "record" }, outputs: { close: "close", openRecord: "openRecord", navigateToRelated: "navigateToRelated", openRelatedRecord: "openRelatedRecord", openForeignKeyRecord: "openForeignKeyRecord" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 24, vars: 9, consts: [[1, "entity-record-card-container"], [1, "panel-header"], [1, "panel-title-row"], [1, "entity-icon", 3, "class"], [1, "panel-title"], ["title", "Close", "aria-label", "Close panel", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [3, "ExpandedChange", "Expanded", "TitleIconMuted"], ["mjAccordionTitle", ""], ["Size", "compact", "Icon", "fa-solid fa-circle-info", "Title", "No details available"], [1, "relationships-loading"], ["Size", "compact", "Icon", "fa-solid fa-diagram-project", "Title", "No related records"], [3, "Expanded", "TitleIconMuted"], [1, "panel-footer"], [1, "open-record-btn", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "entity-icon"], [1, "fa-solid", "fa-info-circle"], [1, "field-row", "field-row-pk"], [1, "field-row", "field-row-fk"], [1, "field-row"], [1, "pk-row"], [1, "fa-solid", "fa-key", "pk-icon"], [1, "field-label"], ["title", "Copy ID", 1, "copy-btn", 3, "click"], [1, "fa-solid", "fa-copy"], [1, "fk-value-row"], [1, "field-value", "fk-display-value"], [1, "field-value", "fk-id-value"], [1, "fk-link-btn", 3, "title"], [1, "fk-link-btn", 3, "click", "title"], [3, "value"], [1, "field-value"], [1, "fa-solid", "fa-project-diagram"], ["text", "Loading related records...", "size", "small"], [1, "related-entity-group", 3, "expanded"], [1, "related-entity-group"], [1, "related-entity-header", 3, "click"], [1, "fa-solid", "expand-chevron"], [1, "related-entity-name"], [1, "related-entity-count"], [1, "related-records-list"], [1, "records-loading"], ["text", "Loading...", "size", "small"], [1, "related-record-item"], [1, "view-all-link"], [1, "related-record-item", 3, "click"], [1, "record-info"], [1, "record-name"], [1, "record-subtitle"], [1, "fa-solid", "fa-external-link-alt", "record-open-icon"], [1, "view-all-link", 3, "click"], [1, "fa-solid", "fa-arrow-right"], ["Size", "compact", "Icon", "fa-solid fa-link", "Title", "No organic key matches"], [1, "fa-solid", "fa-link"], ["text", "Loading organic key matches...", "size", "small"]], template: function EntityRecordDetailPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1230
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordDetailPanelComponent, selectors: [["mj-entity-record-detail-panel"]], inputs: { entity: "entity", record: "record" }, outputs: { close: "close", OpenRecord: "OpenRecord", openRecord: "openRecord", NavigateToRelated: "NavigateToRelated", navigateToRelated: "navigateToRelated", OpenRelatedRecord: "OpenRelatedRecord", openRelatedRecord: "openRelatedRecord", OpenForeignKeyRecord: "OpenForeignKeyRecord", openForeignKeyRecord: "openForeignKeyRecord" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 24, vars: 9, consts: [[1, "entity-record-card-container"], [1, "panel-header"], [1, "panel-title-row"], [1, "entity-icon", 3, "class"], [1, "panel-title"], ["title", "Close", "aria-label", "Close panel", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [3, "ExpandedChange", "Expanded", "TitleIconMuted"], ["mjAccordionTitle", ""], ["Size", "compact", "Icon", "fa-solid fa-circle-info", "Title", "No details available"], [1, "relationships-loading"], ["Size", "compact", "Icon", "fa-solid fa-diagram-project", "Title", "No related records"], [3, "Expanded", "TitleIconMuted"], [1, "panel-footer"], [1, "open-record-btn", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "entity-icon"], [1, "fa-solid", "fa-info-circle"], [1, "field-row", "field-row-pk"], [1, "field-row", "field-row-fk"], [1, "field-row"], [1, "pk-row"], [1, "fa-solid", "fa-key", "pk-icon"], [1, "field-label"], ["title", "Copy ID", 1, "copy-btn", 3, "click"], [1, "fa-solid", "fa-copy"], [1, "fk-value-row"], [1, "field-value", "fk-display-value"], [1, "field-value", "fk-id-value"], [1, "fk-link-btn", 3, "title"], [1, "fk-link-btn", 3, "click", "title"], [3, "value"], [1, "field-value"], [1, "fa-solid", "fa-project-diagram"], ["text", "Loading related records...", "size", "small"], [1, "related-entity-group", 3, "expanded"], [1, "related-entity-group"], [1, "related-entity-header", 3, "click"], [1, "fa-solid", "expand-chevron"], [1, "related-entity-name"], [1, "related-entity-count"], [1, "related-records-list"], [1, "records-loading"], ["text", "Loading...", "size", "small"], [1, "related-record-item"], [1, "view-all-link"], [1, "related-record-item", 3, "click"], [1, "record-info"], [1, "record-name"], [1, "record-subtitle"], [1, "fa-solid", "fa-external-link-alt", "record-open-icon"], [1, "view-all-link", 3, "click"], [1, "fa-solid", "fa-arrow-right"], ["Size", "compact", "Icon", "fa-solid fa-link", "Title", "No organic key matches"], [1, "fa-solid", "fa-link"], ["text", "Loading organic key matches...", "size", "small"]], template: function EntityRecordDetailPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1055
1231
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
|
|
1056
1232
|
i0.ɵɵconditionalCreate(3, EntityRecordDetailPanelComponent_Conditional_3_Template, 1, 2, "i", 3);
|
|
1057
1233
|
i0.ɵɵelementStart(4, "h3", 4);
|
|
@@ -1109,12 +1285,20 @@ export class EntityRecordDetailPanelComponent extends BaseAngularComponent {
|
|
|
1109
1285
|
type: Input
|
|
1110
1286
|
}], close: [{
|
|
1111
1287
|
type: Output
|
|
1288
|
+
}], OpenRecord: [{
|
|
1289
|
+
type: Output
|
|
1112
1290
|
}], openRecord: [{
|
|
1113
1291
|
type: Output
|
|
1292
|
+
}], NavigateToRelated: [{
|
|
1293
|
+
type: Output
|
|
1114
1294
|
}], navigateToRelated: [{
|
|
1115
1295
|
type: Output
|
|
1296
|
+
}], OpenRelatedRecord: [{
|
|
1297
|
+
type: Output
|
|
1116
1298
|
}], openRelatedRecord: [{
|
|
1117
1299
|
type: Output
|
|
1300
|
+
}], OpenForeignKeyRecord: [{
|
|
1301
|
+
type: Output
|
|
1118
1302
|
}], openForeignKeyRecord: [{
|
|
1119
1303
|
type: Output
|
|
1120
1304
|
}] }); })();
|