@memberjunction/core-entities 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engines/FileStorageEngine.d.ts +71 -0
- package/dist/engines/FileStorageEngine.d.ts.map +1 -0
- package/dist/engines/FileStorageEngine.js +121 -0
- package/dist/engines/FileStorageEngine.js.map +1 -0
- package/dist/engines/UserInfoEngine.d.ts +18 -2
- package/dist/engines/UserInfoEngine.d.ts.map +1 -1
- package/dist/engines/UserInfoEngine.js +77 -43
- package/dist/engines/UserInfoEngine.js.map +1 -1
- package/dist/generated/entity_subclasses.d.ts +1077 -158
- package/dist/generated/entity_subclasses.d.ts.map +1 -1
- package/dist/generated/entity_subclasses.js +1539 -229
- package/dist/generated/entity_subclasses.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { BaseEngine, IMetadataProvider, UserInfo } from "@memberjunction/core";
|
|
2
|
+
import { FileStorageAccountEntity, FileStorageProviderEntity } from "../generated/entity_subclasses";
|
|
3
|
+
/**
|
|
4
|
+
* Represents a storage account with its associated provider details
|
|
5
|
+
*/
|
|
6
|
+
export interface StorageAccountWithProvider {
|
|
7
|
+
account: FileStorageAccountEntity;
|
|
8
|
+
provider: FileStorageProviderEntity;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* FileStorageEngine provides centralized, cached access to file storage accounts and providers.
|
|
12
|
+
* This engine eliminates redundant database calls by caching the data and making it available
|
|
13
|
+
* across the application.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const engine = FileStorageEngine.Instance;
|
|
18
|
+
* await engine.Config(false); // Use cached data if available
|
|
19
|
+
* const accounts = engine.AccountsWithProviders;
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class FileStorageEngine extends BaseEngine<FileStorageEngine> {
|
|
23
|
+
/**
|
|
24
|
+
* Returns the global instance of the class. This is a singleton class, so there is only
|
|
25
|
+
* one instance of it in the application. Do not directly create new instances of it,
|
|
26
|
+
* always use this method to get the instance.
|
|
27
|
+
*/
|
|
28
|
+
static get Instance(): FileStorageEngine;
|
|
29
|
+
private _accounts;
|
|
30
|
+
private _providers;
|
|
31
|
+
/**
|
|
32
|
+
* Configures the engine by loading file storage accounts and providers.
|
|
33
|
+
* @param forceRefresh - If true, forces a refresh from the database even if data is cached
|
|
34
|
+
* @param contextUser - Optional user context for server-side operations
|
|
35
|
+
* @param provider - Optional metadata provider
|
|
36
|
+
*/
|
|
37
|
+
Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Gets all file storage accounts
|
|
40
|
+
*/
|
|
41
|
+
get Accounts(): FileStorageAccountEntity[];
|
|
42
|
+
/**
|
|
43
|
+
* Gets all file storage providers.
|
|
44
|
+
* Consumers should filter by IsActive if needed.
|
|
45
|
+
*/
|
|
46
|
+
get Providers(): FileStorageProviderEntity[];
|
|
47
|
+
/**
|
|
48
|
+
* Gets all storage accounts combined with their provider details.
|
|
49
|
+
* Consumers should filter/sort as needed (e.g., by provider.IsActive).
|
|
50
|
+
*/
|
|
51
|
+
get AccountsWithProviders(): StorageAccountWithProvider[];
|
|
52
|
+
/**
|
|
53
|
+
* Gets a file storage account by its ID
|
|
54
|
+
* @param accountId - The ID of the account to find
|
|
55
|
+
* @returns The account entity or undefined if not found
|
|
56
|
+
*/
|
|
57
|
+
GetAccountById(accountId: string): FileStorageAccountEntity | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Gets a file storage provider by its ID
|
|
60
|
+
* @param providerId - The ID of the provider to find
|
|
61
|
+
* @returns The provider entity or undefined if not found
|
|
62
|
+
*/
|
|
63
|
+
GetProviderById(providerId: string): FileStorageProviderEntity | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Gets a storage account with its provider details by account ID
|
|
66
|
+
* @param accountId - The ID of the account to find
|
|
67
|
+
* @returns The account with provider or null if not found or provider is inactive
|
|
68
|
+
*/
|
|
69
|
+
GetAccountWithProvider(accountId: string): StorageAccountWithProvider | null;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=FileStorageEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileStorageEngine.d.ts","sourceRoot":"","sources":["../../src/engines/FileStorageEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzG,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAErG;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,wBAAwB,CAAC;IAClC,QAAQ,EAAE,yBAAyB,CAAC;CACvC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,iBAAiB,CAAC;IAChE;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,iBAAiB,CAE9C;IAED,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,UAAU,CAAmC;IAErD;;;;;OAKG;IACU,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhH;;OAEG;IACH,IAAW,QAAQ,IAAI,wBAAwB,EAAE,CAEhD;IAED;;;OAGG;IACH,IAAW,SAAS,IAAI,yBAAyB,EAAE,CAElD;IAED;;;OAGG;IACH,IAAW,qBAAqB,IAAI,0BAA0B,EAAE,CAW/D;IAMD;;;;OAIG;IACI,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,wBAAwB,GAAG,SAAS;IAI9E;;;;OAIG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS;IAIjF;;;;OAIG;IACI,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI;CAOtF"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileStorageEngine = void 0;
|
|
4
|
+
const core_1 = require("@memberjunction/core");
|
|
5
|
+
/**
|
|
6
|
+
* FileStorageEngine provides centralized, cached access to file storage accounts and providers.
|
|
7
|
+
* This engine eliminates redundant database calls by caching the data and making it available
|
|
8
|
+
* across the application.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const engine = FileStorageEngine.Instance;
|
|
13
|
+
* await engine.Config(false); // Use cached data if available
|
|
14
|
+
* const accounts = engine.AccountsWithProviders;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
class FileStorageEngine extends core_1.BaseEngine {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this._accounts = [];
|
|
21
|
+
this._providers = [];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the global instance of the class. This is a singleton class, so there is only
|
|
25
|
+
* one instance of it in the application. Do not directly create new instances of it,
|
|
26
|
+
* always use this method to get the instance.
|
|
27
|
+
*/
|
|
28
|
+
static get Instance() {
|
|
29
|
+
return super.getInstance();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Configures the engine by loading file storage accounts and providers.
|
|
33
|
+
* @param forceRefresh - If true, forces a refresh from the database even if data is cached
|
|
34
|
+
* @param contextUser - Optional user context for server-side operations
|
|
35
|
+
* @param provider - Optional metadata provider
|
|
36
|
+
*/
|
|
37
|
+
async Config(forceRefresh, contextUser, provider) {
|
|
38
|
+
const configs = [
|
|
39
|
+
{
|
|
40
|
+
Type: 'entity',
|
|
41
|
+
EntityName: 'MJ: File Storage Accounts',
|
|
42
|
+
PropertyName: '_accounts',
|
|
43
|
+
CacheLocal: true
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
Type: 'entity',
|
|
47
|
+
EntityName: 'File Storage Providers',
|
|
48
|
+
PropertyName: '_providers',
|
|
49
|
+
CacheLocal: true
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
await this.Load(configs, provider, forceRefresh, contextUser);
|
|
53
|
+
}
|
|
54
|
+
// ========================================
|
|
55
|
+
// Getters for cached data
|
|
56
|
+
// ========================================
|
|
57
|
+
/**
|
|
58
|
+
* Gets all file storage accounts
|
|
59
|
+
*/
|
|
60
|
+
get Accounts() {
|
|
61
|
+
return this._accounts || [];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets all file storage providers.
|
|
65
|
+
* Consumers should filter by IsActive if needed.
|
|
66
|
+
*/
|
|
67
|
+
get Providers() {
|
|
68
|
+
return this._providers || [];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Gets all storage accounts combined with their provider details.
|
|
72
|
+
* Consumers should filter/sort as needed (e.g., by provider.IsActive).
|
|
73
|
+
*/
|
|
74
|
+
get AccountsWithProviders() {
|
|
75
|
+
const providerMap = new Map();
|
|
76
|
+
this.Providers.forEach(p => providerMap.set(p.ID, p));
|
|
77
|
+
return this.Accounts
|
|
78
|
+
.map(account => {
|
|
79
|
+
const provider = providerMap.get(account.ProviderID);
|
|
80
|
+
if (!provider)
|
|
81
|
+
return null;
|
|
82
|
+
return { account, provider };
|
|
83
|
+
})
|
|
84
|
+
.filter((item) => item !== null);
|
|
85
|
+
}
|
|
86
|
+
// ========================================
|
|
87
|
+
// Lookup Methods
|
|
88
|
+
// ========================================
|
|
89
|
+
/**
|
|
90
|
+
* Gets a file storage account by its ID
|
|
91
|
+
* @param accountId - The ID of the account to find
|
|
92
|
+
* @returns The account entity or undefined if not found
|
|
93
|
+
*/
|
|
94
|
+
GetAccountById(accountId) {
|
|
95
|
+
return this.Accounts.find(a => a.ID === accountId);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets a file storage provider by its ID
|
|
99
|
+
* @param providerId - The ID of the provider to find
|
|
100
|
+
* @returns The provider entity or undefined if not found
|
|
101
|
+
*/
|
|
102
|
+
GetProviderById(providerId) {
|
|
103
|
+
return this.Providers.find(p => p.ID === providerId);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets a storage account with its provider details by account ID
|
|
107
|
+
* @param accountId - The ID of the account to find
|
|
108
|
+
* @returns The account with provider or null if not found or provider is inactive
|
|
109
|
+
*/
|
|
110
|
+
GetAccountWithProvider(accountId) {
|
|
111
|
+
const account = this.GetAccountById(accountId);
|
|
112
|
+
if (!account)
|
|
113
|
+
return null;
|
|
114
|
+
const provider = this.GetProviderById(account.ProviderID);
|
|
115
|
+
if (!provider)
|
|
116
|
+
return null;
|
|
117
|
+
return { account, provider };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.FileStorageEngine = FileStorageEngine;
|
|
121
|
+
//# sourceMappingURL=FileStorageEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileStorageEngine.js","sourceRoot":"","sources":["../../src/engines/FileStorageEngine.ts"],"names":[],"mappings":";;;AAAA,+CAAyG;AAWzG;;;;;;;;;;;GAWG;AACH,MAAa,iBAAkB,SAAQ,iBAA6B;IAApE;;QAUY,cAAS,GAA+B,EAAE,CAAC;QAC3C,eAAU,GAAgC,EAAE,CAAC;IAgGzD,CAAC;IA1GG;;;;OAIG;IACI,MAAM,KAAK,QAAQ;QACtB,OAAO,KAAK,CAAC,WAAW,EAAqB,CAAC;IAClD,CAAC;IAKD;;;;;OAKG;IACI,KAAK,CAAC,MAAM,CAAC,YAAsB,EAAE,WAAsB,EAAE,QAA4B;QAC5F,MAAM,OAAO,GAAwC;YACjD;gBACI,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,2BAA2B;gBACvC,YAAY,EAAE,WAAW;gBACzB,UAAU,EAAE,IAAI;aACnB;YACD;gBACI,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,wBAAwB;gBACpC,YAAY,EAAE,YAAY;gBAC1B,UAAU,EAAE,IAAI;aACnB;SACJ,CAAC;QACF,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAClE,CAAC;IAED,2CAA2C;IAC3C,0BAA0B;IAC1B,2CAA2C;IAE3C;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,IAAW,SAAS;QAChB,OAAO,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,IAAW,qBAAqB;QAC5B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAqC,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEtD,OAAO,IAAI,CAAC,QAAQ;aACf,GAAG,CAAC,OAAO,CAAC,EAAE;YACX,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC3B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QACjC,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,IAAI,EAAsC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,2CAA2C;IAC3C,iBAAiB;IACjB,2CAA2C;IAE3C;;;;OAIG;IACI,cAAc,CAAC,SAAiB;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACI,eAAe,CAAC,UAAkB;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACI,sBAAsB,CAAC,SAAiB;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;CACJ;AA3GD,8CA2GC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApplicationInfo, BaseEngine, IMetadataProvider, UserInfo } from
|
|
1
|
+
import { ApplicationInfo, BaseEngine, IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
2
2
|
/**
|
|
3
3
|
* Status indicating why a user can or cannot access an application.
|
|
4
4
|
* - 'installed_active': User has UserApplication record with IsActive=true
|
|
@@ -6,7 +6,7 @@ import { ApplicationInfo, BaseEngine, IMetadataProvider, UserInfo } from "@membe
|
|
|
6
6
|
* - 'not_installed': User has no UserApplication record for this app
|
|
7
7
|
*/
|
|
8
8
|
export type UserApplicationAccessStatus = 'installed_active' | 'installed_inactive' | 'not_installed';
|
|
9
|
-
import { UserNotificationEntity, WorkspaceEntity, UserApplicationEntity, UserFavoriteEntity, UserRecordLogEntity, UserSettingEntity } from
|
|
9
|
+
import { UserNotificationEntity, UserNotificationTypeEntity, WorkspaceEntity, UserApplicationEntity, UserFavoriteEntity, UserRecordLogEntity, UserSettingEntity, UserNotificationPreferenceEntity } from '../generated/entity_subclasses';
|
|
10
10
|
/**
|
|
11
11
|
* UserInfoEngine is a singleton engine that provides centralized access to user-specific data
|
|
12
12
|
* including notifications, workspaces, applications, favorites, and record logs.
|
|
@@ -40,6 +40,8 @@ export declare class UserInfoEngine extends BaseEngine<UserInfoEngine> {
|
|
|
40
40
|
private _UserFavorites;
|
|
41
41
|
private _UserRecordLogs;
|
|
42
42
|
private _UserSettings;
|
|
43
|
+
private _NotificationTypes;
|
|
44
|
+
private _UserNotificationPreferences;
|
|
43
45
|
private _loadedForUserId;
|
|
44
46
|
private _createDefaultAppsPromise;
|
|
45
47
|
/**
|
|
@@ -250,5 +252,19 @@ export declare class UserInfoEngine extends BaseEngine<UserInfoEngine> {
|
|
|
250
252
|
* Separated to allow the public method to manage the promise state.
|
|
251
253
|
*/
|
|
252
254
|
private doCreateDefaultApplications;
|
|
255
|
+
/**
|
|
256
|
+
* Get all notification preferences for the current user
|
|
257
|
+
*/
|
|
258
|
+
get NotificationPreferences(): UserNotificationPreferenceEntity[];
|
|
259
|
+
GetUserPreferenceForType(userId: string, typeId: string): UserNotificationPreferenceEntity | undefined;
|
|
260
|
+
/**
|
|
261
|
+
* Get current user's preference for a specific notification type
|
|
262
|
+
*/
|
|
263
|
+
GetCurrentUserPreferenceForType(typeId: string): UserNotificationPreferenceEntity | undefined;
|
|
264
|
+
/**
|
|
265
|
+
* Get all notification types.
|
|
266
|
+
* Notification types are global (not user-specific) and define the available notification categories.
|
|
267
|
+
*/
|
|
268
|
+
get NotificationTypes(): UserNotificationTypeEntity[];
|
|
253
269
|
}
|
|
254
270
|
//# sourceMappingURL=UserInfoEngine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserInfoEngine.d.ts","sourceRoot":"","sources":["../../src/engines/UserInfoEngine.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"UserInfoEngine.d.ts","sourceRoot":"","sources":["../../src/engines/UserInfoEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,10 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
39
39
|
this._UserFavorites = [];
|
|
40
40
|
this._UserRecordLogs = [];
|
|
41
41
|
this._UserSettings = [];
|
|
42
|
+
// Notification types (global - not user-specific)
|
|
43
|
+
this._NotificationTypes = [];
|
|
44
|
+
// User notification preferences (user-specific)
|
|
45
|
+
this._UserNotificationPreferences = [];
|
|
42
46
|
// Track the user ID we loaded data for
|
|
43
47
|
this._loadedForUserId = null;
|
|
44
48
|
// Track in-progress CreateDefaultApplications call to prevent duplicate execution
|
|
@@ -80,38 +84,50 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
80
84
|
Type: 'entity',
|
|
81
85
|
EntityName: 'User Notifications',
|
|
82
86
|
PropertyName: '_UserNotifications',
|
|
83
|
-
CacheLocal: true
|
|
87
|
+
CacheLocal: true,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
Type: 'entity',
|
|
91
|
+
EntityName: 'MJ: User Notification Types',
|
|
92
|
+
PropertyName: '_NotificationTypes',
|
|
93
|
+
CacheLocal: true,
|
|
84
94
|
},
|
|
85
95
|
{
|
|
86
96
|
Type: 'entity',
|
|
87
97
|
EntityName: 'Workspaces',
|
|
88
98
|
PropertyName: '_Workspaces',
|
|
89
|
-
CacheLocal: true
|
|
99
|
+
CacheLocal: true,
|
|
90
100
|
},
|
|
91
101
|
{
|
|
92
102
|
Type: 'entity',
|
|
93
103
|
EntityName: 'MJ: User Settings',
|
|
94
104
|
PropertyName: '_UserSettings',
|
|
95
|
-
CacheLocal: true
|
|
105
|
+
CacheLocal: true,
|
|
96
106
|
},
|
|
97
107
|
{
|
|
98
108
|
Type: 'entity',
|
|
99
109
|
EntityName: 'User Applications',
|
|
100
110
|
PropertyName: '_UserApplications',
|
|
101
|
-
CacheLocal: true
|
|
111
|
+
CacheLocal: true,
|
|
102
112
|
},
|
|
103
113
|
{
|
|
104
114
|
Type: 'entity',
|
|
105
115
|
EntityName: 'User Favorites',
|
|
106
116
|
PropertyName: '_UserFavorites',
|
|
107
|
-
CacheLocal: true
|
|
117
|
+
CacheLocal: true,
|
|
108
118
|
},
|
|
109
119
|
{
|
|
110
120
|
Type: 'entity',
|
|
111
121
|
EntityName: 'User Record Logs',
|
|
112
122
|
PropertyName: '_UserRecordLogs',
|
|
113
|
-
CacheLocal: true
|
|
114
|
-
}
|
|
123
|
+
CacheLocal: true,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
Type: 'entity',
|
|
127
|
+
EntityName: 'MJ: User Notification Preferences',
|
|
128
|
+
PropertyName: '_UserNotificationPreferences',
|
|
129
|
+
CacheLocal: true,
|
|
130
|
+
},
|
|
115
131
|
];
|
|
116
132
|
await super.Load(configs, provider, forceRefresh, contextUser);
|
|
117
133
|
this._loadedForUserId = userId;
|
|
@@ -126,7 +142,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
126
142
|
if (!this._loadedForUserId)
|
|
127
143
|
return [];
|
|
128
144
|
return (this._UserNotifications || [])
|
|
129
|
-
.filter(n => n.UserID === this._loadedForUserId)
|
|
145
|
+
.filter((n) => n.UserID === this._loadedForUserId)
|
|
130
146
|
.sort((a, b) => new Date(b.Get('__mj_CreatedAt')).getTime() - new Date(a.Get('__mj_CreatedAt')).getTime());
|
|
131
147
|
}
|
|
132
148
|
/**
|
|
@@ -135,7 +151,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
135
151
|
get UserSettings() {
|
|
136
152
|
if (!this._loadedForUserId)
|
|
137
153
|
return [];
|
|
138
|
-
return (this._UserSettings || []).filter(s => s.UserID === this._loadedForUserId);
|
|
154
|
+
return (this._UserSettings || []).filter((s) => s.UserID === this._loadedForUserId);
|
|
139
155
|
}
|
|
140
156
|
/**
|
|
141
157
|
* Get a user setting value by key.
|
|
@@ -143,7 +159,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
143
159
|
* @returns The setting value string, or undefined if not found
|
|
144
160
|
*/
|
|
145
161
|
GetSetting(settingKey) {
|
|
146
|
-
const setting = this.UserSettings.find(s => s.Setting === settingKey);
|
|
162
|
+
const setting = this.UserSettings.find((s) => s.Setting === settingKey);
|
|
147
163
|
return setting?.Value ?? undefined;
|
|
148
164
|
}
|
|
149
165
|
/**
|
|
@@ -152,7 +168,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
152
168
|
* @returns The UserSettingEntity, or undefined if not found
|
|
153
169
|
*/
|
|
154
170
|
GetSettingEntity(settingKey) {
|
|
155
|
-
return this.UserSettings.find(s => s.Setting === settingKey);
|
|
171
|
+
return this.UserSettings.find((s) => s.Setting === settingKey);
|
|
156
172
|
}
|
|
157
173
|
/**
|
|
158
174
|
* Set a user setting by key. Creates a new setting if it doesn't exist.
|
|
@@ -186,7 +202,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
186
202
|
const saved = await setting.Save();
|
|
187
203
|
if (saved) {
|
|
188
204
|
// If it was a new record, add to cache
|
|
189
|
-
if (!this._UserSettings.some(s => s.ID === setting.ID)) {
|
|
205
|
+
if (!this._UserSettings.some((s) => s.ID === setting.ID)) {
|
|
190
206
|
this._UserSettings.push(setting);
|
|
191
207
|
}
|
|
192
208
|
return true;
|
|
@@ -216,7 +232,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
216
232
|
const deleted = await setting.Delete();
|
|
217
233
|
if (deleted) {
|
|
218
234
|
// Remove from cache
|
|
219
|
-
const index = this._UserSettings.findIndex(s => s.ID === setting.ID);
|
|
235
|
+
const index = this._UserSettings.findIndex((s) => s.ID === setting.ID);
|
|
220
236
|
if (index >= 0) {
|
|
221
237
|
this._UserSettings.splice(index, 1);
|
|
222
238
|
}
|
|
@@ -236,7 +252,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
236
252
|
* Get unread notifications for the current user
|
|
237
253
|
*/
|
|
238
254
|
get UnreadNotifications() {
|
|
239
|
-
return this.UserNotifications.filter(n => n.Unread);
|
|
255
|
+
return this.UserNotifications.filter((n) => n.Unread);
|
|
240
256
|
}
|
|
241
257
|
/**
|
|
242
258
|
* Get the count of unread notifications
|
|
@@ -250,7 +266,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
250
266
|
get Workspaces() {
|
|
251
267
|
if (!this._loadedForUserId)
|
|
252
268
|
return [];
|
|
253
|
-
return (this._Workspaces || []).filter(w => w.UserID === this._loadedForUserId);
|
|
269
|
+
return (this._Workspaces || []).filter((w) => w.UserID === this._loadedForUserId);
|
|
254
270
|
}
|
|
255
271
|
/**
|
|
256
272
|
* Get the current user's primary workspace (first one if multiple exist)
|
|
@@ -266,7 +282,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
266
282
|
if (!this._loadedForUserId)
|
|
267
283
|
return [];
|
|
268
284
|
return (this._UserApplications || [])
|
|
269
|
-
.filter(ua => ua.UserID === this._loadedForUserId)
|
|
285
|
+
.filter((ua) => ua.UserID === this._loadedForUserId)
|
|
270
286
|
.sort((a, b) => {
|
|
271
287
|
// Sort by Sequence first, then by Application name
|
|
272
288
|
if (a.Sequence !== b.Sequence) {
|
|
@@ -282,7 +298,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
282
298
|
if (!this._loadedForUserId)
|
|
283
299
|
return [];
|
|
284
300
|
return (this._UserFavorites || [])
|
|
285
|
-
.filter(f => f.UserID === this._loadedForUserId)
|
|
301
|
+
.filter((f) => f.UserID === this._loadedForUserId)
|
|
286
302
|
.sort((a, b) => new Date(b.Get('__mj_CreatedAt')).getTime() - new Date(a.Get('__mj_CreatedAt')).getTime());
|
|
287
303
|
}
|
|
288
304
|
/**
|
|
@@ -292,7 +308,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
292
308
|
if (!this._loadedForUserId)
|
|
293
309
|
return [];
|
|
294
310
|
return (this._UserRecordLogs || [])
|
|
295
|
-
.filter(r => r.UserID === this._loadedForUserId)
|
|
311
|
+
.filter((r) => r.UserID === this._loadedForUserId)
|
|
296
312
|
.sort((a, b) => new Date(b.LatestAt).getTime() - new Date(a.LatestAt).getTime());
|
|
297
313
|
}
|
|
298
314
|
// ========================================================================
|
|
@@ -318,7 +334,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
318
334
|
*/
|
|
319
335
|
GetNotificationsForUser(userId) {
|
|
320
336
|
return (this._UserNotifications || [])
|
|
321
|
-
.filter(n => n.UserID === userId)
|
|
337
|
+
.filter((n) => n.UserID === userId)
|
|
322
338
|
.sort((a, b) => new Date(b.Get('__mj_CreatedAt')).getTime() - new Date(a.Get('__mj_CreatedAt')).getTime());
|
|
323
339
|
}
|
|
324
340
|
/**
|
|
@@ -327,7 +343,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
327
343
|
*/
|
|
328
344
|
GetUserApplicationsForUser(userId) {
|
|
329
345
|
return (this._UserApplications || [])
|
|
330
|
-
.filter(ua => ua.UserID === userId)
|
|
346
|
+
.filter((ua) => ua.UserID === userId)
|
|
331
347
|
.sort((a, b) => {
|
|
332
348
|
if (a.Sequence !== b.Sequence) {
|
|
333
349
|
return a.Sequence - b.Sequence;
|
|
@@ -343,21 +359,21 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
343
359
|
* @param notificationId - The notification ID to find
|
|
344
360
|
*/
|
|
345
361
|
GetNotificationById(notificationId) {
|
|
346
|
-
return this.UserNotifications.find(n => n.ID === notificationId);
|
|
362
|
+
return this.UserNotifications.find((n) => n.ID === notificationId);
|
|
347
363
|
}
|
|
348
364
|
/**
|
|
349
365
|
* Get a user application by application ID
|
|
350
366
|
* @param applicationId - The application ID to find
|
|
351
367
|
*/
|
|
352
368
|
GetUserApplicationByAppId(applicationId) {
|
|
353
|
-
return this.UserApplications.find(ua => ua.ApplicationID === applicationId);
|
|
369
|
+
return this.UserApplications.find((ua) => ua.ApplicationID === applicationId);
|
|
354
370
|
}
|
|
355
371
|
/**
|
|
356
372
|
* Get favorites for a specific entity
|
|
357
373
|
* @param entityId - The entity ID to filter by
|
|
358
374
|
*/
|
|
359
375
|
GetFavoritesForEntity(entityId) {
|
|
360
|
-
return this.UserFavorites.filter(f => f.EntityID === entityId);
|
|
376
|
+
return this.UserFavorites.filter((f) => f.EntityID === entityId);
|
|
361
377
|
}
|
|
362
378
|
/**
|
|
363
379
|
* Get recent record logs for a specific entity
|
|
@@ -365,9 +381,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
365
381
|
* @param maxItems - Maximum number of items to return (default: 10)
|
|
366
382
|
*/
|
|
367
383
|
GetRecentRecordsForEntity(entityId, maxItems = 10) {
|
|
368
|
-
return this.UserRecordLogs
|
|
369
|
-
.filter(r => r.EntityID === entityId)
|
|
370
|
-
.slice(0, maxItems);
|
|
384
|
+
return this.UserRecordLogs.filter((r) => r.EntityID === entityId).slice(0, maxItems);
|
|
371
385
|
}
|
|
372
386
|
/**
|
|
373
387
|
* Check if a record is in the user's favorites
|
|
@@ -375,7 +389,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
375
389
|
* @param recordId - The record ID
|
|
376
390
|
*/
|
|
377
391
|
IsRecordFavorite(entityId, recordId) {
|
|
378
|
-
return this.UserFavorites.some(f => f.EntityID === entityId && f.RecordID === recordId);
|
|
392
|
+
return this.UserFavorites.some((f) => f.EntityID === entityId && f.RecordID === recordId);
|
|
379
393
|
}
|
|
380
394
|
/**
|
|
381
395
|
* Get the user ID this engine was loaded for
|
|
@@ -404,7 +418,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
404
418
|
*/
|
|
405
419
|
IsApplicationInactive(applicationId) {
|
|
406
420
|
const md = new core_1.Metadata();
|
|
407
|
-
const appInfo = md.Applications.find(a => a.ID === applicationId);
|
|
421
|
+
const appInfo = md.Applications.find((a) => a.ID === applicationId);
|
|
408
422
|
return appInfo != null && appInfo.Status !== 'Active';
|
|
409
423
|
}
|
|
410
424
|
/**
|
|
@@ -413,7 +427,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
413
427
|
*/
|
|
414
428
|
GetApplicationInfo(applicationId) {
|
|
415
429
|
const md = new core_1.Metadata();
|
|
416
|
-
return md.Applications.find(a => a.ID === applicationId);
|
|
430
|
+
return md.Applications.find((a) => a.ID === applicationId);
|
|
417
431
|
}
|
|
418
432
|
/**
|
|
419
433
|
* Find application info by path or name (case-insensitive).
|
|
@@ -423,12 +437,12 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
423
437
|
const normalized = pathOrName.trim().toLowerCase();
|
|
424
438
|
const md = new core_1.Metadata();
|
|
425
439
|
// First try path match
|
|
426
|
-
const pathMatch = md.Applications.find(a => a.Path?.toLowerCase() === normalized);
|
|
440
|
+
const pathMatch = md.Applications.find((a) => a.Path?.toLowerCase() === normalized);
|
|
427
441
|
if (pathMatch) {
|
|
428
442
|
return pathMatch;
|
|
429
443
|
}
|
|
430
444
|
// Fallback to name match
|
|
431
|
-
return md.Applications.find(a => a.Name.trim().toLowerCase() === normalized);
|
|
445
|
+
return md.Applications.find((a) => a.Name.trim().toLowerCase() === normalized);
|
|
432
446
|
}
|
|
433
447
|
/**
|
|
434
448
|
* Force refresh all user data
|
|
@@ -444,14 +458,14 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
444
458
|
* Get only the active user applications (IsActive = true)
|
|
445
459
|
*/
|
|
446
460
|
get ActiveUserApplications() {
|
|
447
|
-
return this.UserApplications.filter(ua => ua.IsActive);
|
|
461
|
+
return this.UserApplications.filter((ua) => ua.IsActive);
|
|
448
462
|
}
|
|
449
463
|
/**
|
|
450
464
|
* Check if user has a specific application installed (has UserApplication record)
|
|
451
465
|
* @param applicationId - The application ID to check
|
|
452
466
|
*/
|
|
453
467
|
HasApplication(applicationId) {
|
|
454
|
-
return this.UserApplications.some(ua => ua.ApplicationID === applicationId);
|
|
468
|
+
return this.UserApplications.some((ua) => ua.ApplicationID === applicationId);
|
|
455
469
|
}
|
|
456
470
|
/**
|
|
457
471
|
* Check if user has a specific application active (installed AND IsActive = true)
|
|
@@ -589,7 +603,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
589
603
|
const deleted = await userApp.Delete();
|
|
590
604
|
if (deleted) {
|
|
591
605
|
// Remove from cached array
|
|
592
|
-
const index = this._UserApplications.findIndex(ua => ua.ApplicationID === applicationId);
|
|
606
|
+
const index = this._UserApplications.findIndex((ua) => ua.ApplicationID === applicationId);
|
|
593
607
|
if (index >= 0) {
|
|
594
608
|
this._UserApplications.splice(index, 1);
|
|
595
609
|
}
|
|
@@ -644,14 +658,10 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
644
658
|
return [];
|
|
645
659
|
}
|
|
646
660
|
// Get existing UserApplication records for this user to prevent duplicates
|
|
647
|
-
const existingAppIds = new Set(this._UserApplications
|
|
648
|
-
.filter(ua => ua.UserID === userId)
|
|
649
|
-
.map(ua => ua.ApplicationID));
|
|
661
|
+
const existingAppIds = new Set(this._UserApplications.filter((ua) => ua.UserID === userId).map((ua) => ua.ApplicationID));
|
|
650
662
|
// Filter to Active apps with DefaultForNewUser=true, sorted by DefaultSequence
|
|
651
663
|
// Exclude apps that already have UserApplication records
|
|
652
|
-
const defaultApps = md.Applications
|
|
653
|
-
.filter(a => a.DefaultForNewUser && a.Status === 'Active' && !existingAppIds.has(a.ID))
|
|
654
|
-
.sort((a, b) => (a.DefaultSequence ?? 100) - (b.DefaultSequence ?? 100));
|
|
664
|
+
const defaultApps = md.Applications.filter((a) => a.DefaultForNewUser && a.Status === 'Active' && !existingAppIds.has(a.ID)).sort((a, b) => (a.DefaultSequence ?? 100) - (b.DefaultSequence ?? 100));
|
|
655
665
|
if (defaultApps.length === 0) {
|
|
656
666
|
console.log('UserInfoEngine.CreateDefaultApplications: No new apps to install (all defaults already exist)');
|
|
657
667
|
return [];
|
|
@@ -659,9 +669,7 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
659
669
|
console.log(`UserInfoEngine.CreateDefaultApplications: Found ${defaultApps.length} default apps to install`);
|
|
660
670
|
const createdUserApps = [];
|
|
661
671
|
// Calculate starting sequence based on existing apps
|
|
662
|
-
const maxExistingSequence = this._UserApplications
|
|
663
|
-
.filter(ua => ua.UserID === userId)
|
|
664
|
-
.reduce((max, ua) => Math.max(max, ua.Sequence), -1);
|
|
672
|
+
const maxExistingSequence = this._UserApplications.filter((ua) => ua.UserID === userId).reduce((max, ua) => Math.max(max, ua.Sequence), -1);
|
|
665
673
|
for (const [index, appInfo] of defaultApps.entries()) {
|
|
666
674
|
try {
|
|
667
675
|
const userApp = await md.GetEntityObject('User Applications', contextUser);
|
|
@@ -686,6 +694,32 @@ let UserInfoEngine = class UserInfoEngine extends core_1.BaseEngine {
|
|
|
686
694
|
}
|
|
687
695
|
return createdUserApps;
|
|
688
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Get all notification preferences for the current user
|
|
699
|
+
*/
|
|
700
|
+
get NotificationPreferences() {
|
|
701
|
+
if (!this._loadedForUserId)
|
|
702
|
+
return [];
|
|
703
|
+
return (this._UserNotificationPreferences || []).filter((p) => p.UserID === this._loadedForUserId);
|
|
704
|
+
}
|
|
705
|
+
GetUserPreferenceForType(userId, typeId) {
|
|
706
|
+
return (this._UserNotificationPreferences || []).find((p) => p.UserID === userId && p.NotificationTypeID === typeId);
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Get current user's preference for a specific notification type
|
|
710
|
+
*/
|
|
711
|
+
GetCurrentUserPreferenceForType(typeId) {
|
|
712
|
+
if (!this._loadedForUserId)
|
|
713
|
+
return undefined;
|
|
714
|
+
return this.GetUserPreferenceForType(this._loadedForUserId, typeId);
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Get all notification types.
|
|
718
|
+
* Notification types are global (not user-specific) and define the available notification categories.
|
|
719
|
+
*/
|
|
720
|
+
get NotificationTypes() {
|
|
721
|
+
return this._NotificationTypes || [];
|
|
722
|
+
}
|
|
689
723
|
};
|
|
690
724
|
exports.UserInfoEngine = UserInfoEngine;
|
|
691
725
|
exports.UserInfoEngine = UserInfoEngine = __decorate([
|