@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.
@@ -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 = new RunView();
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 = new RunView();
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 = new Metadata();
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 = new Metadata();
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 = new Metadata();
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 = new Metadata();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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 = new RunView();
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAqB,QAAQ,EAAE,OAAO,EAAY,MAAM,sBAAsB,CAAC;AAQtF,OAAO,EAAE,eAAe,EAAc,MAAM,MAAM,CAAC;;AAGnD;;GAEG;AACH,MAAM,qBAAqB,GAAG,sCAAsC,CAAC;AAErE;;;;;;;GAOG;AAIH,MAAM,OAAO,kBAAkB;IACrB,cAAc,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC,CAAC;IACtD,QAAQ,GAAwB,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;IAE1E,+CAA+C;IACvC,UAAU,GAA0B,IAAI,CAAC;IACzC,UAAU,GAA0B,IAAI,CAAC;IAEzC,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,qBAAqB;QACnB,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,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,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;gBAC1D,UAAU,EAAE,0BAA0B;gBACtC,WAAW,EAAE,qBAAqB,qBAAqB,6BAA6B,MAAM,GAAG;gBAC7F,UAAU,EAAE,eAAe;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACvC,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,0DAA0D;YAC1D,MAAM,MAAM,GAAoB,EAAE,CAAC;YAEnC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;gBAChE,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,MAAc,EAAE,MAAc;QACzD,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,+BAA+B;QAC/B,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;YAC9D,UAAU,EAAE,0BAA0B;YACtC,WAAW,EAAE,qBAAqB,qBAAqB,6BAA6B,MAAM,qCAAqC,MAAM,2BAA2B;YAChK,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9E,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAsC,CAAC;QACtE,CAAC;QAED,8DAA8D;QAC9D,uBAAuB;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,MAAc,EACd,MAAc,EACd,eAAoC,EACpC,cAAsB;QAEtB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YAEzB,gCAAgC;YAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAEtE,IAAI,QAAQ,EAAE,CAAC;gBACb,wBAAwB;gBACxB,QAAQ,CAAC,eAAe,GAAG,eAAe,CAAC;gBAC3C,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC;gBAC7B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpC,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,QAAQ,CAAC,EAAE;oBACpB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,wBAAwB;iBACzE,CAAC;YACJ,CAAC;YAED,mBAAmB;YACnB,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,CAAC,CAAC;YACpG,UAAU,CAAC,SAAS,EAAE,CAAC;YACvB,UAAU,CAAC,cAAc,GAAG,qBAAqB,CAAC;YAClD,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC;YACrC,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;YACzB,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;YAC3B,UAAU,CAAC,eAAe,GAAG,eAAe,CAAC;YAC7C,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC;YAE/B,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,UAAU,CAAC,EAAE;gBACtB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,sBAAsB;aACrE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,uBAAuB,YAAY,EAAE;aAC/C,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,MAAc,EACd,MAAc,EACd,eAAoC,EACpC,cAAsB;QAEtB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YAEzB,gCAAgC;YAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAEtE,IAAI,QAAQ,EAAE,CAAC;gBACb,wBAAwB;gBACxB,QAAQ,CAAC,eAAe,GAAG,eAAe,CAAC;gBAC3C,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC;gBAC7B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpC,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,QAAQ,CAAC,EAAE;oBACpB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,wBAAwB;iBACzE,CAAC;YACJ,CAAC;YAED,mBAAmB;YACnB,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,CAAC,CAAC;YACpG,UAAU,CAAC,SAAS,EAAE,CAAC;YACvB,UAAU,CAAC,cAAc,GAAG,qBAAqB,CAAC;YAClD,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC;YACrC,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;YACzB,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;YAC3B,UAAU,CAAC,eAAe,GAAG,eAAe,CAAC;YAC7C,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC;YAE/B,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,UAAU,CAAC,EAAE;gBACtB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,gCAAgC;aACzF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,uBAAuB,YAAY,EAAE;aAC/C,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CACzB,OAAe,EACf,kBAAuC;QAEvC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YACzB,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,CAAC,CAAC;YAEpG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,iBAAiB;iBAC3B,CAAC;YACJ,CAAC;YAED,UAAU,CAAC,eAAe,GAAG,kBAAkB,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YAEtC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,UAAU,CAAC,EAAE;gBACtB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,6BAA6B;aACnF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,8BAA8B,YAAY,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YACzB,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,CAAC,CAAC;YAEpG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,iBAAiB;iBAC3B,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,wBAAwB;aAC3E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,yBAAyB,YAAY,EAAE;aACjD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,MAAc;QACzC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;YAC1D,UAAU,EAAE,0BAA0B;YACtC,WAAW,EAAE,qBAAqB,qBAAqB,qCAAqC,MAAM,2BAA2B;YAC7H,MAAM,EAAE,CAAC,kBAAkB,CAAC;YAC5B,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAA+B,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACrF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,oBAAoB,CAAC,MAAc;QACvC,wCAAwC;QACxC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YACjD,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,aAAa,MAAM,GAAG;YACnC,MAAM,EAAE,CAAC,IAAI,CAAC;YACd,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrF,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEtE,iCAAiC;QACjC,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;YAChE,UAAU,EAAE,0BAA0B;YACtC,WAAW,EAAE,qBAAqB,qBAAqB,8BAA8B,YAAY,2BAA2B;YAC5H,MAAM,EAAE,CAAC,kBAAkB,CAAC;YAC5B,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEhD,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACjD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;gBACzC,MAAM,UAAU,GAAG,KAAqC,CAAC;gBACzD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBACpE,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,MAAc,EAAE,MAAc;QACnD,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,6BAA6B;QAC7B,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAChD,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,SAAS,MAAM,mBAAmB,MAAM,GAAG;YACxD,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qCAAqC;QACrC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1E,OAAO,eAAe,KAAK,OAAO,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,UAAkB,EAAE,QAAgB,EAAE;QACtD,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,gBAAgB,UAAU,sBAAsB,UAAU,sBAAsB;YAC7F,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,MAAe;SACtB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,UAAkB,EAAE,QAAgB,EAAE;QACtD,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,eAAe,UAAU,IAAI;YAC1C,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,MAAe;SACtB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,eAAwB,KAAK;QAC7C,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,WAAW,EAAE,cAAc;YAC3B,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC;YACjC,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,eAAwB,KAAK;QAC7C,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU,CAAC;QACzB,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC;YACjC,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAC7B,MAAc,EACd,IAAqB,EACrB,WAAmB;QAEnB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEtD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;YAC1D,UAAU,EAAE,0BAA0B;YACtC,WAAW,EAAE,qBAAqB,qBAAqB,6BAA6B,MAAM,iBAAiB,IAAI,SAAS,OAAO,OAAO,WAAW,GAAG;YACpJ,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAAC,UAAsC;QACzE,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACpD,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;gBAChD,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,SAAS,UAAU,CAAC,MAAM,GAAG;gBAC1C,UAAU,EAAE,eAAe;aAC5B,CAAC,CAAC;YAEH,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9E,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,UAAU,CAAC,EAAE;oBACtB,MAAM,EAAE,UAAU,CAAC,gBAAgB;oBACnC,IAAI,EAAE,MAAM;oBACZ,WAAW,EAAE,UAAU,CAAC,MAAM;oBAC9B,aAAa,EAAE,IAAI,CAAC,IAAI;oBACxB,cAAc,EAAE,IAAI,CAAC,KAAK;oBAC1B,eAAe,EAAE,UAAU,CAAC,eAAsC;oBAClE,MAAM,EAAE,UAAU,CAAC,MAA6C;oBAChE,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;oBAC3F,YAAY,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;iBACtF,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YAC3D,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;gBAChD,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,SAAS,UAAU,CAAC,MAAM,GAAG;gBAC1C,UAAU,EAAE,eAAe;aAC5B,CAAC,CAAC;YAEH,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9E,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,UAAU,CAAC,EAAE;oBACtB,MAAM,EAAE,UAAU,CAAC,gBAAgB;oBACnC,IAAI,EAAE,MAAM;oBACZ,WAAW,EAAE,UAAU,CAAC,MAAM;oBAC9B,aAAa,EAAE,IAAI,CAAC,IAAI;oBACxB,eAAe,EAAE,UAAU,CAAC,eAAsC;oBAClE,MAAM,EAAE,UAAU,CAAC,MAA6C;oBAChE,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;oBAC3F,YAAY,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;iBACtF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,MAAc;QACxC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;YAC1D,UAAU,EAAE,0BAA0B;YACtC,WAAW,EAAE,qBAAqB,qBAAqB,6BAA6B,MAAM,2BAA2B;YACrH,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,KAAqC,CAAC;gBACzD,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC/B,UAAU,EAAE,CAAC;gBACf,CAAC;qBAAM,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACtC,UAAU,EAAE,CAAC;gBACf,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM;YACN,WAAW,EAAE,UAAU,GAAG,UAAU;YACpC,UAAU;YACV,UAAU;YACV,cAAc,EAAE,KAAK,EAAE,+CAA+C;YACtE,YAAY,EAAE,UAAU,GAAG,UAAU,GAAG,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;4GA5iBU,kBAAkB;gEAAlB,kBAAkB,WAAlB,kBAAkB,mBAFjB,MAAM;;iFAEP,kBAAkB;cAH9B,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","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.30.1",
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.30.1",
37
- "@memberjunction/core-entities": "5.30.1",
38
- "@memberjunction/global": "5.30.1",
39
- "@memberjunction/ng-container-directives": "5.30.1",
40
- "@memberjunction/ng-shared": "5.30.1",
41
- "@memberjunction/ng-shared-generic": "5.30.1",
42
- "@memberjunction/ng-ui-components": "5.30.1",
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
+ }