@memberjunction/ng-conversations 2.107.0 → 2.108.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.
Files changed (108) hide show
  1. package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts +67 -0
  2. package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -0
  3. package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +725 -0
  4. package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -0
  5. package/dist/lib/components/collection/artifact-create-modal.component.d.ts +39 -0
  6. package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -0
  7. package/dist/lib/components/collection/artifact-create-modal.component.js +351 -0
  8. package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -0
  9. package/dist/lib/components/collection/collection-form-modal.component.d.ts +3 -1
  10. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  11. package/dist/lib/components/collection/collection-form-modal.component.js +60 -10
  12. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  13. package/dist/lib/components/collection/collection-share-modal.component.d.ts +43 -0
  14. package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -0
  15. package/dist/lib/components/collection/collection-share-modal.component.js +728 -0
  16. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -0
  17. package/dist/lib/components/collection/collection-tree.component.d.ts +8 -1
  18. package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
  19. package/dist/lib/components/collection/collection-tree.component.js +217 -115
  20. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  21. package/dist/lib/components/collection/collection-view.component.d.ts +2 -1
  22. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  23. package/dist/lib/components/collection/collection-view.component.js +52 -34
  24. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  25. package/dist/lib/components/collection/collections-full-view.component.d.ts +45 -9
  26. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  27. package/dist/lib/components/collection/collections-full-view.component.js +586 -220
  28. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  29. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +42 -15
  30. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  31. package/dist/lib/components/conversation/conversation-chat-area.component.js +336 -219
  32. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  33. package/dist/lib/components/message/message-input.component.d.ts +7 -1
  34. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  35. package/dist/lib/components/message/message-input.component.js +65 -10
  36. package/dist/lib/components/message/message-input.component.js.map +1 -1
  37. package/dist/lib/components/message/message-item.component.d.ts +39 -5
  38. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  39. package/dist/lib/components/message/message-item.component.js +259 -137
  40. package/dist/lib/components/message/message-item.component.js.map +1 -1
  41. package/dist/lib/components/message/message-list.component.d.ts +5 -1
  42. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  43. package/dist/lib/components/message/message-list.component.js +26 -12
  44. package/dist/lib/components/message/message-list.component.js.map +1 -1
  45. package/dist/lib/components/message/suggested-responses.component.d.ts +55 -0
  46. package/dist/lib/components/message/suggested-responses.component.d.ts.map +1 -0
  47. package/dist/lib/components/message/suggested-responses.component.js +207 -0
  48. package/dist/lib/components/message/suggested-responses.component.js.map +1 -0
  49. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  50. package/dist/lib/components/search/search-panel.component.js +245 -113
  51. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  52. package/dist/lib/components/shared/user-picker.component.d.ts +29 -0
  53. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -0
  54. package/dist/lib/components/shared/user-picker.component.js +229 -0
  55. package/dist/lib/components/shared/user-picker.component.js.map +1 -0
  56. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +7 -1
  57. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  58. package/dist/lib/components/tasks/tasks-dropdown.component.js +36 -6
  59. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  60. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +19 -2
  61. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  62. package/dist/lib/components/workspace/conversation-workspace.component.js +167 -58
  63. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  64. package/dist/lib/conversations.module.d.ts +52 -47
  65. package/dist/lib/conversations.module.d.ts.map +1 -1
  66. package/dist/lib/conversations.module.js +27 -4
  67. package/dist/lib/conversations.module.js.map +1 -1
  68. package/dist/lib/models/conversation-complete-query.model.d.ts +75 -0
  69. package/dist/lib/models/conversation-complete-query.model.d.ts.map +1 -0
  70. package/dist/lib/models/conversation-complete-query.model.js +19 -0
  71. package/dist/lib/models/conversation-complete-query.model.js.map +1 -0
  72. package/dist/lib/models/conversation-state.model.d.ts +27 -0
  73. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  74. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  75. package/dist/lib/services/agent-state.service.js +5 -0
  76. package/dist/lib/services/agent-state.service.js.map +1 -1
  77. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  78. package/dist/lib/services/artifact-state.service.js +14 -9
  79. package/dist/lib/services/artifact-state.service.js.map +1 -1
  80. package/dist/lib/services/collection-permission.service.d.ts +96 -0
  81. package/dist/lib/services/collection-permission.service.d.ts.map +1 -0
  82. package/dist/lib/services/collection-permission.service.js +303 -0
  83. package/dist/lib/services/collection-permission.service.js.map +1 -0
  84. package/dist/lib/services/collection-state.service.d.ts +34 -0
  85. package/dist/lib/services/collection-state.service.d.ts.map +1 -0
  86. package/dist/lib/services/collection-state.service.js +50 -0
  87. package/dist/lib/services/collection-state.service.js.map +1 -0
  88. package/dist/lib/services/conversation-agent.service.d.ts +9 -4
  89. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  90. package/dist/lib/services/conversation-agent.service.js +41 -12
  91. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  92. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  93. package/dist/lib/services/data-cache.service.js +5 -0
  94. package/dist/lib/services/data-cache.service.js.map +1 -1
  95. package/dist/lib/services/mention-autocomplete.service.js +1 -1
  96. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  97. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  98. package/dist/lib/services/mention-parser.service.js +0 -5
  99. package/dist/lib/services/mention-parser.service.js.map +1 -1
  100. package/dist/lib/services/search.service.d.ts +26 -3
  101. package/dist/lib/services/search.service.d.ts.map +1 -1
  102. package/dist/lib/services/search.service.js +172 -12
  103. package/dist/lib/services/search.service.js.map +1 -1
  104. package/dist/public-api.d.ts +3 -0
  105. package/dist/public-api.d.ts.map +1 -1
  106. package/dist/public-api.js +3 -0
  107. package/dist/public-api.js.map +1 -1
  108. package/package.json +12 -12
