@memberjunction/ng-list-management 5.34.1 → 5.36.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/README.md +179 -85
- package/dist/lib/components/audience-source-picker/audience-source-picker.component.d.ts +74 -0
- package/dist/lib/components/audience-source-picker/audience-source-picker.component.d.ts.map +1 -0
- package/dist/lib/components/audience-source-picker/audience-source-picker.component.js +396 -0
- package/dist/lib/components/audience-source-picker/audience-source-picker.component.js.map +1 -0
- package/dist/lib/components/audience-source-summary/audience-source-summary.component.d.ts +34 -0
- package/dist/lib/components/audience-source-summary/audience-source-summary.component.d.ts.map +1 -0
- package/dist/lib/components/audience-source-summary/audience-source-summary.component.js +136 -0
- package/dist/lib/components/audience-source-summary/audience-source-summary.component.js.map +1 -0
- package/dist/lib/components/list-audit-log/list-audit-log.component.d.ts +55 -0
- package/dist/lib/components/list-audit-log/list-audit-log.component.d.ts.map +1 -0
- package/dist/lib/components/list-audit-log/list-audit-log.component.js +280 -0
- package/dist/lib/components/list-audit-log/list-audit-log.component.js.map +1 -0
- package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.d.ts +64 -0
- package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.d.ts.map +1 -0
- package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.js +323 -0
- package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.js.map +1 -0
- package/dist/lib/components/list-invitations/list-invitations.component.d.ts +60 -0
- package/dist/lib/components/list-invitations/list-invitations.component.d.ts.map +1 -0
- package/dist/lib/components/list-invitations/list-invitations.component.js +367 -0
- package/dist/lib/components/list-invitations/list-invitations.component.js.map +1 -0
- package/dist/lib/components/list-management-dialog/list-management-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/list-management-dialog/list-management-dialog.component.js +0 -4
- package/dist/lib/components/list-management-dialog/list-management-dialog.component.js.map +1 -1
- package/dist/lib/components/list-share-dialog/list-share-dialog.component.d.ts +18 -1
- package/dist/lib/components/list-share-dialog/list-share-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/list-share-dialog/list-share-dialog.component.js +115 -66
- package/dist/lib/components/list-share-dialog/list-share-dialog.component.js.map +1 -1
- package/dist/lib/components/list-stats/list-stats.component.d.ts +52 -0
- package/dist/lib/components/list-stats/list-stats.component.d.ts.map +1 -0
- package/dist/lib/components/list-stats/list-stats.component.js +283 -0
- package/dist/lib/components/list-stats/list-stats.component.js.map +1 -0
- package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.d.ts +68 -0
- package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.d.ts.map +1 -0
- package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.js +316 -0
- package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.js.map +1 -0
- package/dist/lib/components/shared-with-me/shared-with-me.component.d.ts +47 -0
- package/dist/lib/components/shared-with-me/shared-with-me.component.d.ts.map +1 -0
- package/dist/lib/components/shared-with-me/shared-with-me.component.js +231 -0
- package/dist/lib/components/shared-with-me/shared-with-me.component.js.map +1 -0
- package/dist/lib/components/tag-chips/tag-chips.component.d.ts +85 -0
- package/dist/lib/components/tag-chips/tag-chips.component.d.ts.map +1 -0
- package/dist/lib/components/tag-chips/tag-chips.component.js +392 -0
- package/dist/lib/components/tag-chips/tag-chips.component.js.map +1 -0
- package/dist/lib/models/list-sharing.models.d.ts +5 -0
- package/dist/lib/models/list-sharing.models.d.ts.map +1 -1
- package/dist/lib/models/list-sharing.models.js.map +1 -1
- package/dist/lib/module.d.ts +17 -8
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +51 -6
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/services/list-management.service.d.ts.map +1 -1
- package/dist/lib/services/list-management.service.js +0 -9
- package/dist/lib/services/list-management.service.js.map +1 -1
- package/dist/lib/services/list-sharing.service.d.ts +8 -3
- package/dist/lib/services/list-sharing.service.d.ts.map +1 -1
- package/dist/lib/services/list-sharing.service.js +33 -15
- package/dist/lib/services/list-sharing.service.js.map +1 -1
- package/dist/public-api.d.ts +9 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +9 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +13 -11
package/dist/lib/module.js
CHANGED
|
@@ -7,8 +7,17 @@ import { MJButtonDirective, MJDialogComponent, MJDialogActionsComponent, MJDropd
|
|
|
7
7
|
import { ContainerDirectivesModule } from '@memberjunction/ng-container-directives';
|
|
8
8
|
import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
|
|
9
9
|
// Components
|
|
10
|
+
import { AudienceSourcePickerComponent } from './components/audience-source-picker/audience-source-picker.component';
|
|
11
|
+
import { AudienceSourceSummaryComponent } from './components/audience-source-summary/audience-source-summary.component';
|
|
12
|
+
import { ListAuditLogComponent } from './components/list-audit-log/list-audit-log.component';
|
|
13
|
+
import { ListDeltaConfirmComponent } from './components/list-delta-confirm/list-delta-confirm.component';
|
|
14
|
+
import { ListInvitationsComponent } from './components/list-invitations/list-invitations.component';
|
|
10
15
|
import { ListManagementDialogComponent } from './components/list-management-dialog/list-management-dialog.component';
|
|
11
16
|
import { ListShareDialogComponent } from './components/list-share-dialog/list-share-dialog.component';
|
|
17
|
+
import { ListStatsComponent } from './components/list-stats/list-stats.component';
|
|
18
|
+
import { ListsSharedWithMeComponent } from './components/shared-with-me/shared-with-me.component';
|
|
19
|
+
import { SaveViewAsListDialogComponent } from './components/save-view-as-list-dialog/save-view-as-list-dialog.component';
|
|
20
|
+
import { TagChipsComponent } from './components/tag-chips/tag-chips.component';
|
|
12
21
|
// Services
|
|
13
22
|
import { ListManagementService } from './services/list-management.service';
|
|
14
23
|
import { ListSharingService } from './services/list-sharing.service';
|
|
@@ -34,8 +43,17 @@ export class ListManagementModule {
|
|
|
34
43
|
type: NgModule,
|
|
35
44
|
args: [{
|
|
36
45
|
declarations: [
|
|
46
|
+
AudienceSourcePickerComponent,
|
|
47
|
+
AudienceSourceSummaryComponent,
|
|
48
|
+
ListAuditLogComponent,
|
|
49
|
+
ListDeltaConfirmComponent,
|
|
50
|
+
ListInvitationsComponent,
|
|
37
51
|
ListManagementDialogComponent,
|
|
38
|
-
ListShareDialogComponent
|
|
52
|
+
ListShareDialogComponent,
|
|
53
|
+
ListStatsComponent,
|
|
54
|
+
ListsSharedWithMeComponent,
|
|
55
|
+
SaveViewAsListDialogComponent,
|
|
56
|
+
TagChipsComponent
|
|
39
57
|
],
|
|
40
58
|
imports: [
|
|
41
59
|
CommonModule,
|
|
@@ -48,8 +66,17 @@ export class ListManagementModule {
|
|
|
48
66
|
SharedGenericModule
|
|
49
67
|
],
|
|
50
68
|
exports: [
|
|
69
|
+
AudienceSourcePickerComponent,
|
|
70
|
+
AudienceSourceSummaryComponent,
|
|
71
|
+
ListAuditLogComponent,
|
|
72
|
+
ListDeltaConfirmComponent,
|
|
73
|
+
ListInvitationsComponent,
|
|
51
74
|
ListManagementDialogComponent,
|
|
52
|
-
ListShareDialogComponent
|
|
75
|
+
ListShareDialogComponent,
|
|
76
|
+
ListStatsComponent,
|
|
77
|
+
ListsSharedWithMeComponent,
|
|
78
|
+
SaveViewAsListDialogComponent,
|
|
79
|
+
TagChipsComponent
|
|
53
80
|
],
|
|
54
81
|
providers: [
|
|
55
82
|
ListManagementService,
|
|
@@ -57,14 +84,32 @@ export class ListManagementModule {
|
|
|
57
84
|
]
|
|
58
85
|
}]
|
|
59
86
|
}], null, null); })();
|
|
60
|
-
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(ListManagementModule, { declarations: [
|
|
61
|
-
|
|
87
|
+
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(ListManagementModule, { declarations: [AudienceSourcePickerComponent,
|
|
88
|
+
AudienceSourceSummaryComponent,
|
|
89
|
+
ListAuditLogComponent,
|
|
90
|
+
ListDeltaConfirmComponent,
|
|
91
|
+
ListInvitationsComponent,
|
|
92
|
+
ListManagementDialogComponent,
|
|
93
|
+
ListShareDialogComponent,
|
|
94
|
+
ListStatsComponent,
|
|
95
|
+
ListsSharedWithMeComponent,
|
|
96
|
+
SaveViewAsListDialogComponent,
|
|
97
|
+
TagChipsComponent], imports: [CommonModule,
|
|
62
98
|
FormsModule,
|
|
63
99
|
MJButtonDirective,
|
|
64
100
|
MJDialogComponent,
|
|
65
101
|
MJDialogActionsComponent,
|
|
66
102
|
MJDropdownComponent,
|
|
67
103
|
ContainerDirectivesModule,
|
|
68
|
-
SharedGenericModule], exports: [
|
|
69
|
-
|
|
104
|
+
SharedGenericModule], exports: [AudienceSourcePickerComponent,
|
|
105
|
+
AudienceSourceSummaryComponent,
|
|
106
|
+
ListAuditLogComponent,
|
|
107
|
+
ListDeltaConfirmComponent,
|
|
108
|
+
ListInvitationsComponent,
|
|
109
|
+
ListManagementDialogComponent,
|
|
110
|
+
ListShareDialogComponent,
|
|
111
|
+
ListStatsComponent,
|
|
112
|
+
ListsSharedWithMeComponent,
|
|
113
|
+
SaveViewAsListDialogComponent,
|
|
114
|
+
TagChipsComponent] }); })();
|
|
70
115
|
//# sourceMappingURL=module.js.map
|
package/dist/lib/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,mBAAmB;AACnB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAE1C,yBAAyB;AACzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,aAAa;AACb,OAAO,EAAE,6BAA6B,EAAE,MAAM,sEAAsE,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,4DAA4D,CAAC;
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"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","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\n// MJ UI Components\nimport {\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent\n} from '@memberjunction/ng-ui-components';\n\n// MemberJunction imports\nimport { ContainerDirectivesModule } from '@memberjunction/ng-container-directives';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\n\n// Components\nimport { AudienceSourcePickerComponent } from './components/audience-source-picker/audience-source-picker.component';\nimport { AudienceSourceSummaryComponent } from './components/audience-source-summary/audience-source-summary.component';\nimport { ListAuditLogComponent } from './components/list-audit-log/list-audit-log.component';\nimport { ListDeltaConfirmComponent } from './components/list-delta-confirm/list-delta-confirm.component';\nimport { ListInvitationsComponent } from './components/list-invitations/list-invitations.component';\nimport { ListManagementDialogComponent } from './components/list-management-dialog/list-management-dialog.component';\nimport { ListShareDialogComponent } from './components/list-share-dialog/list-share-dialog.component';\nimport { ListStatsComponent } from './components/list-stats/list-stats.component';\nimport { ListsSharedWithMeComponent } from './components/shared-with-me/shared-with-me.component';\nimport { SaveViewAsListDialogComponent } from './components/save-view-as-list-dialog/save-view-as-list-dialog.component';\nimport { TagChipsComponent } from './components/tag-chips/tag-chips.component';\n\n// Services\nimport { ListManagementService } from './services/list-management.service';\nimport { ListSharingService } from './services/list-sharing.service';\n\n/**\n * Module providing list management components for MemberJunction.\n */\n@NgModule({\n declarations: [\n AudienceSourcePickerComponent,\n AudienceSourceSummaryComponent,\n ListAuditLogComponent,\n ListDeltaConfirmComponent,\n ListInvitationsComponent,\n ListManagementDialogComponent,\n ListShareDialogComponent,\n ListStatsComponent,\n ListsSharedWithMeComponent,\n SaveViewAsListDialogComponent,\n TagChipsComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent,\n ContainerDirectivesModule,\n SharedGenericModule\n ],\n exports: [\n AudienceSourcePickerComponent,\n AudienceSourceSummaryComponent,\n ListAuditLogComponent,\n ListDeltaConfirmComponent,\n ListInvitationsComponent,\n ListManagementDialogComponent,\n ListShareDialogComponent,\n ListStatsComponent,\n ListsSharedWithMeComponent,\n SaveViewAsListDialogComponent,\n TagChipsComponent\n ],\n providers: [\n ListManagementService,\n ListSharingService\n ]\n})\nexport class ListManagementModule { }\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-management.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/list-management.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAA+B,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAEpB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;;AAO1C;;;;;;GAMG;AACH,qBAGa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAG9C,OAAO,CAAC,SAAS,CAAiD;IAClE,OAAO,CAAC,aAAa,CAAmD;IACxE,OAAO,CAAC,eAAe,CAAwD;IAG/E,OAAO,CAAC,cAAc,CAAuC;IACtD,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;IAE1E,OAAO,CAAC,SAAS,CAAkC;IAEnD,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;;IAID;;OAEG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,YAAY,EAAE,CAAC;IA4C1B;;OAEG;IACG,iBAAiB,CAAC,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAuBvF;;;OAGG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAiDjC;;OAEG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC;IA2B1B;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvD;;OAEG;IACG,mBAAmB,CACvB,KAAK,EAAE,YAAY,EAAE,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAChC,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA+C/B;;OAEG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,cAAc,GAAE,OAAc,GAC7B,OAAO,CAAC,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"list-management.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/list-management.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAA+B,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAEpB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;;AAO1C;;;;;;GAMG;AACH,qBAGa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAG9C,OAAO,CAAC,SAAS,CAAiD;IAClE,OAAO,CAAC,aAAa,CAAmD;IACxE,OAAO,CAAC,eAAe,CAAwD;IAG/E,OAAO,CAAC,cAAc,CAAuC;IACtD,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;IAE1E,OAAO,CAAC,SAAS,CAAkC;IAEnD,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;;IAID;;OAEG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,YAAY,EAAE,CAAC;IA4C1B;;OAEG;IACG,iBAAiB,CAAC,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAuBvF;;;OAGG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAiDjC;;OAEG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC;IA2B1B;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvD;;OAEG;IACG,mBAAmB,CACvB,KAAK,EAAE,YAAY,EAAE,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAChC,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA+C/B;;OAEG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,cAAc,GAAE,OAAc,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IAwFhC;;OAEG;IACG,sBAAsB,CAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,oBAAoB,CAAC;IAiDhC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA6BxE;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAUxC;;OAEG;IACH,OAAO,CAAC,mBAAmB;yCAhdhB,qBAAqB;6CAArB,qBAAqB;CAwdjC"}
|
|
@@ -217,10 +217,6 @@ export class ListManagementService {
|
|
|
217
217
|
* Add records to one or more lists
|
|
218
218
|
*/
|
|
219
219
|
async addRecordsToLists(listIds, recordIds, skipDuplicates = true) {
|
|
220
|
-
console.log(`[ListManagementService] addRecordsToLists called:`);
|
|
221
|
-
console.log(` - listIds (${listIds.length}):`, listIds);
|
|
222
|
-
console.log(` - recordIds (${recordIds.length}):`, recordIds);
|
|
223
|
-
console.log(` - skipDuplicates:`, skipDuplicates);
|
|
224
220
|
const result = {
|
|
225
221
|
success: 0,
|
|
226
222
|
failed: 0,
|
|
@@ -261,7 +257,6 @@ export class ListManagementService {
|
|
|
261
257
|
}
|
|
262
258
|
}
|
|
263
259
|
if (recordsToAdd.length === 0) {
|
|
264
|
-
console.log(`[ListManagementService] No records to add (all skipped as duplicates)`);
|
|
265
260
|
return result;
|
|
266
261
|
}
|
|
267
262
|
// Use transaction group for bulk insert
|
|
@@ -285,22 +280,18 @@ export class ListManagementService {
|
|
|
285
280
|
}
|
|
286
281
|
}
|
|
287
282
|
// Submit the transaction
|
|
288
|
-
console.log(`[ListManagementService] Submitting transaction with ${recordsToAdd.length} records...`);
|
|
289
283
|
const success = await tg.Submit();
|
|
290
284
|
if (success) {
|
|
291
285
|
result.success = recordsToAdd.length - result.errors.length;
|
|
292
286
|
result.failed = result.errors.length;
|
|
293
|
-
console.log(`[ListManagementService] Transaction succeeded. Added ${result.success} records.`);
|
|
294
287
|
}
|
|
295
288
|
else {
|
|
296
289
|
result.failed = recordsToAdd.length;
|
|
297
290
|
result.success = 0;
|
|
298
|
-
console.error(`[ListManagementService] Transaction failed`);
|
|
299
291
|
result.errors.push('Transaction failed to submit');
|
|
300
292
|
}
|
|
301
293
|
// Invalidate membership cache
|
|
302
294
|
this.membershipCache.clear();
|
|
303
|
-
console.log(`[ListManagementService] addRecordsToLists final result:`, result);
|
|
304
295
|
return result;
|
|
305
296
|
}
|
|
306
297
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-management.service.js","sourceRoot":"","sources":["../../../src/lib/services/list-management.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAqB,QAAQ,EAAE,OAAO,EAAY,MAAM,sBAAsB,CAAC;AAEtF,OAAO,EAAE,eAAe,EAAc,MAAM,MAAM,CAAC;;AAanD;;;;;;GAMG;AAIH,MAAM,OAAO,qBAAqB;IACf,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;IAE3D,gBAAgB;IACR,SAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IAC1D,aAAa,GAA8C,IAAI,CAAC;IAChE,eAAe,GAAG,IAAI,GAAG,EAA6C,CAAC;IAE/E,yBAAyB;IACjB,cAAc,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC,CAAC;IACtD,QAAQ,GAAwB,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;IAElE,SAAS,GAA6B,IAAI,CAAC;IAEnD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAC7C,CAAC;IACD,IAAW,QAAQ,CAAC,KAA+B;QACjD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,gBAAe,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,QAAgB,EAChB,MAAe,EACf,eAAwB,KAAK;QAE7B,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAElD,oBAAoB;QACpB,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,OAAO,MAAM,CAAC,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,MAAM,GAAG,eAAe,QAAQ,GAAG,CAAC;YAExC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,kBAAkB,MAAM,GAAG,CAAC;YACxC,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;gBAC5C,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,MAAM;gBACnB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,eAAe;aAC5B,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;gBACnC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE;oBAC3B,IAAI,EAAE,KAAK;oBACX,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC5D,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,eAAwB,KAAK;QACnD,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACjF,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACjC,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAuB;YACpD,UAAU,EAAE,qBAAqB;YACjC,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,aAAa,GAAG;gBACnB,IAAI,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;gBAC1B,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC;YACF,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACjC,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB,CACvB,QAAgB,EAChB,SAAmB;QAEnB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAE7D,cAAc;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACxC,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEvD,yCAAyC;YACzC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;gBAClD,UAAU,EAAE,kBAAkB;gBAC9B,WAAW,EAAE,gBAAgB,cAAc,GAAG;gBAC9C,UAAU,EAAE,eAAe;aAC5B,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;YAE/C,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpC,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBAC5D,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC/C,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACxC,CAAC;oBACD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE;gBACjC,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC;YAEH,OAAO,UAAU,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,QAAgB,EAChB,QAAgB;QAEhB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,mCAAmC;QACnC,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;YACzD,UAAU,EAAE,kBAAkB;YAC9B,WAAW,EAAE,eAAe,QAAQ,GAAG;YACvC,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3F,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAE7F,mCAAmC;QACnC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YACjD,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,UAAU,YAAY,qBAAqB,QAAQ,GAAG;YACnE,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC9B,UAAU,EAAE,kBAAkB;YAC9B,WAAW,EAAE,aAAa,MAAM,GAAG;YACnC,UAAU,EAAE,YAAY;SACzB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CACvB,KAAqB,EACrB,SAAmB,EACnB,UAAiC;QAEjC,MAAM,UAAU,GAAwB,EAAE,CAAC;QAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,mDAAmD;QACnD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE5D,+EAA+E;QAC/E,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;YACxD,UAAU,EAAE,kBAAkB;YAC9B,WAAW,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK;YACvE,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,kBAAkB;QAClB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACjD,KAAK,MAAM,MAAM,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACjD,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACtD,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC;YAC/C,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC;YAEvC,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI;gBACJ,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBACrC,eAAe;gBACf,oBAAoB,EAAE,aAAa;gBACnC,YAAY,EAAE,eAAe,KAAK,aAAa,IAAI,aAAa,GAAG,CAAC;gBACpE,eAAe,EAAE,eAAe,GAAG,CAAC,IAAI,eAAe,GAAG,aAAa;gBACvE,WAAW,EAAE,eAAe,KAAK,CAAC;gBAClC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAS,IAAI,IAAI,IAAI,EAAE;gBAC7D,QAAQ,EAAE,SAAS,EAAE,wCAAwC;gBAC7D,gBAAgB,EAAE,KAAK;gBACvB,mBAAmB,EAAE,KAAK;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,OAAiB,EACjB,SAAmB,EACnB,iBAA0B,IAAI;QAE9B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,MAAM,IAAI,EAAE,OAAO,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,CAAC,MAAM,IAAI,EAAE,SAAS,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAyB;YACnC,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,EAAE;SACX,CAAC;QAEF,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEzB,6CAA6C;QAC7C,IAAI,kBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAC;QACxD,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5D,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEhE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;gBACpD,UAAU,EAAE,kBAAkB;gBAC9B,WAAW,EAAE,cAAc,YAAY,sBAAsB,cAAc,GAAG;gBAC9E,UAAU,EAAE,eAAe;aAC5B,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;YAEnB,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACzC,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACtC,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;oBACrE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBAC/B,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,MAAM,YAAY,GAA8C,EAAE,CAAC;QACnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;YACpE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,IAAI,cAAc,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACpD,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;YACrF,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,wCAAwC;QACxC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,sBAAsB,EAAE,CAAC;QAE7C,KAAK,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,YAAY,EAAE,CAAC;YAChD,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAAqB,kBAAkB,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;gBACpG,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;gBAC3B,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAC/B,UAAU,CAAC,gBAAgB,GAAG,EAAE,CAAC;gBACjC,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;gBAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,OAAO,CAAC,KAAK,CAAC,kDAAkD,QAAQ,aAAa,MAAM,GAAG,EAAE,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;oBAClI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,QAAQ,YAAY,MAAM,KAAK,UAAU,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;gBACnI,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;gBACzE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,QAAQ,YAAY,MAAM,KAAK,YAAY,EAAE,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,uDAAuD,YAAY,CAAC,MAAM,aAAa,CAAC,CAAC;QACrG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;QAElC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,GAAG,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5D,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,wDAAwD,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;QACjG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;YACpC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QACrD,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAE7B,OAAO,CAAC,GAAG,CAAC,yDAAyD,EAAE,MAAM,CAAC,CAAC;QAC/E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAC1B,OAAiB,EACjB,SAAmB;QAEnB,MAAM,MAAM,GAAyB;YACnC,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,EAAE;SACX,CAAC;QAEF,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,uCAAuC;QACvC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhE,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;YAC1D,UAAU,EAAE,kBAAkB;YAC9B,WAAW,EAAE,cAAc,YAAY,sBAAsB,cAAc,GAAG;YAC9E,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YAC5D,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,8BAA8B;QAC9B,KAAK,MAAM,MAAM,IAAI,cAAc,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3C,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,MAAM,EAAE,CAAC;oBAChB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,MAAM,CAAC,QAAQ,cAAc,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC9F,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAE7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,MAAwB;QACvC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,eAAe,CAAe,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;YACjF,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAChC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;YAEhC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YACtC,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,UAAU,EAAE,CAAC;gBACf,wBAAwB;gBACxB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,YAAY,CAAI,KAAoB;QAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,QAAiB;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,QAAgB;QAC1C,yDAAyD;QACzD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;YACxC,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;+GAjeU,qBAAqB;gEAArB,qBAAqB,WAArB,qBAAqB,mBAFpB,MAAM;;iFAEP,qBAAqB;cAHjC,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport { MJListEntity, MJListDetailEntity, MJListCategoryEntity } from '@memberjunction/core-entities';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport {\n ListItemViewModel,\n BatchOperationResult,\n RecordMembershipInfo,\n CreateListConfig\n} from '../models/list-management.models';\n\ninterface CacheEntry<T> {\n data: T;\n timestamp: Date;\n}\n\n/**\n * Service for managing list operations including data loading, caching,\n * and batch add/remove operations.\n *\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ListManagementService {\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n // Cache storage\n private listCache = new Map<string, CacheEntry<MJListEntity[]>>();\n private categoryCache: CacheEntry<MJListCategoryEntity[]> | null = null;\n private membershipCache = new Map<string, CacheEntry<Map<string, string[]>>>();\n\n // Loading state subjects\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n private _provider: IMetadataProvider | null = null;\n\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n constructor() {}\n\n /**\n * Get lists for a specific entity, with optional caching\n */\n async getListsForEntity(\n entityId: string,\n userId?: string,\n forceRefresh: boolean = false\n ): Promise<MJListEntity[]> {\n const cacheKey = `${entityId}_${userId || 'all'}`;\n\n // Check cache first\n if (!forceRefresh) {\n const cached = this.listCache.get(cacheKey);\n if (cached && this.isCacheValid(cached)) {\n return cached.data;\n }\n }\n\n this.loadingSubject.next(true);\n\n try {\n const rv = RunView.FromMetadataProvider(this.Provider);\n let filter = `EntityID = '${entityId}'`;\n\n if (userId) {\n filter += ` AND UserID = '${userId}'`;\n }\n\n const result = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: filter,\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n const lists = result.Results || [];\n this.listCache.set(cacheKey, {\n data: lists,\n timestamp: new Date()\n });\n return lists;\n } else {\n console.error('Failed to load lists:', result.ErrorMessage);\n return [];\n }\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get all list categories\n */\n async getListCategories(forceRefresh: boolean = false): Promise<MJListCategoryEntity[]> {\n if (!forceRefresh && this.categoryCache && this.isCacheValid(this.categoryCache)) {\n return this.categoryCache.data;\n }\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<MJListCategoryEntity>({\n EntityName: 'MJ: List Categories',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.categoryCache = {\n data: result.Results || [],\n timestamp: new Date()\n };\n return this.categoryCache.data;\n }\n\n return [];\n }\n\n /**\n * Get membership information for a set of records\n * Returns a Map where key is listId and value is array of recordIds that are members\n */\n async getRecordMembership(\n entityId: string,\n recordIds: string[]\n ): Promise<Map<string, string[]>> {\n if (recordIds.length === 0) {\n return new Map();\n }\n\n const cacheKey = `${entityId}_${recordIds.sort().join(',')}`;\n\n // Check cache\n const cached = this.membershipCache.get(cacheKey);\n if (cached && this.isCacheValid(cached)) {\n return cached.data;\n }\n\n this.loadingSubject.next(true);\n\n try {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get all list details for these records\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n const result = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n });\n\n const membership = new Map<string, string[]>();\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const existingRecords = membership.get(detail.ListID) || [];\n if (!existingRecords.includes(detail.RecordID)) {\n existingRecords.push(detail.RecordID);\n }\n membership.set(detail.ListID, existingRecords);\n }\n }\n\n this.membershipCache.set(cacheKey, {\n data: membership,\n timestamp: new Date()\n });\n\n return membership;\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get lists that contain a specific record\n */\n async getListsForRecord(\n entityId: string,\n recordId: string\n ): Promise<MJListEntity[]> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get list details for this record\n const detailsResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `RecordID = '${recordId}'`,\n ResultType: 'entity_object'\n });\n\n if (!detailsResult.Success || !detailsResult.Results || detailsResult.Results.length === 0) {\n return [];\n }\n\n const listIds = [...new Set(detailsResult.Results.map((d: MJListDetailEntity) => d.ListID))];\n\n // Get the lists filtered by entity\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const listsResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `ID IN (${listIdFilter}) AND EntityID = '${entityId}'`,\n ResultType: 'entity_object'\n });\n\n return listsResult.Success ? (listsResult.Results || []) : [];\n }\n\n /**\n * Get item count for a list\n */\n async getListItemCount(listId: string): Promise<number> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID = '${listId}'`,\n ResultType: 'count_only'\n });\n\n return result.Success ? result.TotalRowCount : 0;\n }\n\n /**\n * Build view models for lists with membership information\n */\n async buildListViewModels(\n lists: MJListEntity[],\n recordIds: string[],\n membership: Map<string, string[]>\n ): Promise<ListItemViewModel[]> {\n const viewModels: ListItemViewModel[] = [];\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get item counts for all lists in one batch query\n const listIds = lists.map(l => l.ID);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n\n // Get counts grouped by list - using a regular query since we need aggregation\n const countsResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: listIds.length > 0 ? `ListID IN (${listIdFilter})` : '1=0',\n ResultType: 'entity_object'\n });\n\n // Build count map\n const countMap = new Map<string, number>();\n if (countsResult.Success && countsResult.Results) {\n for (const detail of countsResult.Results) {\n const current = countMap.get(detail.ListID) || 0;\n countMap.set(detail.ListID, current + 1);\n }\n }\n\n for (const list of lists) {\n const memberRecordIds = membership.get(list.ID) || [];\n const membershipCount = memberRecordIds.length;\n const totalSelected = recordIds.length;\n\n viewModels.push({\n list,\n itemCount: countMap.get(list.ID) || 0,\n membershipCount,\n totalSelectedRecords: totalSelected,\n isFullMember: membershipCount === totalSelected && totalSelected > 0,\n isPartialMember: membershipCount > 0 && membershipCount < totalSelected,\n isNotMember: membershipCount === 0,\n lastUpdated: list.Get('__mj_UpdatedAt') as Date || new Date(),\n category: undefined, // Can be populated separately if needed\n isSelectedForAdd: false,\n isSelectedForRemove: false\n });\n }\n\n return viewModels;\n }\n\n /**\n * Add records to one or more lists\n */\n async addRecordsToLists(\n listIds: string[],\n recordIds: string[],\n skipDuplicates: boolean = true\n ): Promise<BatchOperationResult> {\n console.log(`[ListManagementService] addRecordsToLists called:`);\n console.log(` - listIds (${listIds.length}):`, listIds);\n console.log(` - recordIds (${recordIds.length}):`, recordIds);\n console.log(` - skipDuplicates:`, skipDuplicates);\n\n const result: BatchOperationResult = {\n success: 0,\n failed: 0,\n skipped: 0,\n errors: []\n };\n\n const md = this.Provider;\n\n // Get existing membership to skip duplicates\n let existingMembership = new Map<string, Set<string>>();\n if (skipDuplicates) {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n\n const existing = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter}) AND RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n }, md.CurrentUser);\n\n if (existing.Success && existing.Results) {\n for (const detail of existing.Results) {\n const recordSet = existingMembership.get(detail.ListID) || new Set();\n recordSet.add(detail.RecordID);\n existingMembership.set(detail.ListID, recordSet);\n }\n }\n }\n\n // Build list of records to add (excluding duplicates)\n const recordsToAdd: Array<{listId: string, recordId: string}> = [];\n for (const listId of listIds) {\n const existingRecords = existingMembership.get(listId) || new Set();\n for (const recordId of recordIds) {\n if (skipDuplicates && existingRecords.has(recordId)) {\n result.skipped++;\n } else {\n recordsToAdd.push({ listId, recordId });\n }\n }\n }\n\n if (recordsToAdd.length === 0) {\n console.log(`[ListManagementService] No records to add (all skipped as duplicates)`);\n return result;\n }\n\n // Use transaction group for bulk insert\n const tg = await md.CreateTransactionGroup();\n\n for (const { listId, recordId } of recordsToAdd) {\n try {\n const listDetail = await md.GetEntityObject<MJListDetailEntity>('MJ: List Details', md.CurrentUser);\n listDetail.ListID = listId;\n listDetail.RecordID = recordId;\n listDetail.TransactionGroup = tg;\n const saveResult = await listDetail.Save();\n if (!saveResult) {\n console.error(`[ListManagementService] Failed to queue record ${recordId} for list ${listId}:`, listDetail.LatestResult?.Message);\n result.errors.push(`Failed to add record ${recordId} to list ${listId}: ${listDetail.LatestResult?.Message || 'Unknown error'}`);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`[ListManagementService] Exception adding record:`, error);\n result.errors.push(`Error adding record ${recordId} to list ${listId}: ${errorMessage}`);\n }\n }\n\n // Submit the transaction\n console.log(`[ListManagementService] Submitting transaction with ${recordsToAdd.length} records...`);\n const success = await tg.Submit();\n\n if (success) {\n result.success = recordsToAdd.length - result.errors.length;\n result.failed = result.errors.length;\n console.log(`[ListManagementService] Transaction succeeded. Added ${result.success} records.`);\n } else {\n result.failed = recordsToAdd.length;\n result.success = 0;\n console.error(`[ListManagementService] Transaction failed`);\n result.errors.push('Transaction failed to submit');\n }\n\n // Invalidate membership cache\n this.membershipCache.clear();\n\n console.log(`[ListManagementService] addRecordsToLists final result:`, result);\n return result;\n }\n\n /**\n * Remove records from one or more lists\n */\n async removeRecordsFromLists(\n listIds: string[],\n recordIds: string[]\n ): Promise<BatchOperationResult> {\n const result: BatchOperationResult = {\n success: 0,\n failed: 0,\n skipped: 0,\n errors: []\n };\n\n const md = this.Provider;\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Find existing list details to delete\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n\n const existingResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter}) AND RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n });\n\n if (!existingResult.Success) {\n result.errors.push('Failed to query existing list details');\n return result;\n }\n\n // Delete each matching detail\n for (const detail of existingResult.Results || []) {\n try {\n const deleteResult = await detail.Delete();\n if (deleteResult) {\n result.success++;\n } else {\n result.failed++;\n result.errors.push(`Failed to remove record ${detail.RecordID} from list ${detail.ListID}`);\n }\n } catch (error) {\n result.failed++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n result.errors.push(`Error removing record: ${errorMessage}`);\n }\n }\n\n // Invalidate caches\n this.membershipCache.clear();\n\n return result;\n }\n\n /**\n * Create a new list\n */\n async createList(config: CreateListConfig): Promise<MJListEntity | null> {\n const md = this.Provider;\n\n try {\n const list = await md.GetEntityObject<MJListEntity>('MJ: Lists', md.CurrentUser);\n list.NewRecord();\n list.Name = config.name;\n list.Description = config.description || '';\n list.EntityID = config.entityId;\n list.UserID = md.CurrentUser.ID;\n\n if (config.categoryId) {\n list.CategoryID = config.categoryId;\n }\n\n const saveResult = await list.Save();\n if (saveResult) {\n // Invalidate list cache\n this.invalidateListCache(config.entityId);\n return list;\n }\n\n return null;\n } catch (error) {\n console.error('Error creating list:', error);\n return null;\n }\n }\n\n /**\n * Check if a cache entry is still valid\n */\n private isCacheValid<T>(entry: CacheEntry<T>): boolean {\n const now = new Date().getTime();\n const entryTime = entry.timestamp.getTime();\n return (now - entryTime) < this.CACHE_TTL_MS;\n }\n\n /**\n * Invalidate cache for a specific entity or all caches\n */\n invalidateCache(entityId?: string): void {\n if (entityId) {\n this.invalidateListCache(entityId);\n } else {\n this.listCache.clear();\n this.categoryCache = null;\n this.membershipCache.clear();\n }\n }\n\n /**\n * Invalidate list cache for a specific entity\n */\n private invalidateListCache(entityId: string): void {\n // Remove all cache entries that start with this entityId\n for (const key of this.listCache.keys()) {\n if (key.startsWith(entityId)) {\n this.listCache.delete(key);\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list-management.service.js","sourceRoot":"","sources":["../../../src/lib/services/list-management.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport { MJListEntity, MJListDetailEntity, MJListCategoryEntity } from '@memberjunction/core-entities';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport {\n ListItemViewModel,\n BatchOperationResult,\n RecordMembershipInfo,\n CreateListConfig\n} from '../models/list-management.models';\n\ninterface CacheEntry<T> {\n data: T;\n timestamp: Date;\n}\n\n/**\n * Service for managing list operations including data loading, caching,\n * and batch add/remove operations.\n *\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ListManagementService {\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n // Cache storage\n private listCache = new Map<string, CacheEntry<MJListEntity[]>>();\n private categoryCache: CacheEntry<MJListCategoryEntity[]> | null = null;\n private membershipCache = new Map<string, CacheEntry<Map<string, string[]>>>();\n\n // Loading state subjects\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n private _provider: IMetadataProvider | null = null;\n\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n constructor() {}\n\n /**\n * Get lists for a specific entity, with optional caching\n */\n async getListsForEntity(\n entityId: string,\n userId?: string,\n forceRefresh: boolean = false\n ): Promise<MJListEntity[]> {\n const cacheKey = `${entityId}_${userId || 'all'}`;\n\n // Check cache first\n if (!forceRefresh) {\n const cached = this.listCache.get(cacheKey);\n if (cached && this.isCacheValid(cached)) {\n return cached.data;\n }\n }\n\n this.loadingSubject.next(true);\n\n try {\n const rv = RunView.FromMetadataProvider(this.Provider);\n let filter = `EntityID = '${entityId}'`;\n\n if (userId) {\n filter += ` AND UserID = '${userId}'`;\n }\n\n const result = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: filter,\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n const lists = result.Results || [];\n this.listCache.set(cacheKey, {\n data: lists,\n timestamp: new Date()\n });\n return lists;\n } else {\n console.error('Failed to load lists:', result.ErrorMessage);\n return [];\n }\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get all list categories\n */\n async getListCategories(forceRefresh: boolean = false): Promise<MJListCategoryEntity[]> {\n if (!forceRefresh && this.categoryCache && this.isCacheValid(this.categoryCache)) {\n return this.categoryCache.data;\n }\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<MJListCategoryEntity>({\n EntityName: 'MJ: List Categories',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.categoryCache = {\n data: result.Results || [],\n timestamp: new Date()\n };\n return this.categoryCache.data;\n }\n\n return [];\n }\n\n /**\n * Get membership information for a set of records\n * Returns a Map where key is listId and value is array of recordIds that are members\n */\n async getRecordMembership(\n entityId: string,\n recordIds: string[]\n ): Promise<Map<string, string[]>> {\n if (recordIds.length === 0) {\n return new Map();\n }\n\n const cacheKey = `${entityId}_${recordIds.sort().join(',')}`;\n\n // Check cache\n const cached = this.membershipCache.get(cacheKey);\n if (cached && this.isCacheValid(cached)) {\n return cached.data;\n }\n\n this.loadingSubject.next(true);\n\n try {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get all list details for these records\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n const result = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n });\n\n const membership = new Map<string, string[]>();\n\n if (result.Success && result.Results) {\n for (const detail of result.Results) {\n const existingRecords = membership.get(detail.ListID) || [];\n if (!existingRecords.includes(detail.RecordID)) {\n existingRecords.push(detail.RecordID);\n }\n membership.set(detail.ListID, existingRecords);\n }\n }\n\n this.membershipCache.set(cacheKey, {\n data: membership,\n timestamp: new Date()\n });\n\n return membership;\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get lists that contain a specific record\n */\n async getListsForRecord(\n entityId: string,\n recordId: string\n ): Promise<MJListEntity[]> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get list details for this record\n const detailsResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `RecordID = '${recordId}'`,\n ResultType: 'entity_object'\n });\n\n if (!detailsResult.Success || !detailsResult.Results || detailsResult.Results.length === 0) {\n return [];\n }\n\n const listIds = [...new Set(detailsResult.Results.map((d: MJListDetailEntity) => d.ListID))];\n\n // Get the lists filtered by entity\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const listsResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `ID IN (${listIdFilter}) AND EntityID = '${entityId}'`,\n ResultType: 'entity_object'\n });\n\n return listsResult.Success ? (listsResult.Results || []) : [];\n }\n\n /**\n * Get item count for a list\n */\n async getListItemCount(listId: string): Promise<number> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID = '${listId}'`,\n ResultType: 'count_only'\n });\n\n return result.Success ? result.TotalRowCount : 0;\n }\n\n /**\n * Build view models for lists with membership information\n */\n async buildListViewModels(\n lists: MJListEntity[],\n recordIds: string[],\n membership: Map<string, string[]>\n ): Promise<ListItemViewModel[]> {\n const viewModels: ListItemViewModel[] = [];\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Get item counts for all lists in one batch query\n const listIds = lists.map(l => l.ID);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n\n // Get counts grouped by list - using a regular query since we need aggregation\n const countsResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: listIds.length > 0 ? `ListID IN (${listIdFilter})` : '1=0',\n ResultType: 'entity_object'\n });\n\n // Build count map\n const countMap = new Map<string, number>();\n if (countsResult.Success && countsResult.Results) {\n for (const detail of countsResult.Results) {\n const current = countMap.get(detail.ListID) || 0;\n countMap.set(detail.ListID, current + 1);\n }\n }\n\n for (const list of lists) {\n const memberRecordIds = membership.get(list.ID) || [];\n const membershipCount = memberRecordIds.length;\n const totalSelected = recordIds.length;\n\n viewModels.push({\n list,\n itemCount: countMap.get(list.ID) || 0,\n membershipCount,\n totalSelectedRecords: totalSelected,\n isFullMember: membershipCount === totalSelected && totalSelected > 0,\n isPartialMember: membershipCount > 0 && membershipCount < totalSelected,\n isNotMember: membershipCount === 0,\n lastUpdated: list.Get('__mj_UpdatedAt') as Date || new Date(),\n category: undefined, // Can be populated separately if needed\n isSelectedForAdd: false,\n isSelectedForRemove: false\n });\n }\n\n return viewModels;\n }\n\n /**\n * Add records to one or more lists\n */\n async addRecordsToLists(\n listIds: string[],\n recordIds: string[],\n skipDuplicates: boolean = true\n ): Promise<BatchOperationResult> {\n const result: BatchOperationResult = {\n success: 0,\n failed: 0,\n skipped: 0,\n errors: []\n };\n\n const md = this.Provider;\n\n // Get existing membership to skip duplicates\n let existingMembership = new Map<string, Set<string>>();\n if (skipDuplicates) {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n\n const existing = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter}) AND RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n }, md.CurrentUser);\n\n if (existing.Success && existing.Results) {\n for (const detail of existing.Results) {\n const recordSet = existingMembership.get(detail.ListID) || new Set();\n recordSet.add(detail.RecordID);\n existingMembership.set(detail.ListID, recordSet);\n }\n }\n }\n\n // Build list of records to add (excluding duplicates)\n const recordsToAdd: Array<{listId: string, recordId: string}> = [];\n for (const listId of listIds) {\n const existingRecords = existingMembership.get(listId) || new Set();\n for (const recordId of recordIds) {\n if (skipDuplicates && existingRecords.has(recordId)) {\n result.skipped++;\n } else {\n recordsToAdd.push({ listId, recordId });\n }\n }\n }\n\n if (recordsToAdd.length === 0) {\n return result;\n }\n\n // Use transaction group for bulk insert\n const tg = await md.CreateTransactionGroup();\n\n for (const { listId, recordId } of recordsToAdd) {\n try {\n const listDetail = await md.GetEntityObject<MJListDetailEntity>('MJ: List Details', md.CurrentUser);\n listDetail.ListID = listId;\n listDetail.RecordID = recordId;\n listDetail.TransactionGroup = tg;\n const saveResult = await listDetail.Save();\n if (!saveResult) {\n console.error(`[ListManagementService] Failed to queue record ${recordId} for list ${listId}:`, listDetail.LatestResult?.Message);\n result.errors.push(`Failed to add record ${recordId} to list ${listId}: ${listDetail.LatestResult?.Message || 'Unknown error'}`);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`[ListManagementService] Exception adding record:`, error);\n result.errors.push(`Error adding record ${recordId} to list ${listId}: ${errorMessage}`);\n }\n }\n\n // Submit the transaction\n const success = await tg.Submit();\n\n if (success) {\n result.success = recordsToAdd.length - result.errors.length;\n result.failed = result.errors.length;\n } else {\n result.failed = recordsToAdd.length;\n result.success = 0;\n result.errors.push('Transaction failed to submit');\n }\n\n // Invalidate membership cache\n this.membershipCache.clear();\n\n return result;\n }\n\n /**\n * Remove records from one or more lists\n */\n async removeRecordsFromLists(\n listIds: string[],\n recordIds: string[]\n ): Promise<BatchOperationResult> {\n const result: BatchOperationResult = {\n success: 0,\n failed: 0,\n skipped: 0,\n errors: []\n };\n\n const md = this.Provider;\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Find existing list details to delete\n const listIdFilter = listIds.map(id => `'${id}'`).join(',');\n const recordIdFilter = recordIds.map(id => `'${id}'`).join(',');\n\n const existingResult = await rv.RunView<MJListDetailEntity>({\n EntityName: 'MJ: List Details',\n ExtraFilter: `ListID IN (${listIdFilter}) AND RecordID IN (${recordIdFilter})`,\n ResultType: 'entity_object'\n });\n\n if (!existingResult.Success) {\n result.errors.push('Failed to query existing list details');\n return result;\n }\n\n // Delete each matching detail\n for (const detail of existingResult.Results || []) {\n try {\n const deleteResult = await detail.Delete();\n if (deleteResult) {\n result.success++;\n } else {\n result.failed++;\n result.errors.push(`Failed to remove record ${detail.RecordID} from list ${detail.ListID}`);\n }\n } catch (error) {\n result.failed++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n result.errors.push(`Error removing record: ${errorMessage}`);\n }\n }\n\n // Invalidate caches\n this.membershipCache.clear();\n\n return result;\n }\n\n /**\n * Create a new list\n */\n async createList(config: CreateListConfig): Promise<MJListEntity | null> {\n const md = this.Provider;\n\n try {\n const list = await md.GetEntityObject<MJListEntity>('MJ: Lists', md.CurrentUser);\n list.NewRecord();\n list.Name = config.name;\n list.Description = config.description || '';\n list.EntityID = config.entityId;\n list.UserID = md.CurrentUser.ID;\n\n if (config.categoryId) {\n list.CategoryID = config.categoryId;\n }\n\n const saveResult = await list.Save();\n if (saveResult) {\n // Invalidate list cache\n this.invalidateListCache(config.entityId);\n return list;\n }\n\n return null;\n } catch (error) {\n console.error('Error creating list:', error);\n return null;\n }\n }\n\n /**\n * Check if a cache entry is still valid\n */\n private isCacheValid<T>(entry: CacheEntry<T>): boolean {\n const now = new Date().getTime();\n const entryTime = entry.timestamp.getTime();\n return (now - entryTime) < this.CACHE_TTL_MS;\n }\n\n /**\n * Invalidate cache for a specific entity or all caches\n */\n invalidateCache(entityId?: string): void {\n if (entityId) {\n this.invalidateListCache(entityId);\n } else {\n this.listCache.clear();\n this.categoryCache = null;\n this.membershipCache.clear();\n }\n }\n\n /**\n * Invalidate list cache for a specific entity\n */\n private invalidateListCache(entityId: string): void {\n // Remove all cache entries that start with this entityId\n for (const key of this.listCache.keys()) {\n if (key.startsWith(entityId)) {\n this.listCache.delete(key);\n }\n }\n }\n}\n"]}
|
|
@@ -21,9 +21,14 @@ export declare class ListSharingService {
|
|
|
21
21
|
set Provider(value: IMetadataProvider | null);
|
|
22
22
|
constructor();
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
* Resolve the `MJ: Resource Types.ID` for the row named "Lists" via the
|
|
25
|
+
* shared `ResourceTypeEngine`. Throws if missing — that indicates a
|
|
26
|
+
* misconfigured environment (seed data never pushed) and we'd rather fail
|
|
27
|
+
* loud than write `MJResourcePermission` rows with an undefined
|
|
28
|
+
* `ResourceTypeID`. `Engine.Config()` is idempotent (BaseEngine semantics)
|
|
29
|
+
* so calling this on every method that needs it is cheap.
|
|
30
|
+
*/
|
|
31
|
+
private resolveListResourceTypeId;
|
|
27
32
|
/**
|
|
28
33
|
* Get all shares for a specific list
|
|
29
34
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-sharing.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/list-sharing.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAA+B,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAIL,YAAY,EACZ,YAAY,
|
|
1
|
+
{"version":3,"file":"list-sharing.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/list-sharing.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
2
|
import { Metadata, RunView } from '@memberjunction/core';
|
|
3
|
+
import { ResourceTypeEngine, } from '@memberjunction/core-entities';
|
|
3
4
|
import { BehaviorSubject } from 'rxjs';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
const LIST_RESOURCE_TYPE_ID = 'E64D433E-F36B-1410-8560-0041FA62858A';
|
|
6
|
+
/** Name of the row in `MJ: Resource Types` that scopes List shares. */
|
|
7
|
+
const LIST_RESOURCE_TYPE_NAME = 'Lists';
|
|
9
8
|
/**
|
|
10
9
|
* Service for managing list sharing using the existing ResourcePermission system.
|
|
11
10
|
* Lists are already registered as a ResourceType, so we use ResourcePermissions
|
|
@@ -29,10 +28,21 @@ export class ListSharingService {
|
|
|
29
28
|
}
|
|
30
29
|
constructor() { }
|
|
31
30
|
/**
|
|
32
|
-
*
|
|
31
|
+
* Resolve the `MJ: Resource Types.ID` for the row named "Lists" via the
|
|
32
|
+
* shared `ResourceTypeEngine`. Throws if missing — that indicates a
|
|
33
|
+
* misconfigured environment (seed data never pushed) and we'd rather fail
|
|
34
|
+
* loud than write `MJResourcePermission` rows with an undefined
|
|
35
|
+
* `ResourceTypeID`. `Engine.Config()` is idempotent (BaseEngine semantics)
|
|
36
|
+
* so calling this on every method that needs it is cheap.
|
|
33
37
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
async resolveListResourceTypeId() {
|
|
39
|
+
await ResourceTypeEngine.Instance.Config(false, undefined, this.Provider);
|
|
40
|
+
const rt = ResourceTypeEngine.Instance.ByName(LIST_RESOURCE_TYPE_NAME);
|
|
41
|
+
if (!rt) {
|
|
42
|
+
throw new Error(`MJ: Resource Types row "${LIST_RESOURCE_TYPE_NAME}" not found. ` +
|
|
43
|
+
`Seed metadata/resource-types/ via 'mj sync push' before using ListSharingService.`);
|
|
44
|
+
}
|
|
45
|
+
return rt.ID;
|
|
36
46
|
}
|
|
37
47
|
/**
|
|
38
48
|
* Get all shares for a specific list
|
|
@@ -40,10 +50,11 @@ export class ListSharingService {
|
|
|
40
50
|
async getListShares(listId) {
|
|
41
51
|
this.loadingSubject.next(true);
|
|
42
52
|
try {
|
|
53
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
43
54
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
44
55
|
const result = await rv.RunView({
|
|
45
56
|
EntityName: 'MJ: Resource Permissions',
|
|
46
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
57
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND ResourceRecordID = '${listId}'`,
|
|
47
58
|
ResultType: 'entity_object'
|
|
48
59
|
});
|
|
49
60
|
if (!result.Success || !result.Results) {
|
|
@@ -67,11 +78,12 @@ export class ListSharingService {
|
|
|
67
78
|
* Get permission level for a specific user on a specific list
|
|
68
79
|
*/
|
|
69
80
|
async getUserPermissionLevel(listId, userId) {
|
|
81
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
70
82
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
71
83
|
// Check direct user permission
|
|
72
84
|
const userResult = await rv.RunView({
|
|
73
85
|
EntityName: 'MJ: Resource Permissions',
|
|
74
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
86
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND ResourceRecordID = '${listId}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,
|
|
75
87
|
ResultType: 'entity_object'
|
|
76
88
|
});
|
|
77
89
|
if (userResult.Success && userResult.Results && userResult.Results.length > 0) {
|
|
@@ -101,9 +113,10 @@ export class ListSharingService {
|
|
|
101
113
|
};
|
|
102
114
|
}
|
|
103
115
|
// Create new share
|
|
116
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
104
117
|
const permission = await md.GetEntityObject('MJ: Resource Permissions');
|
|
105
118
|
permission.NewRecord();
|
|
106
|
-
permission.ResourceTypeID =
|
|
119
|
+
permission.ResourceTypeID = resourceTypeId;
|
|
107
120
|
permission.ResourceRecordID = listId;
|
|
108
121
|
permission.Type = 'User';
|
|
109
122
|
permission.UserID = userId;
|
|
@@ -144,9 +157,10 @@ export class ListSharingService {
|
|
|
144
157
|
};
|
|
145
158
|
}
|
|
146
159
|
// Create new share
|
|
160
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
147
161
|
const permission = await md.GetEntityObject('MJ: Resource Permissions');
|
|
148
162
|
permission.NewRecord();
|
|
149
|
-
permission.ResourceTypeID =
|
|
163
|
+
permission.ResourceTypeID = resourceTypeId;
|
|
150
164
|
permission.ResourceRecordID = listId;
|
|
151
165
|
permission.Type = 'Role';
|
|
152
166
|
permission.RoleID = roleId;
|
|
@@ -229,10 +243,11 @@ export class ListSharingService {
|
|
|
229
243
|
* Get lists shared with the current user (that they don't own)
|
|
230
244
|
*/
|
|
231
245
|
async getListsSharedWithUser(userId) {
|
|
246
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
232
247
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
233
248
|
const result = await rv.RunView({
|
|
234
249
|
EntityName: 'MJ: Resource Permissions',
|
|
235
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
250
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,
|
|
236
251
|
Fields: ['ResourceRecordID'],
|
|
237
252
|
ResultType: 'simple'
|
|
238
253
|
});
|
|
@@ -259,9 +274,10 @@ export class ListSharingService {
|
|
|
259
274
|
const listIds = listsResult.Results.map((l) => l.ID);
|
|
260
275
|
const listIdFilter = listIds.map((id) => `'${id}'`).join(',');
|
|
261
276
|
// Get all shares for these lists
|
|
277
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
262
278
|
const sharesResult = await rv.RunView({
|
|
263
279
|
EntityName: 'MJ: Resource Permissions',
|
|
264
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
280
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND ResourceRecordID IN (${listIdFilter}) AND Status = 'Approved'`,
|
|
265
281
|
Fields: ['ResourceRecordID'],
|
|
266
282
|
ResultType: 'simple'
|
|
267
283
|
});
|
|
@@ -379,11 +395,12 @@ export class ListSharingService {
|
|
|
379
395
|
* Helper to find existing share
|
|
380
396
|
*/
|
|
381
397
|
async findExistingShare(listId, type, recipientId) {
|
|
398
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
382
399
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
383
400
|
const idField = type === 'User' ? 'UserID' : 'RoleID';
|
|
384
401
|
const result = await rv.RunView({
|
|
385
402
|
EntityName: 'MJ: Resource Permissions',
|
|
386
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
403
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND ResourceRecordID = '${listId}' AND Type = '${type}' AND ${idField} = '${recipientId}'`,
|
|
387
404
|
ResultType: 'entity_object'
|
|
388
405
|
});
|
|
389
406
|
if (result.Success && result.Results && result.Results.length > 0) {
|
|
@@ -445,10 +462,11 @@ export class ListSharingService {
|
|
|
445
462
|
* Get sharing summary for a single list
|
|
446
463
|
*/
|
|
447
464
|
async getListSharingSummary(listId) {
|
|
465
|
+
const resourceTypeId = await this.resolveListResourceTypeId();
|
|
448
466
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
449
467
|
const result = await rv.RunView({
|
|
450
468
|
EntityName: 'MJ: Resource Permissions',
|
|
451
|
-
ExtraFilter: `ResourceTypeID = '${
|
|
469
|
+
ExtraFilter: `ResourceTypeID = '${resourceTypeId}' AND ResourceRecordID = '${listId}' AND Status = 'Approved'`,
|
|
452
470
|
Fields: ['ID', 'Type'],
|
|
453
471
|
ResultType: 'simple'
|
|
454
472
|
});
|