@memberjunction/ng-list-management 5.30.1 → 5.31.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/dist/lib/components/list-management-dialog/list-management-dialog.component.d.ts +2 -1
- 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 +6 -5
- 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 +2 -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 +6 -5
- package/dist/lib/components/list-share-dialog/list-share-dialog.component.js.map +1 -1
- package/dist/lib/services/list-management.service.d.ts +7 -0
- package/dist/lib/services/list-management.service.d.ts.map +1 -1
- package/dist/lib/services/list-management.service.js +22 -12
- package/dist/lib/services/list-management.service.js.map +1 -1
- package/dist/lib/services/list-sharing.service.d.ts +7 -0
- package/dist/lib/services/list-sharing.service.d.ts.map +1 -1
- package/dist/lib/services/list-sharing.service.js +26 -16
- package/dist/lib/services/list-sharing.service.js.map +1 -1
- package/package.json +11 -10
|
@@ -10,6 +10,9 @@ const LIST_RESOURCE_TYPE_ID = 'E64D433E-F36B-1410-8560-0041FA62858A';
|
|
|
10
10
|
* Service for managing list sharing using the existing ResourcePermission system.
|
|
11
11
|
* Lists are already registered as a ResourceType, so we use ResourcePermissions
|
|
12
12
|
* to share lists with users and roles.
|
|
13
|
+
*
|
|
14
|
+
* Multi-provider note: callers under a non-default provider should set
|
|
15
|
+
* `service.Provider = component.ProviderToUse` before invoking any methods.
|
|
13
16
|
*/
|
|
14
17
|
export class ListSharingService {
|
|
15
18
|
loadingSubject = new BehaviorSubject(false);
|
|
@@ -17,6 +20,13 @@ export class ListSharingService {
|
|
|
17
20
|
// Cache for users and roles (for autocomplete)
|
|
18
21
|
usersCache = null;
|
|
19
22
|
rolesCache = null;
|
|
23
|
+
_provider = null;
|
|
24
|
+
get Provider() {
|
|
25
|
+
return this._provider ?? Metadata.Provider;
|
|
26
|
+
}
|
|
27
|
+
set Provider(value) {
|
|
28
|
+
this._provider = value;
|
|
29
|
+
}
|
|
20
30
|
constructor() { }
|
|
21
31
|
/**
|
|
22
32
|
* Get the ResourceType ID for Lists
|
|
@@ -30,7 +40,7 @@ export class ListSharingService {
|
|
|
30
40
|
async getListShares(listId) {
|
|
31
41
|
this.loadingSubject.next(true);
|
|
32
42
|
try {
|
|
33
|
-
const rv =
|
|
43
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
34
44
|
const result = await rv.RunView({
|
|
35
45
|
EntityName: 'MJ: Resource Permissions',
|
|
36
46
|
ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}'`,
|
|
@@ -57,7 +67,7 @@ export class ListSharingService {
|
|
|
57
67
|
* Get permission level for a specific user on a specific list
|
|
58
68
|
*/
|
|
59
69
|
async getUserPermissionLevel(listId, userId) {
|
|
60
|
-
const rv =
|
|
70
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
61
71
|
// Check direct user permission
|
|
62
72
|
const userResult = await rv.RunView({
|
|
63
73
|
EntityName: 'MJ: Resource Permissions',
|
|
@@ -76,7 +86,7 @@ export class ListSharingService {
|
|
|
76
86
|
*/
|
|
77
87
|
async shareListWithUser(listId, userId, permissionLevel, sharedByUserId) {
|
|
78
88
|
try {
|
|
79
|
-
const md =
|
|
89
|
+
const md = this.Provider;
|
|
80
90
|
// Check if share already exists
|
|
81
91
|
const existing = await this.findExistingShare(listId, 'User', userId);
|
|
82
92
|
if (existing) {
|
|
@@ -119,7 +129,7 @@ export class ListSharingService {
|
|
|
119
129
|
*/
|
|
120
130
|
async shareListWithRole(listId, roleId, permissionLevel, sharedByUserId) {
|
|
121
131
|
try {
|
|
122
|
-
const md =
|
|
132
|
+
const md = this.Provider;
|
|
123
133
|
// Check if share already exists
|
|
124
134
|
const existing = await this.findExistingShare(listId, 'Role', roleId);
|
|
125
135
|
if (existing) {
|
|
@@ -162,7 +172,7 @@ export class ListSharingService {
|
|
|
162
172
|
*/
|
|
163
173
|
async updateSharePermission(shareId, newPermissionLevel) {
|
|
164
174
|
try {
|
|
165
|
-
const md =
|
|
175
|
+
const md = this.Provider;
|
|
166
176
|
const permission = await md.GetEntityObject('MJ: Resource Permissions');
|
|
167
177
|
const loaded = await permission.Load(shareId);
|
|
168
178
|
if (!loaded) {
|
|
@@ -192,7 +202,7 @@ export class ListSharingService {
|
|
|
192
202
|
*/
|
|
193
203
|
async removeShare(shareId) {
|
|
194
204
|
try {
|
|
195
|
-
const md =
|
|
205
|
+
const md = this.Provider;
|
|
196
206
|
const permission = await md.GetEntityObject('MJ: Resource Permissions');
|
|
197
207
|
const loaded = await permission.Load(shareId);
|
|
198
208
|
if (!loaded) {
|
|
@@ -219,7 +229,7 @@ export class ListSharingService {
|
|
|
219
229
|
* Get lists shared with the current user (that they don't own)
|
|
220
230
|
*/
|
|
221
231
|
async getListsSharedWithUser(userId) {
|
|
222
|
-
const rv =
|
|
232
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
223
233
|
const result = await rv.RunView({
|
|
224
234
|
EntityName: 'MJ: Resource Permissions',
|
|
225
235
|
ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,
|
|
@@ -236,7 +246,7 @@ export class ListSharingService {
|
|
|
236
246
|
*/
|
|
237
247
|
async getListsSharedByUser(userId) {
|
|
238
248
|
// First get all lists owned by the user
|
|
239
|
-
const rv =
|
|
249
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
240
250
|
const listsResult = await rv.RunView({
|
|
241
251
|
EntityName: 'MJ: Lists',
|
|
242
252
|
ExtraFilter: `UserID = '${userId}'`,
|
|
@@ -269,7 +279,7 @@ export class ListSharingService {
|
|
|
269
279
|
* Check if user can share a list (must be owner or have Owner permission)
|
|
270
280
|
*/
|
|
271
281
|
async canUserShareList(listId, userId) {
|
|
272
|
-
const rv =
|
|
282
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
273
283
|
// Check if user is the owner
|
|
274
284
|
const listResult = await rv.RunView({
|
|
275
285
|
EntityName: 'MJ: Lists',
|
|
@@ -287,7 +297,7 @@ export class ListSharingService {
|
|
|
287
297
|
* Search users for sharing autocomplete
|
|
288
298
|
*/
|
|
289
299
|
async searchUsers(searchTerm, limit = 10) {
|
|
290
|
-
const rv =
|
|
300
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
291
301
|
const result = await rv.RunView({
|
|
292
302
|
EntityName: 'MJ: Users',
|
|
293
303
|
ExtraFilter: `(Name LIKE '%${searchTerm}%' OR Email LIKE '%${searchTerm}%') AND IsActive = 1`,
|
|
@@ -309,7 +319,7 @@ export class ListSharingService {
|
|
|
309
319
|
* Search roles for sharing autocomplete
|
|
310
320
|
*/
|
|
311
321
|
async searchRoles(searchTerm, limit = 10) {
|
|
312
|
-
const rv =
|
|
322
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
313
323
|
const result = await rv.RunView({
|
|
314
324
|
EntityName: 'MJ: Roles',
|
|
315
325
|
ExtraFilter: `Name LIKE '%${searchTerm}%'`,
|
|
@@ -333,7 +343,7 @@ export class ListSharingService {
|
|
|
333
343
|
if (!forceRefresh && this.usersCache) {
|
|
334
344
|
return this.usersCache;
|
|
335
345
|
}
|
|
336
|
-
const rv =
|
|
346
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
337
347
|
const result = await rv.RunView({
|
|
338
348
|
EntityName: 'MJ: Users',
|
|
339
349
|
ExtraFilter: 'IsActive = 1',
|
|
@@ -353,7 +363,7 @@ export class ListSharingService {
|
|
|
353
363
|
if (!forceRefresh && this.rolesCache) {
|
|
354
364
|
return this.rolesCache;
|
|
355
365
|
}
|
|
356
|
-
const rv =
|
|
366
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
357
367
|
const result = await rv.RunView({
|
|
358
368
|
EntityName: 'MJ: Roles',
|
|
359
369
|
OrderBy: 'Name',
|
|
@@ -369,7 +379,7 @@ export class ListSharingService {
|
|
|
369
379
|
* Helper to find existing share
|
|
370
380
|
*/
|
|
371
381
|
async findExistingShare(listId, type, recipientId) {
|
|
372
|
-
const rv =
|
|
382
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
373
383
|
const idField = type === 'User' ? 'UserID' : 'RoleID';
|
|
374
384
|
const result = await rv.RunView({
|
|
375
385
|
EntityName: 'MJ: Resource Permissions',
|
|
@@ -385,7 +395,7 @@ export class ListSharingService {
|
|
|
385
395
|
* Convert MJResourcePermissionEntity to ListShareInfo
|
|
386
396
|
*/
|
|
387
397
|
async convertToListShareInfo(permission) {
|
|
388
|
-
const rv =
|
|
398
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
389
399
|
if (permission.Type === 'User' && permission.UserID) {
|
|
390
400
|
const userResult = await rv.RunView({
|
|
391
401
|
EntityName: 'MJ: Users',
|
|
@@ -435,7 +445,7 @@ export class ListSharingService {
|
|
|
435
445
|
* Get sharing summary for a single list
|
|
436
446
|
*/
|
|
437
447
|
async getListSharingSummary(listId) {
|
|
438
|
-
const rv =
|
|
448
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
439
449
|
const result = await rv.RunView({
|
|
440
450
|
EntityName: 'MJ: Resource Permissions',
|
|
441
451
|
ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Status = 'Approved'`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-sharing.service.js","sourceRoot":"","sources":["../../../src/lib/services/list-sharing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport {\n MJListEntity,\n MJResourcePermissionEntity,\n MJResourceTypeEntity,\n MJUserEntity,\n MJRoleEntity\n} from '@memberjunction/core-entities';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { ListShareInfo, ListPermissionLevel, ShareRecipient, ListShareResult } from '../models/list-sharing.models';\n\n/**\n * Known List ResourceType ID from the database\n */\nconst LIST_RESOURCE_TYPE_ID = 'E64D433E-F36B-1410-8560-0041FA62858A';\n\n/**\n * Service for managing list sharing using the existing ResourcePermission system.\n * Lists are already registered as a ResourceType, so we use ResourcePermissions\n * to share lists with users and roles.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ListSharingService {\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n // Cache for users and roles (for autocomplete)\n private usersCache: MJUserEntity[] | null = null;\n private rolesCache: MJRoleEntity[] | null = null;\n\n constructor() {}\n\n /**\n * Get the ResourceType ID for Lists\n */\n getListResourceTypeId(): string {\n return LIST_RESOURCE_TYPE_ID;\n }\n\n /**\n * Get all shares for a specific list\n */\n async getListShares(listId: string): Promise<ListShareInfo[]> {\n this.loadingSubject.next(true);\n\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}'`,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n // Convert to ListShareInfo objects with user/role details\n const shares: ListShareInfo[] = [];\n\n for (const permission of result.Results) {\n const shareInfo = await this.convertToListShareInfo(permission);\n if (shareInfo) {\n shares.push(shareInfo);\n }\n }\n\n return shares;\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get permission level for a specific user on a specific list\n */\n async getUserPermissionLevel(listId: string, userId: string): Promise<ListPermissionLevel | null> {\n const rv = new RunView();\n\n // Check direct user permission\n const userResult = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,\n ResultType: 'entity_object'\n });\n\n if (userResult.Success && userResult.Results && userResult.Results.length > 0) {\n return userResult.Results[0].PermissionLevel as ListPermissionLevel;\n }\n\n // If no direct permission, could check role-based permissions\n // For now, return null\n return null;\n }\n\n /**\n * Share a list with a user\n */\n async shareListWithUser(\n listId: string,\n userId: string,\n permissionLevel: ListPermissionLevel,\n sharedByUserId: string\n ): Promise<ListShareResult> {\n try {\n const md = new Metadata();\n\n // Check if share already exists\n const existing = await this.findExistingShare(listId, 'User', userId);\n\n if (existing) {\n // Update existing share\n existing.PermissionLevel = permissionLevel;\n existing.Status = 'Approved';\n const saved = await existing.Save();\n return {\n success: saved,\n shareId: existing.ID,\n message: saved ? 'Share updated successfully' : 'Failed to update share'\n };\n }\n\n // Create new share\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n permission.NewRecord();\n permission.ResourceTypeID = LIST_RESOURCE_TYPE_ID;\n permission.ResourceRecordID = listId;\n permission.Type = 'User';\n permission.UserID = userId;\n permission.PermissionLevel = permissionLevel;\n permission.Status = 'Approved';\n\n const saved = await permission.Save();\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'List shared successfully' : 'Failed to share list'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error sharing list: ${errorMessage}`\n };\n }\n }\n\n /**\n * Share a list with a role\n */\n async shareListWithRole(\n listId: string,\n roleId: string,\n permissionLevel: ListPermissionLevel,\n sharedByUserId: string\n ): Promise<ListShareResult> {\n try {\n const md = new Metadata();\n\n // Check if share already exists\n const existing = await this.findExistingShare(listId, 'Role', roleId);\n\n if (existing) {\n // Update existing share\n existing.PermissionLevel = permissionLevel;\n existing.Status = 'Approved';\n const saved = await existing.Save();\n return {\n success: saved,\n shareId: existing.ID,\n message: saved ? 'Share updated successfully' : 'Failed to update share'\n };\n }\n\n // Create new share\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n permission.NewRecord();\n permission.ResourceTypeID = LIST_RESOURCE_TYPE_ID;\n permission.ResourceRecordID = listId;\n permission.Type = 'Role';\n permission.RoleID = roleId;\n permission.PermissionLevel = permissionLevel;\n permission.Status = 'Approved';\n\n const saved = await permission.Save();\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'List shared with role successfully' : 'Failed to share list with role'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error sharing list: ${errorMessage}`\n };\n }\n }\n\n /**\n * Update permission level for an existing share\n */\n async updateSharePermission(\n shareId: string,\n newPermissionLevel: ListPermissionLevel\n ): Promise<ListShareResult> {\n try {\n const md = new Metadata();\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n\n const loaded = await permission.Load(shareId);\n if (!loaded) {\n return {\n success: false,\n message: 'Share not found'\n };\n }\n\n permission.PermissionLevel = newPermissionLevel;\n const saved = await permission.Save();\n\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'Permission updated successfully' : 'Failed to update permission'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error updating permission: ${errorMessage}`\n };\n }\n }\n\n /**\n * Remove a share (revoke access)\n */\n async removeShare(shareId: string): Promise<ListShareResult> {\n try {\n const md = new Metadata();\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n\n const loaded = await permission.Load(shareId);\n if (!loaded) {\n return {\n success: false,\n message: 'Share not found'\n };\n }\n\n const deleted = await permission.Delete();\n\n return {\n success: deleted,\n message: deleted ? 'Share removed successfully' : 'Failed to remove share'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error removing share: ${errorMessage}`\n };\n }\n }\n\n /**\n * Get lists shared with the current user (that they don't own)\n */\n async getListsSharedWithUser(userId: string): Promise<string[]> {\n const rv = new RunView();\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,\n Fields: ['ResourceRecordID'],\n ResultType: 'simple'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map((r: { ResourceRecordID: string }) => r.ResourceRecordID);\n }\n\n /**\n * Get lists that the user has shared with others\n */\n async getListsSharedByUser(userId: string): Promise<Map<string, number>> {\n // First get all lists owned by the user\n const rv = new RunView();\n\n const listsResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `UserID = '${userId}'`,\n Fields: ['ID'],\n ResultType: 'simple'\n });\n\n if (!listsResult.Success || !listsResult.Results || listsResult.Results.length === 0) {\n return new Map();\n }\n\n const listIds = listsResult.Results.map((l: { ID: string }) => l.ID);\n const listIdFilter = listIds.map((id: string) => `'${id}'`).join(',');\n\n // Get all shares for these lists\n const sharesResult = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID IN (${listIdFilter}) AND Status = 'Approved'`,\n Fields: ['ResourceRecordID'],\n ResultType: 'simple'\n });\n\n const shareCountMap = new Map<string, number>();\n\n if (sharesResult.Success && sharesResult.Results) {\n for (const share of sharesResult.Results) {\n const typedShare = share as { ResourceRecordID: string };\n const current = shareCountMap.get(typedShare.ResourceRecordID) || 0;\n shareCountMap.set(typedShare.ResourceRecordID, current + 1);\n }\n }\n\n return shareCountMap;\n }\n\n /**\n * Check if user can share a list (must be owner or have Owner permission)\n */\n async canUserShareList(listId: string, userId: string): Promise<boolean> {\n const rv = new RunView();\n\n // Check if user is the owner\n const listResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `ID = '${listId}' AND UserID = '${userId}'`,\n ResultType: 'simple'\n });\n\n if (listResult.Success && listResult.Results && listResult.Results.length > 0) {\n return true;\n }\n\n // Check if user has Owner permission\n const permissionLevel = await this.getUserPermissionLevel(listId, userId);\n return permissionLevel === 'Owner';\n }\n\n /**\n * Search users for sharing autocomplete\n */\n async searchUsers(searchTerm: string, limit: number = 10): Promise<ShareRecipient[]> {\n const rv = new RunView();\n\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: `(Name LIKE '%${searchTerm}%' OR Email LIKE '%${searchTerm}%') AND IsActive = 1`,\n OrderBy: 'Name',\n MaxRows: limit,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map(user => ({\n id: user.ID,\n name: user.Name,\n email: user.Email,\n type: 'User' as const\n }));\n }\n\n /**\n * Search roles for sharing autocomplete\n */\n async searchRoles(searchTerm: string, limit: number = 10): Promise<ShareRecipient[]> {\n const rv = new RunView();\n\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ExtraFilter: `Name LIKE '%${searchTerm}%'`,\n OrderBy: 'Name',\n MaxRows: limit,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map(role => ({\n id: role.ID,\n name: role.Name,\n type: 'Role' as const\n }));\n }\n\n /**\n * Get all available users (cached)\n */\n async getAllUsers(forceRefresh: boolean = false): Promise<MJUserEntity[]> {\n if (!forceRefresh && this.usersCache) {\n return this.usersCache;\n }\n\n const rv = new RunView();\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: 'IsActive = 1',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.usersCache = result.Results;\n return result.Results;\n }\n\n return [];\n }\n\n /**\n * Get all available roles (cached)\n */\n async getAllRoles(forceRefresh: boolean = false): Promise<MJRoleEntity[]> {\n if (!forceRefresh && this.rolesCache) {\n return this.rolesCache;\n }\n\n const rv = new RunView();\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.rolesCache = result.Results;\n return result.Results;\n }\n\n return [];\n }\n\n /**\n * Helper to find existing share\n */\n private async findExistingShare(\n listId: string,\n type: 'User' | 'Role',\n recipientId: string\n ): Promise<MJResourcePermissionEntity | null> {\n const rv = new RunView();\n const idField = type === 'User' ? 'UserID' : 'RoleID';\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Type = '${type}' AND ${idField} = '${recipientId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results && result.Results.length > 0) {\n return result.Results[0];\n }\n\n return null;\n }\n\n /**\n * Convert MJResourcePermissionEntity to ListShareInfo\n */\n private async convertToListShareInfo(permission: MJResourcePermissionEntity): Promise<ListShareInfo | null> {\n const rv = new RunView();\n\n if (permission.Type === 'User' && permission.UserID) {\n const userResult = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: `ID = '${permission.UserID}'`,\n ResultType: 'entity_object'\n });\n\n if (userResult.Success && userResult.Results && userResult.Results.length > 0) {\n const user = userResult.Results[0];\n return {\n shareId: permission.ID,\n listId: permission.ResourceRecordID,\n type: 'User',\n recipientId: permission.UserID,\n recipientName: user.Name,\n recipientEmail: user.Email,\n permissionLevel: permission.PermissionLevel as ListPermissionLevel,\n status: permission.Status as 'Approved' | 'Pending' | 'Rejected',\n startSharingAt: permission.StartSharingAt ? new Date(permission.StartSharingAt) : undefined,\n endSharingAt: permission.EndSharingAt ? new Date(permission.EndSharingAt) : undefined\n };\n }\n } else if (permission.Type === 'Role' && permission.RoleID) {\n const roleResult = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ExtraFilter: `ID = '${permission.RoleID}'`,\n ResultType: 'entity_object'\n });\n\n if (roleResult.Success && roleResult.Results && roleResult.Results.length > 0) {\n const role = roleResult.Results[0];\n return {\n shareId: permission.ID,\n listId: permission.ResourceRecordID,\n type: 'Role',\n recipientId: permission.RoleID,\n recipientName: role.Name,\n permissionLevel: permission.PermissionLevel as ListPermissionLevel,\n status: permission.Status as 'Approved' | 'Pending' | 'Rejected',\n startSharingAt: permission.StartSharingAt ? new Date(permission.StartSharingAt) : undefined,\n endSharingAt: permission.EndSharingAt ? new Date(permission.EndSharingAt) : undefined\n };\n }\n }\n\n return null;\n }\n\n /**\n * Get sharing summary for a single list\n */\n async getListSharingSummary(listId: string): Promise<{ listId: string; totalShares: number; userShares: number; roleShares: number; isSharedWithMe: boolean; isSharedByMe: boolean }> {\n const rv = new RunView();\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Status = 'Approved'`,\n Fields: ['ID', 'Type'],\n ResultType: 'simple'\n });\n\n let userShares = 0;\n let roleShares = 0;\n\n if (result.Success && result.Results) {\n for (const share of result.Results) {\n const typedShare = share as { ID: string; Type: string };\n if (typedShare.Type === 'User') {\n userShares++;\n } else if (typedShare.Type === 'Role') {\n roleShares++;\n }\n }\n }\n\n return {\n listId,\n totalShares: userShares + roleShares,\n userShares,\n roleShares,\n isSharedWithMe: false, // Would need current user context to determine\n isSharedByMe: userShares + roleShares > 0\n };\n }\n\n /**\n * Clear internal caches\n */\n clearCache(): void {\n this.usersCache = null;\n this.rolesCache = null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list-sharing.service.js","sourceRoot":"","sources":["../../../src/lib/services/list-sharing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport {\n MJListEntity,\n MJResourcePermissionEntity,\n MJResourceTypeEntity,\n MJUserEntity,\n MJRoleEntity\n} from '@memberjunction/core-entities';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { ListShareInfo, ListPermissionLevel, ShareRecipient, ListShareResult } from '../models/list-sharing.models';\n\n/**\n * Known List ResourceType ID from the database\n */\nconst LIST_RESOURCE_TYPE_ID = 'E64D433E-F36B-1410-8560-0041FA62858A';\n\n/**\n * Service for managing list sharing using the existing ResourcePermission system.\n * Lists are already registered as a ResourceType, so we use ResourcePermissions\n * to share lists with users and roles.\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 ListSharingService {\n private loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n // Cache for users and roles (for autocomplete)\n private usersCache: MJUserEntity[] | null = null;\n private rolesCache: MJRoleEntity[] | null = null;\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 the ResourceType ID for Lists\n */\n getListResourceTypeId(): string {\n return LIST_RESOURCE_TYPE_ID;\n }\n\n /**\n * Get all shares for a specific list\n */\n async getListShares(listId: string): Promise<ListShareInfo[]> {\n this.loadingSubject.next(true);\n\n try {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}'`,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n // Convert to ListShareInfo objects with user/role details\n const shares: ListShareInfo[] = [];\n\n for (const permission of result.Results) {\n const shareInfo = await this.convertToListShareInfo(permission);\n if (shareInfo) {\n shares.push(shareInfo);\n }\n }\n\n return shares;\n } finally {\n this.loadingSubject.next(false);\n }\n }\n\n /**\n * Get permission level for a specific user on a specific list\n */\n async getUserPermissionLevel(listId: string, userId: string): Promise<ListPermissionLevel | null> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Check direct user permission\n const userResult = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,\n ResultType: 'entity_object'\n });\n\n if (userResult.Success && userResult.Results && userResult.Results.length > 0) {\n return userResult.Results[0].PermissionLevel as ListPermissionLevel;\n }\n\n // If no direct permission, could check role-based permissions\n // For now, return null\n return null;\n }\n\n /**\n * Share a list with a user\n */\n async shareListWithUser(\n listId: string,\n userId: string,\n permissionLevel: ListPermissionLevel,\n sharedByUserId: string\n ): Promise<ListShareResult> {\n try {\n const md = this.Provider;\n\n // Check if share already exists\n const existing = await this.findExistingShare(listId, 'User', userId);\n\n if (existing) {\n // Update existing share\n existing.PermissionLevel = permissionLevel;\n existing.Status = 'Approved';\n const saved = await existing.Save();\n return {\n success: saved,\n shareId: existing.ID,\n message: saved ? 'Share updated successfully' : 'Failed to update share'\n };\n }\n\n // Create new share\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n permission.NewRecord();\n permission.ResourceTypeID = LIST_RESOURCE_TYPE_ID;\n permission.ResourceRecordID = listId;\n permission.Type = 'User';\n permission.UserID = userId;\n permission.PermissionLevel = permissionLevel;\n permission.Status = 'Approved';\n\n const saved = await permission.Save();\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'List shared successfully' : 'Failed to share list'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error sharing list: ${errorMessage}`\n };\n }\n }\n\n /**\n * Share a list with a role\n */\n async shareListWithRole(\n listId: string,\n roleId: string,\n permissionLevel: ListPermissionLevel,\n sharedByUserId: string\n ): Promise<ListShareResult> {\n try {\n const md = this.Provider;\n\n // Check if share already exists\n const existing = await this.findExistingShare(listId, 'Role', roleId);\n\n if (existing) {\n // Update existing share\n existing.PermissionLevel = permissionLevel;\n existing.Status = 'Approved';\n const saved = await existing.Save();\n return {\n success: saved,\n shareId: existing.ID,\n message: saved ? 'Share updated successfully' : 'Failed to update share'\n };\n }\n\n // Create new share\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n permission.NewRecord();\n permission.ResourceTypeID = LIST_RESOURCE_TYPE_ID;\n permission.ResourceRecordID = listId;\n permission.Type = 'Role';\n permission.RoleID = roleId;\n permission.PermissionLevel = permissionLevel;\n permission.Status = 'Approved';\n\n const saved = await permission.Save();\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'List shared with role successfully' : 'Failed to share list with role'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error sharing list: ${errorMessage}`\n };\n }\n }\n\n /**\n * Update permission level for an existing share\n */\n async updateSharePermission(\n shareId: string,\n newPermissionLevel: ListPermissionLevel\n ): Promise<ListShareResult> {\n try {\n const md = this.Provider;\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n\n const loaded = await permission.Load(shareId);\n if (!loaded) {\n return {\n success: false,\n message: 'Share not found'\n };\n }\n\n permission.PermissionLevel = newPermissionLevel;\n const saved = await permission.Save();\n\n return {\n success: saved,\n shareId: permission.ID,\n message: saved ? 'Permission updated successfully' : 'Failed to update permission'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error updating permission: ${errorMessage}`\n };\n }\n }\n\n /**\n * Remove a share (revoke access)\n */\n async removeShare(shareId: string): Promise<ListShareResult> {\n try {\n const md = this.Provider;\n const permission = await md.GetEntityObject<MJResourcePermissionEntity>('MJ: Resource Permissions');\n\n const loaded = await permission.Load(shareId);\n if (!loaded) {\n return {\n success: false,\n message: 'Share not found'\n };\n }\n\n const deleted = await permission.Delete();\n\n return {\n success: deleted,\n message: deleted ? 'Share removed successfully' : 'Failed to remove share'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error removing share: ${errorMessage}`\n };\n }\n }\n\n /**\n * Get lists shared with the current user (that they don't own)\n */\n async getListsSharedWithUser(userId: string): Promise<string[]> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND Type = 'User' AND UserID = '${userId}' AND Status = 'Approved'`,\n Fields: ['ResourceRecordID'],\n ResultType: 'simple'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map((r: { ResourceRecordID: string }) => r.ResourceRecordID);\n }\n\n /**\n * Get lists that the user has shared with others\n */\n async getListsSharedByUser(userId: string): Promise<Map<string, number>> {\n // First get all lists owned by the user\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const listsResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `UserID = '${userId}'`,\n Fields: ['ID'],\n ResultType: 'simple'\n });\n\n if (!listsResult.Success || !listsResult.Results || listsResult.Results.length === 0) {\n return new Map();\n }\n\n const listIds = listsResult.Results.map((l: { ID: string }) => l.ID);\n const listIdFilter = listIds.map((id: string) => `'${id}'`).join(',');\n\n // Get all shares for these lists\n const sharesResult = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID IN (${listIdFilter}) AND Status = 'Approved'`,\n Fields: ['ResourceRecordID'],\n ResultType: 'simple'\n });\n\n const shareCountMap = new Map<string, number>();\n\n if (sharesResult.Success && sharesResult.Results) {\n for (const share of sharesResult.Results) {\n const typedShare = share as { ResourceRecordID: string };\n const current = shareCountMap.get(typedShare.ResourceRecordID) || 0;\n shareCountMap.set(typedShare.ResourceRecordID, current + 1);\n }\n }\n\n return shareCountMap;\n }\n\n /**\n * Check if user can share a list (must be owner or have Owner permission)\n */\n async canUserShareList(listId: string, userId: string): Promise<boolean> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n // Check if user is the owner\n const listResult = await rv.RunView<MJListEntity>({\n EntityName: 'MJ: Lists',\n ExtraFilter: `ID = '${listId}' AND UserID = '${userId}'`,\n ResultType: 'simple'\n });\n\n if (listResult.Success && listResult.Results && listResult.Results.length > 0) {\n return true;\n }\n\n // Check if user has Owner permission\n const permissionLevel = await this.getUserPermissionLevel(listId, userId);\n return permissionLevel === 'Owner';\n }\n\n /**\n * Search users for sharing autocomplete\n */\n async searchUsers(searchTerm: string, limit: number = 10): Promise<ShareRecipient[]> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: `(Name LIKE '%${searchTerm}%' OR Email LIKE '%${searchTerm}%') AND IsActive = 1`,\n OrderBy: 'Name',\n MaxRows: limit,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map(user => ({\n id: user.ID,\n name: user.Name,\n email: user.Email,\n type: 'User' as const\n }));\n }\n\n /**\n * Search roles for sharing autocomplete\n */\n async searchRoles(searchTerm: string, limit: number = 10): Promise<ShareRecipient[]> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ExtraFilter: `Name LIKE '%${searchTerm}%'`,\n OrderBy: 'Name',\n MaxRows: limit,\n ResultType: 'entity_object'\n });\n\n if (!result.Success || !result.Results) {\n return [];\n }\n\n return result.Results.map(role => ({\n id: role.ID,\n name: role.Name,\n type: 'Role' as const\n }));\n }\n\n /**\n * Get all available users (cached)\n */\n async getAllUsers(forceRefresh: boolean = false): Promise<MJUserEntity[]> {\n if (!forceRefresh && this.usersCache) {\n return this.usersCache;\n }\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: 'IsActive = 1',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.usersCache = result.Results;\n return result.Results;\n }\n\n return [];\n }\n\n /**\n * Get all available roles (cached)\n */\n async getAllRoles(forceRefresh: boolean = false): Promise<MJRoleEntity[]> {\n if (!forceRefresh && this.rolesCache) {\n return this.rolesCache;\n }\n\n const rv = RunView.FromMetadataProvider(this.Provider);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n OrderBy: 'Name',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.rolesCache = result.Results;\n return result.Results;\n }\n\n return [];\n }\n\n /**\n * Helper to find existing share\n */\n private async findExistingShare(\n listId: string,\n type: 'User' | 'Role',\n recipientId: string\n ): Promise<MJResourcePermissionEntity | null> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n const idField = type === 'User' ? 'UserID' : 'RoleID';\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Type = '${type}' AND ${idField} = '${recipientId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results && result.Results.length > 0) {\n return result.Results[0];\n }\n\n return null;\n }\n\n /**\n * Convert MJResourcePermissionEntity to ListShareInfo\n */\n private async convertToListShareInfo(permission: MJResourcePermissionEntity): Promise<ListShareInfo | null> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n if (permission.Type === 'User' && permission.UserID) {\n const userResult = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ExtraFilter: `ID = '${permission.UserID}'`,\n ResultType: 'entity_object'\n });\n\n if (userResult.Success && userResult.Results && userResult.Results.length > 0) {\n const user = userResult.Results[0];\n return {\n shareId: permission.ID,\n listId: permission.ResourceRecordID,\n type: 'User',\n recipientId: permission.UserID,\n recipientName: user.Name,\n recipientEmail: user.Email,\n permissionLevel: permission.PermissionLevel as ListPermissionLevel,\n status: permission.Status as 'Approved' | 'Pending' | 'Rejected',\n startSharingAt: permission.StartSharingAt ? new Date(permission.StartSharingAt) : undefined,\n endSharingAt: permission.EndSharingAt ? new Date(permission.EndSharingAt) : undefined\n };\n }\n } else if (permission.Type === 'Role' && permission.RoleID) {\n const roleResult = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ExtraFilter: `ID = '${permission.RoleID}'`,\n ResultType: 'entity_object'\n });\n\n if (roleResult.Success && roleResult.Results && roleResult.Results.length > 0) {\n const role = roleResult.Results[0];\n return {\n shareId: permission.ID,\n listId: permission.ResourceRecordID,\n type: 'Role',\n recipientId: permission.RoleID,\n recipientName: role.Name,\n permissionLevel: permission.PermissionLevel as ListPermissionLevel,\n status: permission.Status as 'Approved' | 'Pending' | 'Rejected',\n startSharingAt: permission.StartSharingAt ? new Date(permission.StartSharingAt) : undefined,\n endSharingAt: permission.EndSharingAt ? new Date(permission.EndSharingAt) : undefined\n };\n }\n }\n\n return null;\n }\n\n /**\n * Get sharing summary for a single list\n */\n async getListSharingSummary(listId: string): Promise<{ listId: string; totalShares: number; userShares: number; roleShares: number; isSharedWithMe: boolean; isSharedByMe: boolean }> {\n const rv = RunView.FromMetadataProvider(this.Provider);\n\n const result = await rv.RunView<MJResourcePermissionEntity>({\n EntityName: 'MJ: Resource Permissions',\n ExtraFilter: `ResourceTypeID = '${LIST_RESOURCE_TYPE_ID}' AND ResourceRecordID = '${listId}' AND Status = 'Approved'`,\n Fields: ['ID', 'Type'],\n ResultType: 'simple'\n });\n\n let userShares = 0;\n let roleShares = 0;\n\n if (result.Success && result.Results) {\n for (const share of result.Results) {\n const typedShare = share as { ID: string; Type: string };\n if (typedShare.Type === 'User') {\n userShares++;\n } else if (typedShare.Type === 'Role') {\n roleShares++;\n }\n }\n }\n\n return {\n listId,\n totalShares: userShares + roleShares,\n userShares,\n roleShares,\n isSharedWithMe: false, // Would need current user context to determine\n isSharedByMe: userShares + roleShares > 0\n };\n }\n\n /**\n * Clear internal caches\n */\n clearCache(): void {\n this.usersCache = null;\n this.rolesCache = null;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-list-management",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.31.0",
|
|
4
4
|
"description": "MemberJunction: Angular Components for managing entity list membership with beautiful, responsive UI",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -33,18 +33,19 @@
|
|
|
33
33
|
"rxjs": "^7.8.2"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@memberjunction/core": "5.
|
|
37
|
-
"@memberjunction/core-entities": "5.
|
|
38
|
-
"@memberjunction/global": "5.
|
|
39
|
-
"@memberjunction/ng-container-directives": "5.
|
|
40
|
-
"@memberjunction/ng-shared": "5.
|
|
41
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
42
|
-
"@memberjunction/ng-ui-components": "5.
|
|
43
|
-
"tslib": "^2.8.1"
|
|
36
|
+
"@memberjunction/core": "5.31.0",
|
|
37
|
+
"@memberjunction/core-entities": "5.31.0",
|
|
38
|
+
"@memberjunction/global": "5.31.0",
|
|
39
|
+
"@memberjunction/ng-container-directives": "5.31.0",
|
|
40
|
+
"@memberjunction/ng-shared": "5.31.0",
|
|
41
|
+
"@memberjunction/ng-shared-generic": "5.31.0",
|
|
42
|
+
"@memberjunction/ng-ui-components": "5.31.0",
|
|
43
|
+
"tslib": "^2.8.1",
|
|
44
|
+
"@memberjunction/ng-base-types": "5.31.0"
|
|
44
45
|
},
|
|
45
46
|
"sideEffects": false,
|
|
46
47
|
"repository": {
|
|
47
48
|
"type": "git",
|
|
48
49
|
"url": "https://github.com/MemberJunction/MJ"
|
|
49
50
|
}
|
|
50
|
-
}
|
|
51
|
+
}
|