@@ -0,0 +1,96 @@
1
+ import { UserInfo } from '@memberjunction/core';
2
+ import { CollectionPermissionEntity } from '@memberjunction/core-entities';
3
+ import * as i0 from "@angular/core";
4
+ export interface CollectionPermission {
5
+ id: string;
6
+ collectionId: string;
7
+ userId: string;
8
+ userName: string;
9
+ canRead: boolean;
10
+ canShare: boolean;
11
+ canEdit: boolean;
12
+ canDelete: boolean;
13
+ sharedByUserId: string | null;
14
+ sharedByUserName: string | null;
15
+ sharedAt: Date;
16
+ }
17
+ export interface PermissionSet {
18
+ canRead: boolean;
19
+ canShare: boolean;
20
+ canEdit: boolean;
21
+ canDelete: boolean;
22
+ }
23
+ export declare class CollectionPermissionService {
24
+ /**
25
+ * Load all permissions for a collection
26
+ */
27
+ loadPermissions(collectionId: string, currentUser: UserInfo): Promise<CollectionPermission[]>;
28
+ /**
29
+ * Check if user has permission for a collection
30
+ */
31
+ checkPermission(collectionId: string, userId: string, currentUser: UserInfo): Promise<CollectionPermission | null>;
32
+ /**
33
+ * Check permissions for multiple collections at once (efficient bulk loading)
34
+ */
35
+ checkBulkPermissions(collectionIds: string[], userId: string, currentUser: UserInfo): Promise<Map<string, CollectionPermission>>;
36
+ /**
37
+ * Grant permission to a user
38
+ */
39
+ grantPermission(collectionId: string, userId: string, permissions: PermissionSet, sharedByUserId: string, currentUser: UserInfo): Promise<CollectionPermissionEntity>;
40
+ /**
41
+ * Grant permission and cascade to all child collections
42
+ */
43
+ grantPermissionCascade(collectionId: string, userId: string, permissions: PermissionSet, sharedByUserId: string, currentUser: UserInfo): Promise<void>;
44
+ /**
45
+ * Recursively grant permissions on all child collections
46
+ */
47
+ private grantChildPermissions;
48
+ /**
49
+ * Update existing permission
50
+ */
51
+ updatePermission(permissionId: string, permissions: PermissionSet, currentUser: UserInfo): Promise<boolean>;
52
+ /**
53
+ * Update permission and cascade to all child collections
54
+ */
55
+ updatePermissionCascade(collectionId: string, userId: string, permissions: PermissionSet, currentUser: UserInfo): Promise<void>;
56
+ /**
57
+ * Recursively update permissions on all child collections
58
+ */
59
+ private updateChildPermissions;
60
+ /**
61
+ * Revoke permission
62
+ */
63
+ revokePermission(permissionId: string, currentUser: UserInfo): Promise<boolean>;
64
+ /**
65
+ * Revoke permission and cascade to all child collections
66
+ */
67
+ revokePermissionCascade(collectionId: string, userId: string, currentUser: UserInfo): Promise<void>;
68
+ /**
69
+ * Recursively revoke permissions on all child collections
70
+ */
71
+ private revokeChildPermissions;
72
+ /**
73
+ * Validate that requested permissions don't exceed granter's permissions
74
+ */
75
+ validatePermissions(requested: PermissionSet, granter: PermissionSet, isOwner: boolean): boolean;
76
+ /**
77
+ * Get available permissions for a user to grant based on their own permissions
78
+ */
79
+ getAvailablePermissions(userPermissions: PermissionSet, isOwner: boolean): string[];
80
+ /**
81
+ * Copy all permissions from parent collection to child collection
82
+ */
83
+ copyParentPermissions(parentCollectionId: string, childCollectionId: string, currentUser: UserInfo): Promise<void>;
84
+ /**
85
+ * Delete all permissions for a collection
86
+ */
87
+ deleteAllPermissions(collectionId: string, currentUser: UserInfo): Promise<void>;
88
+ /**
89
+ * Create owner permission record (all permissions enabled)
90
+ */
91
+ createOwnerPermission(collectionId: string, ownerId: string, currentUser: UserInfo): Promise<void>;
92
+ private mapToPermission;
93
+ static ɵfac: i0.ɵɵFactoryDeclaration<CollectionPermissionService, never>;
94
+ static ɵprov: i0.ɵɵInjectableDeclaration<CollectionPermissionService>;
95
+ }
96
+ //# sourceMappingURL=collection-permission.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-permission.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/collection-permission.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,303 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { RunView, Metadata } from '@memberjunction/core';
3
+ import * as i0 from "@angular/core";
4
+ export class CollectionPermissionService {
5
+ /**
6
+ * Load all permissions for a collection
7
+ */
8
+ async loadPermissions(collectionId, currentUser) {
9
+ const rv = new RunView();
10
+ const result = await rv.RunView({
11
+ EntityName: 'MJ: Collection Permissions',
12
+ ExtraFilter: `CollectionID='${collectionId}'`,
13
+ OrderBy: '__mj_CreatedAt ASC',
14
+ ResultType: 'entity_object'
15
+ }, currentUser);
16
+ if (result.Success && result.Results) {
17
+ return result.Results.map(p => this.mapToPermission(p));
18
+ }
19
+ return [];
20
+ }
21
+ /**
22
+ * Check if user has permission for a collection
23
+ */
24
+ async checkPermission(collectionId, userId, currentUser) {
25
+ const rv = new RunView();
26
+ const result = await rv.RunView({
27
+ EntityName: 'MJ: Collection Permissions',
28
+ ExtraFilter: `CollectionID='${collectionId}' AND UserID='${userId}'`,
29
+ MaxRows: 1,
30
+ ResultType: 'entity_object'
31
+ }, currentUser);
32
+ if (result.Success && result.Results && result.Results.length > 0) {
33
+ return this.mapToPermission(result.Results[0]);
34
+ }
35
+ return null;
36
+ }
37
+ /**
38
+ * Check permissions for multiple collections at once (efficient bulk loading)
39
+ */
40
+ async checkBulkPermissions(collectionIds, userId, currentUser) {
41
+ const resultMap = new Map();
42
+ if (collectionIds.length === 0) {
43
+ return resultMap;
44
+ }
45
+ // Build filter for all collection IDs
46
+ const collectionFilter = collectionIds.map(id => `CollectionID='${id}'`).join(' OR ');
47
+ const rv = new RunView();
48
+ const result = await rv.RunView({
49
+ EntityName: 'MJ: Collection Permissions',
50
+ ExtraFilter: `(${collectionFilter}) AND UserID='${userId}'`,
51
+ ResultType: 'entity_object'
52
+ }, currentUser);
53
+ if (result.Success && result.Results) {
54
+ for (const entity of result.Results) {
55
+ const permission = this.mapToPermission(entity);
56
+ resultMap.set(entity.CollectionID, permission);
57
+ }
58
+ }
59
+ return resultMap;
60
+ }
61
+ /**
62
+ * Grant permission to a user
63
+ */
64
+ async grantPermission(collectionId, userId, permissions, sharedByUserId, currentUser) {
65
+ const md = new Metadata();
66
+ const permission = await md.GetEntityObject('MJ: Collection Permissions', currentUser);
67
+ permission.CollectionID = collectionId;
68
+ permission.UserID = userId;
69
+ permission.CanRead = permissions.canRead;
70
+ permission.CanShare = permissions.canShare;
71
+ permission.CanEdit = permissions.canEdit;
72
+ permission.CanDelete = permissions.canDelete;
73
+ permission.SharedByUserID = sharedByUserId;
74
+ const saved = await permission.Save();
75
+ if (!saved) {
76
+ throw new Error(permission.LatestResult?.Message || 'Failed to grant permission');
77
+ }
78
+ return permission;
79
+ }
80
+ /**
81
+ * Grant permission and cascade to all child collections
82
+ */
83
+ async grantPermissionCascade(collectionId, userId, permissions, sharedByUserId, currentUser) {
84
+ // Grant permission on current collection
85
+ await this.grantPermission(collectionId, userId, permissions, sharedByUserId, currentUser);
86
+ // Grant permissions on all child collections recursively
87
+ await this.grantChildPermissions(collectionId, userId, permissions, sharedByUserId, currentUser);
88
+ }
89
+ /**
90
+ * Recursively grant permissions on all child collections
91
+ */
92
+ async grantChildPermissions(parentCollectionId, userId, permissions, sharedByUserId, currentUser) {
93
+ const rv = new RunView();
94
+ const childrenResult = await rv.RunView({
95
+ EntityName: 'MJ: Collections',
96
+ ExtraFilter: `ParentID='${parentCollectionId}'`,
97
+ ResultType: 'entity_object'
98
+ }, currentUser);
99
+ if (childrenResult.Success && childrenResult.Results) {
100
+ for (const child of childrenResult.Results) {
101
+ // Check if permission already exists
102
+ const existing = await this.checkPermission(child.ID, userId, currentUser);
103
+ if (existing) {
104
+ // Permission exists, update it instead
105
+ await this.updatePermission(existing.id, permissions, currentUser);
106
+ }
107
+ else {
108
+ // Grant new permission
109
+ await this.grantPermission(child.ID, userId, permissions, sharedByUserId, currentUser);
110
+ }
111
+ // Recursively grant to grandchildren
112
+ await this.grantChildPermissions(child.ID, userId, permissions, sharedByUserId, currentUser);
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Update existing permission
118
+ */
119
+ async updatePermission(permissionId, permissions, currentUser) {
120
+ const md = new Metadata();
121
+ const permission = await md.GetEntityObject('MJ: Collection Permissions', currentUser);
122
+ await permission.Load(permissionId);
123
+ permission.CanRead = permissions.canRead;
124
+ permission.CanShare = permissions.canShare;
125
+ permission.CanEdit = permissions.canEdit;
126
+ permission.CanDelete = permissions.canDelete;
127
+ return await permission.Save();
128
+ }
129
+ /**
130
+ * Update permission and cascade to all child collections
131
+ */
132
+ async updatePermissionCascade(collectionId, userId, permissions, currentUser) {
133
+ // Update permission on current collection
134
+ const permission = await this.checkPermission(collectionId, userId, currentUser);
135
+ if (permission) {
136
+ await this.updatePermission(permission.id, permissions, currentUser);
137
+ }
138
+ // Get all child collections and update recursively
139
+ await this.updateChildPermissions(collectionId, userId, permissions, currentUser);
140
+ }
141
+ /**
142
+ * Recursively update permissions on all child collections
143
+ */
144
+ async updateChildPermissions(parentCollectionId, userId, permissions, currentUser) {
145
+ const rv = new RunView();
146
+ const childrenResult = await rv.RunView({
147
+ EntityName: 'MJ: Collections',
148
+ ExtraFilter: `ParentID='${parentCollectionId}'`,
149
+ ResultType: 'entity_object'
150
+ }, currentUser);
151
+ if (childrenResult.Success && childrenResult.Results) {
152
+ for (const child of childrenResult.Results) {
153
+ // Update permission if it exists for this user on the child collection
154
+ const childPermission = await this.checkPermission(child.ID, userId, currentUser);
155
+ if (childPermission) {
156
+ await this.updatePermission(childPermission.id, permissions, currentUser);
157
+ }
158
+ // Recursively update grandchildren
159
+ await this.updateChildPermissions(child.ID, userId, permissions, currentUser);
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * Revoke permission
165
+ */
166
+ async revokePermission(permissionId, currentUser) {
167
+ const md = new Metadata();
168
+ const permission = await md.GetEntityObject('MJ: Collection Permissions', currentUser);
169
+ await permission.Load(permissionId);
170
+ return await permission.Delete();
171
+ }
172
+ /**
173
+ * Revoke permission and cascade to all child collections
174
+ */
175
+ async revokePermissionCascade(collectionId, userId, currentUser) {
176
+ // Revoke permission on current collection
177
+ const permission = await this.checkPermission(collectionId, userId, currentUser);
178
+ if (permission) {
179
+ await this.revokePermission(permission.id, currentUser);
180
+ }
181
+ // Revoke permissions on all child collections recursively
182
+ await this.revokeChildPermissions(collectionId, userId, currentUser);
183
+ }
184
+ /**
185
+ * Recursively revoke permissions on all child collections
186
+ */
187
+ async revokeChildPermissions(parentCollectionId, userId, currentUser) {
188
+ const rv = new RunView();
189
+ const childrenResult = await rv.RunView({
190
+ EntityName: 'MJ: Collections',
191
+ ExtraFilter: `ParentID='${parentCollectionId}'`,
192
+ ResultType: 'entity_object'
193
+ }, currentUser);
194
+ if (childrenResult.Success && childrenResult.Results) {
195
+ for (const child of childrenResult.Results) {
196
+ // Revoke permission if it exists for this user on the child collection
197
+ const childPermission = await this.checkPermission(child.ID, userId, currentUser);
198
+ if (childPermission) {
199
+ await this.revokePermission(childPermission.id, currentUser);
200
+ }
201
+ // Recursively revoke from grandchildren
202
+ await this.revokeChildPermissions(child.ID, userId, currentUser);
203
+ }
204
+ }
205
+ }
206
+ /**
207
+ * Validate that requested permissions don't exceed granter's permissions
208
+ */
209
+ validatePermissions(requested, granter, isOwner) {
210
+ if (isOwner)
211
+ return true; // Owner can grant anything
212
+ // Can't grant permissions you don't have
213
+ if (requested.canShare && !granter.canShare)
214
+ return false;
215
+ if (requested.canEdit && !granter.canEdit)
216
+ return false;
217
+ if (requested.canDelete && !granter.canDelete)
218
+ return false;
219
+ return true;
220
+ }
221
+ /**
222
+ * Get available permissions for a user to grant based on their own permissions
223
+ */
224
+ getAvailablePermissions(userPermissions, isOwner) {
225
+ if (isOwner) {
226
+ return ['Read', 'Share', 'Edit', 'Delete'];
227
+ }
228
+ const available = ['Read']; // Always have read
229
+ if (userPermissions.canShare)
230
+ available.push('Share');
231
+ if (userPermissions.canEdit)
232
+ available.push('Edit');
233
+ if (userPermissions.canDelete)
234
+ available.push('Delete');
235
+ return available;
236
+ }
237
+ /**
238
+ * Copy all permissions from parent collection to child collection
239
+ */
240
+ async copyParentPermissions(parentCollectionId, childCollectionId, currentUser) {
241
+ const parentPermissions = await this.loadPermissions(parentCollectionId, currentUser);
242
+ for (const perm of parentPermissions) {
243
+ // Check if permission already exists for this user on the child collection
244
+ const existing = await this.checkPermission(childCollectionId, perm.userId, currentUser);
245
+ if (existing) {
246
+ // Permission already exists (e.g., owner permission), skip to avoid duplicate
247
+ console.log(`Skipping duplicate permission for user ${perm.userId} on collection ${childCollectionId}`);
248
+ continue;
249
+ }
250
+ await this.grantPermission(childCollectionId, perm.userId, {
251
+ canRead: perm.canRead,
252
+ canShare: perm.canShare,
253
+ canEdit: perm.canEdit,
254
+ canDelete: perm.canDelete
255
+ }, perm.sharedByUserId || currentUser.ID, currentUser);
256
+ }
257
+ }
258
+ /**
259
+ * Delete all permissions for a collection
260
+ */
261
+ async deleteAllPermissions(collectionId, currentUser) {
262
+ const permissions = await this.loadPermissions(collectionId, currentUser);
263
+ for (const perm of permissions) {
264
+ await this.revokePermission(perm.id, currentUser);
265
+ }
266
+ }
267
+ /**
268
+ * Create owner permission record (all permissions enabled)
269
+ */
270
+ async createOwnerPermission(collectionId, ownerId, currentUser) {
271
+ await this.grantPermission(collectionId, ownerId, {
272
+ canRead: true,
273
+ canShare: true,
274
+ canEdit: true,
275
+ canDelete: true
276
+ }, ownerId, // Owner grants to themselves
277
+ currentUser);
278
+ }
279
+ mapToPermission(entity) {
280
+ return {
281
+ id: entity.ID,
282
+ collectionId: entity.CollectionID,
283
+ userId: entity.UserID,
284
+ userName: entity.User || '',
285
+ canRead: entity.CanRead,
286
+ canShare: entity.CanShare,
287
+ canEdit: entity.CanEdit,
288
+ canDelete: entity.CanDelete,
289
+ sharedByUserId: entity.SharedByUserID || null,
290
+ sharedByUserName: entity.SharedByUser || null,
291
+ sharedAt: entity.__mj_CreatedAt
292
+ };
293
+ }
294
+ static ɵfac = function CollectionPermissionService_Factory(t) { return new (t || CollectionPermissionService)(); };
295
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: CollectionPermissionService, factory: CollectionPermissionService.ɵfac, providedIn: 'root' });
296
+ }
297
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CollectionPermissionService, [{
298
+ type: Injectable,
299
+ args: [{
300
+ providedIn: 'root'
301
+ }]
302
+ }], null, null); })();
303
+ //# sourceMappingURL=collection-permission.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-permission.service.js","sourceRoot":"","sources":["../../../src/lib/services/collection-permission.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { Observable } from 'rxjs';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * State management service for collections
5
+ * Tracks active collection for deep linking support
6
+ */
7
+ export declare class CollectionStateService {
8
+ private _activeCollectionId$;
9
+ /**
10
+ * Observable of the active collection ID
11
+ */
12
+ readonly activeCollectionId$: Observable<string | null>;
13
+ /**
14
+ * Gets the currently active collection ID (synchronous)
15
+ */
16
+ get activeCollectionId(): string | null;
17
+ constructor();
18
+ /**
19
+ * Sets the active collection
20
+ * @param id The collection ID to activate (or null to clear)
21
+ */
22
+ setActiveCollection(id: string | null): void;
23
+ /**
24
+ * Clears the active collection
25
+ */
26
+ clearActiveCollection(): void;
27
+ /**
28
+ * Gets the currently active collection ID
29
+ */
30
+ getActiveCollectionId(): string | null;
31
+ static ɵfac: i0.ɵɵFactoryDeclaration<CollectionStateService, never>;
32
+ static ɵprov: i0.ɵɵInjectableDeclaration<CollectionStateService>;
33
+ }
34
+ //# sourceMappingURL=collection-state.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-state.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/collection-state.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;;AAEnD;;;GAGG;AACH,qBAGa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAA4C;IAExE;;OAEG;IACH,SAAgB,mBAAmB,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAA4C;IAE1G;;OAEG;IACH,IAAW,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAE7C;;IAID;;;OAGG;IACH,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK5C;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;OAEG;IACH,qBAAqB,IAAI,MAAM,GAAG,IAAI;yCApC3B,sBAAsB;6CAAtB,sBAAsB;CAuClC"}
@@ -0,0 +1,50 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * State management service for collections
6
+ * Tracks active collection for deep linking support
7
+ */
8
+ export class CollectionStateService {
9
+ _activeCollectionId$ = new BehaviorSubject(null);
10
+ /**
11
+ * Observable of the active collection ID
12
+ */
13
+ activeCollectionId$ = this._activeCollectionId$.asObservable();
14
+ /**
15
+ * Gets the currently active collection ID (synchronous)
16
+ */
17
+ get activeCollectionId() {
18
+ return this._activeCollectionId$.value;
19
+ }
20
+ constructor() { }
21
+ /**
22
+ * Sets the active collection
23
+ * @param id The collection ID to activate (or null to clear)
24
+ */
25
+ setActiveCollection(id) {
26
+ console.log('📁 Setting active collection:', id);
27
+ this._activeCollectionId$.next(id);
28
+ }
29
+ /**
30
+ * Clears the active collection
31
+ */
32
+ clearActiveCollection() {
33
+ this._activeCollectionId$.next(null);
34
+ }
35
+ /**
36
+ * Gets the currently active collection ID
37
+ */
38
+ getActiveCollectionId() {
39
+ return this._activeCollectionId$.value;
40
+ }
41
+ static ɵfac = function CollectionStateService_Factory(t) { return new (t || CollectionStateService)(); };
42
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: CollectionStateService, factory: CollectionStateService.ɵfac, providedIn: 'root' });
43
+ }
44
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CollectionStateService, [{
45
+ type: Injectable,
46
+ args: [{
47
+ providedIn: 'root'
48
+ }]
49
+ }], () => [], null); })();
50
+ //# sourceMappingURL=collection-state.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-state.service.js","sourceRoot":"","sources":["../../../src/lib/services/collection-state.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAc,MAAM,MAAM,CAAC;;AAEnD;;;GAGG;AAIH,MAAM,OAAO,sBAAsB;IACzB,oBAAoB,GAAG,IAAI,eAAe,CAAgB,IAAI,CAAC,CAAC;IAExE;;OAEG;IACa,mBAAmB,GAA8B,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;IAE1G;;OAEG;IACH,IAAW,kBAAkB;QAC3B,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IACzC,CAAC;IAED,gBAAe,CAAC;IAEhB;;;OAGG;IACH,mBAAmB,CAAC,EAAiB;QACnC,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IACzC,CAAC;gFAtCU,sBAAsB;gEAAtB,sBAAsB,WAAtB,sBAAsB,mBAFrB,MAAM;;iFAEP,sBAAsB;cAHlC,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB"}
@@ -24,10 +24,6 @@ export declare class ConversationAgentService {
24
24
  * Get or load the Sage Agent (formerly Conversation Manager Agent)
25
25
  */
26
26
  getConversationManagerAgent(): Promise<AIAgentEntityExtended | null>;
27
- /**
28
- * Get or create a session ID for a conversation
29
- */
30
- private getSessionId;
31
27
  /**
32
28
  * Process a message through the ambient Sage Agent.
33
29
  * This should be called for every message sent in a conversation.
@@ -85,6 +81,15 @@ export declare class ConversationAgentService {
85
81
  * Clear the session for a conversation (useful when starting a new topic)
86
82
  */
87
83
  clearSession(conversationId: string): void;
84
+ /**
85
+ * Filter agents based on user's 'run' permission.
86
+ * Only returns agents that the user has permission to run.
87
+ *
88
+ * @param agents List of candidate agents to filter
89
+ * @param user User to check permissions for
90
+ * @returns Filtered list of agents the user can run
91
+ */
92
+ private filterAgentsByPermissions;
88
93
  static ɵfac: i0.ɵɵFactoryDeclaration<ConversationAgentService, never>;
89
94
  static ɵprov: i0.ɵɵInjectableDeclaration<ConversationAgentService>;
90
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-agent.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/conversation-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AAInD,OAAO,EAAsB,kBAAkB,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAGtH,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAA2D,MAAM,+BAA+B,CAAC;;AAGzJ;;;GAGG;AACH,qBAGa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,cAAc,CAAuC;IAE7D;;OAEG;IACH,SAAgB,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;;IAMxF;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,2BAA2B,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IA8BjF;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;;;;;;;OAUG;IACG,cAAc,CAClB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,wBAAwB,EACjC,mBAAmB,EAAE,wBAAwB,EAAE,EAC/C,oBAAoB,EAAE,MAAM,EAC5B,UAAU,CAAC,EAAE,8BAA8B,GAC1C,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IA8DrC;;;;OAIG;YACW,kBAAkB;IAoFhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAMvB;;;;;;;;;;;;;OAaG;IACG,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,wBAAwB,EACjC,mBAAmB,EAAE,wBAAwB,EAAE,EAC/C,SAAS,EAAE,MAAM,EACjB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,GAAG,EACb,UAAU,CAAC,EAAE,8BAA8B,GAC1C,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAsDrC;;;;;;;;OAQG;IACG,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,mBAAmB,EAAE,wBAAwB,EAAE,GAC9C,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC;IA8EnC;;OAEG;IACH,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;yCAnb/B,wBAAwB;6CAAxB,wBAAwB;CAsbpC"}
1
+ {"version":3,"file":"conversation-agent.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/conversation-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AAInD,OAAO,EAAsB,kBAAkB,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAGtH,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAA2D,MAAM,+BAA+B,CAAC;;AAGzJ;;;GAGG;AACH,qBAGa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,cAAc,CAAuC;IAE7D;;OAEG;IACH,SAAgB,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;;IAMxF;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,2BAA2B,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IA+BjF;;;;;;;;;;OAUG;IACG,cAAc,CAClB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,wBAAwB,EACjC,mBAAmB,EAAE,wBAAwB,EAAE,EAC/C,oBAAoB,EAAE,MAAM,EAC5B,UAAU,CAAC,EAAE,8BAA8B,GAC1C,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAkFrC;;;;OAIG;YACW,kBAAkB;IAoFhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAMvB;;;;;;;;;;;;;OAaG;IACG,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,wBAAwB,EACjC,mBAAmB,EAAE,wBAAwB,EAAE,EAC/C,SAAS,EAAE,MAAM,EACjB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,GAAG,EACb,UAAU,CAAC,EAAE,8BAA8B,GAC1C,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAsDrC;;;;;;;;OAQG;IACG,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,mBAAmB,EAAE,wBAAwB,EAAE,GAC9C,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC;IA8EnC;;OAEG;IACH,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAI1C;;;;;;;OAOG;YACW,yBAAyB;yCAzc5B,wBAAwB;6CAAxB,wBAAwB;CAiepC"}
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
2
2
  import { BehaviorSubject } from 'rxjs';
3
3
  import { Metadata, RunView } from '@memberjunction/core';
4
4
  import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
5
- import { AIEngineBase } from '@memberjunction/ai-engine-base';
5
+ import { AIEngineBase, AIAgentPermissionHelper } from '@memberjunction/ai-engine-base';
6
6
  import { MJNotificationService } from '@memberjunction/ng-notifications';
7
7
  import * as i0 from "@angular/core";
8
8
  /**
@@ -65,16 +65,6 @@ export class ConversationAgentService {
65
65
  return null;
66
66
  }
67
67
  }
68
- /**
69
- * Get or create a session ID for a conversation
70
- */
71
- getSessionId(conversationId) {
72
- if (!this._sessionIds.has(conversationId)) {
73
- // Create a new session ID for this conversation
74
- this._sessionIds.set(conversationId, `conv-${conversationId}-${Date.now()}`);
75
- }
76
- return this._sessionIds.get(conversationId);
77
- }
78
68
  /**
79
69
  * Process a message through the ambient Sage Agent.
80
70
  * This should be called for every message sent in a conversation.
@@ -108,8 +98,23 @@ export class ConversationAgentService {
108
98
  // Build conversation messages for the agent
109
99
  // Note: conversationHistory already includes the current message
110
100
  const conversationMessages = await this.buildAgentMessages(conversationHistory);
101
+ // Get current user for permission filtering
102
+ const currentUser = Metadata.Provider.CurrentUser;
103
+ if (!currentUser) {
104
+ console.warn('⚠️ No current user available for permission filtering, using unfiltered agents');
105
+ }
106
+ // Filter agents by status and hierarchy first
107
+ const candidateAgents = AIEngineBase.Instance.Agents.filter(a => a.ID !== agent.ID &&
108
+ !a.ParentID &&
109
+ a.Status === 'Active' &&
110
+ a.InvocationMode !== 'Sub-Agent' // ensure that the agent is intended to run as top-level
111
+ );
112
+ // Filter by user permissions if user context available
113
+ const availAgents = currentUser
114
+ ? await this.filterAgentsByPermissions(candidateAgents, currentUser)
115
+ : candidateAgents;
116
+ console.log(`📋 Available agents for Sage: ${availAgents.length} (filtered from ${candidateAgents.length} candidates)`);
111
117
  // Prepare parameters using the correct ExecuteAgentParams type
112
- const availAgents = AIEngineBase.Instance.Agents.filter(a => a.ID !== agent.ID && !a.ParentID && a.Status === 'Active');
113
118
  const params = {
114
119
  agent: agent,
115
120
  conversationMessages: conversationMessages,
@@ -379,6 +384,30 @@ ${compactHistory}
379
384
  clearSession(conversationId) {
380
385
  this._sessionIds.delete(conversationId);
381
386
  }
387
+ /**
388
+ * Filter agents based on user's 'run' permission.
389
+ * Only returns agents that the user has permission to run.
390
+ *
391
+ * @param agents List of candidate agents to filter
392
+ * @param user User to check permissions for
393
+ * @returns Filtered list of agents the user can run
394
+ */
395
+ async filterAgentsByPermissions(agents, user) {
396
+ const permittedAgents = [];
397
+ for (const agent of agents) {
398
+ try {
399
+ const hasPermission = await AIAgentPermissionHelper.HasPermission(agent.ID, user, 'run');
400
+ if (hasPermission) {
401
+ permittedAgents.push(agent);
402
+ }
403
+ }
404
+ catch (error) {
405
+ console.error(`Error checking permission for agent ${agent.Name}:`, error);
406
+ // On error, exclude agent (fail closed)
407
+ }
408
+ }
409
+ return permittedAgents;
410
+ }
382
411
  static ɵfac = function ConversationAgentService_Factory(t) { return new (t || ConversationAgentService)(); };
383
412
  static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ConversationAgentService, factory: ConversationAgentService.ɵfac, providedIn: 'root' });
384
413
  }