@limetech/lime-web-components 6.4.1 → 6.6.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/CHANGELOG.md +21 -0
- package/dist/action/action.d.ts +305 -13
- package/dist/action/action.d.ts.map +1 -1
- package/dist/application/decorators/application.d.ts +57 -3
- package/dist/application/decorators/application.d.ts.map +1 -1
- package/dist/application/decorators/session.d.ts +44 -3
- package/dist/application/decorators/session.d.ts.map +1 -1
- package/dist/application/decorators/user.d.ts +47 -3
- package/dist/application/decorators/user.d.ts.map +1 -1
- package/dist/application/repository.d.ts +102 -5
- package/dist/application/repository.d.ts.map +1 -1
- package/dist/application/session.d.ts +105 -15
- package/dist/application/session.d.ts.map +1 -1
- package/dist/application/user.d.ts +122 -13
- package/dist/application/user.d.ts.map +1 -1
- package/dist/commandbus/commandbus.d.ts +364 -23
- package/dist/commandbus/commandbus.d.ts.map +1 -1
- package/dist/conditionregistry/conditionregistry.d.ts +310 -27
- package/dist/conditionregistry/conditionregistry.d.ts.map +1 -1
- package/dist/config/decorator.d.ts +50 -3
- package/dist/config/decorator.d.ts.map +1 -1
- package/dist/config/repository.d.ts +131 -10
- package/dist/config/repository.d.ts.map +1 -1
- package/dist/core/context.d.ts +94 -4
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/lime-web-component.d.ts +59 -3
- package/dist/core/lime-web-component.d.ts.map +1 -1
- package/dist/core/metadata.d.ts +113 -13
- package/dist/core/metadata.d.ts.map +1 -1
- package/dist/core/platform.d.ts +175 -14
- package/dist/core/platform.d.ts.map +1 -1
- package/dist/core/state.d.ts +138 -14
- package/dist/core/state.d.ts.map +1 -1
- package/dist/datetimeformatter/datetimeformatter.d.ts +97 -34
- package/dist/datetimeformatter/datetimeformatter.d.ts.map +1 -1
- package/dist/device/decorator.d.ts +56 -4
- package/dist/device/decorator.d.ts.map +1 -1
- package/dist/device/device.d.ts +51 -6
- package/dist/device/device.d.ts.map +1 -1
- package/dist/dialog/dialog.d.ts +155 -19
- package/dist/dialog/dialog.d.ts.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +109 -101
- package/dist/index.esm.js.map +1 -1
- package/dist/limeobject/file.d.ts +6 -0
- package/dist/limeobject/file.d.ts.map +1 -1
- package/dist/logger/index.d.ts +3 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/logger.d.ts +385 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/types.d.ts +15 -0
- package/dist/logger/types.d.ts.map +1 -0
- package/package.json +13 -13
- package/dist/index.cjs.js +0 -4
- package/dist/index.cjs.js.map +0 -1
|
@@ -1,30 +1,160 @@
|
|
|
1
1
|
import { Action } from '../action';
|
|
2
2
|
import { LimeObject } from '../limeobject';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Represents a conditional evaluation rule that can be registered and used
|
|
5
|
+
* throughout the application.
|
|
6
|
+
*
|
|
7
|
+
* Conditions are predicate functions that determine whether certain UI elements should be
|
|
8
|
+
* visible, enabled, or available based on runtime state. For example, they can be used to:
|
|
9
|
+
* - Control action visibility (show/hide menu items based on object state)
|
|
10
|
+
* - Enable/disable features based on user permissions or context
|
|
11
|
+
* - Filter lists of items based on dynamic criteria
|
|
12
|
+
* - Implement business rules for conditional UI rendering
|
|
13
|
+
*
|
|
14
|
+
* Each condition has a unique ID and a type that indicates what kind of subject it evaluates.
|
|
15
|
+
* The most common types are 'limeobject' and 'action', but custom types can be defined.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* Registering a simple LimeObject condition
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const registry = platform.get(PlatformServiceName.ConditionRegistry);
|
|
21
|
+
*
|
|
22
|
+
* const isDealWon = {
|
|
23
|
+
* id: 'deal.is-won',
|
|
24
|
+
* type: 'limeobject',
|
|
25
|
+
* evaluate: (deal) => deal.dealstatus === 'won'
|
|
26
|
+
* };
|
|
27
|
+
*
|
|
28
|
+
* registry.addCondition(isDealWon);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* Condition with additional parameters
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const hasMinimumValue = {
|
|
35
|
+
* id: 'object.min-value',
|
|
36
|
+
* type: 'limeobject',
|
|
37
|
+
* evaluate: (object, params) => {
|
|
38
|
+
* const { field, minValue } = params;
|
|
39
|
+
* const value = object[field];
|
|
40
|
+
* return typeof value === 'number' && value >= minValue;
|
|
41
|
+
* }
|
|
42
|
+
* };
|
|
43
|
+
*
|
|
44
|
+
* const isHighValue = hasMinimumValue.evaluate(dealObject, {
|
|
45
|
+
* field: 'value',
|
|
46
|
+
* minValue: 100000
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @see {@link ConditionRegistry} for managing conditions
|
|
51
|
+
* @see {@link LimeObjectCondition} for LimeObject-specific conditions
|
|
52
|
+
* @see {@link ActionCondition} for action-specific conditions
|
|
5
53
|
*
|
|
6
54
|
* @beta
|
|
7
55
|
* @group Conditions
|
|
8
56
|
*/
|
|
9
57
|
export type Condition<T = unknown> = {
|
|
10
58
|
/**
|
|
11
|
-
* The
|
|
59
|
+
* The type of subject this condition evaluates.
|
|
60
|
+
*
|
|
61
|
+
* Common types include:
|
|
62
|
+
* - `limeobject` - Evaluates {@link LimeObject} instances
|
|
63
|
+
* - `action` - Evaluates {@link Action} instances
|
|
64
|
+
*
|
|
65
|
+
* Custom types can be defined for specialized evaluation contexts.
|
|
12
66
|
*/
|
|
13
67
|
type: string;
|
|
14
68
|
/**
|
|
15
|
-
* The evaluation function
|
|
69
|
+
* The evaluation function that determines if the condition is met.
|
|
70
|
+
*
|
|
71
|
+
* This predicate function receives the subject to evaluate and optional parameters
|
|
72
|
+
* for configuration. It should return `true` if the condition is satisfied,
|
|
73
|
+
* `false` otherwise.
|
|
74
|
+
*
|
|
75
|
+
* The function should be pure and side-effect free when possible, as it may be
|
|
76
|
+
* called frequently during UI rendering and updates.
|
|
77
|
+
*
|
|
78
|
+
* @param subject - The value to evaluate. Type depends on the condition type.
|
|
79
|
+
* For 'limeobject' conditions, this is a {@link LimeObject}.
|
|
80
|
+
* For 'action' conditions, this is an {@link Action}.
|
|
81
|
+
* @param params - Optional configuration data for the evaluation.
|
|
82
|
+
* Can be used to pass context-specific values like field names, thresholds,
|
|
83
|
+
* or other criteria. The evaluation function should validate params if used.
|
|
84
|
+
* @returns `true` if the condition is met, `false` otherwise.
|
|
85
|
+
* @throws May throw an error if params has an unexpected type or required data is missing.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* Simple boolean check
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const evaluate = (deal: LimeObject) => deal.dealstatus === 'won';
|
|
91
|
+
* ```
|
|
16
92
|
*
|
|
17
|
-
* @
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
93
|
+
* @example
|
|
94
|
+
* Using params for configuration
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const evaluate = (obj: LimeObject, params?: { propertyName: string }) => {
|
|
97
|
+
* return obj.getValue(params.propertyName) !== null;
|
|
98
|
+
* };
|
|
99
|
+
* ```
|
|
22
100
|
*/
|
|
23
101
|
evaluate: (subject: T, params?: unknown) => boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Unique identifier for this condition.
|
|
104
|
+
*
|
|
105
|
+
* The ID is used to reference the condition when registering, removing, or
|
|
106
|
+
* looking it up from the {@link ConditionRegistry}. It must be unique across
|
|
107
|
+
* all registered conditions.
|
|
108
|
+
*/
|
|
24
109
|
id: string;
|
|
25
110
|
};
|
|
26
111
|
/**
|
|
27
|
-
* A condition
|
|
112
|
+
* A specialized condition type for evaluating {@link LimeObject} instances.
|
|
113
|
+
*
|
|
114
|
+
* LimeObject conditions are the most common type of condition, used to control
|
|
115
|
+
* UI elements based on the state of business objects (deals, contacts, companies, etc.).
|
|
116
|
+
* The evaluate function receives a LimeObject and can check any of its properties
|
|
117
|
+
* to determine if the condition is met.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* Condition based on object status
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const registry = platform.get(PlatformServiceName.ConditionRegistry);
|
|
123
|
+
*
|
|
124
|
+
* const isDealActive = {
|
|
125
|
+
* id: 'deal.is-active',
|
|
126
|
+
* type: 'limeobject',
|
|
127
|
+
* evaluate: (deal) => {
|
|
128
|
+
* return deal.dealstatus === 'qualification' ||
|
|
129
|
+
* deal.dealstatus === 'proposal';
|
|
130
|
+
* }
|
|
131
|
+
* };
|
|
132
|
+
*
|
|
133
|
+
* registry.addCondition(isDealActive);
|
|
134
|
+
*
|
|
135
|
+
* const condition = registry.getCondition('deal.is-active');
|
|
136
|
+
* const isActive = condition.evaluate(deal);
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* Condition for conditional action visibility
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const canSendEmail = {
|
|
143
|
+
* id: 'contact.can-send-email',
|
|
144
|
+
* type: 'limeobject',
|
|
145
|
+
* evaluate: (contact) => contact.email && contact.email.length > 0
|
|
146
|
+
* };
|
|
147
|
+
*
|
|
148
|
+
* const sendEmailAction = {
|
|
149
|
+
* label: 'Send Email',
|
|
150
|
+
* icon: 'envelope',
|
|
151
|
+
* command: { name: 'send-email' },
|
|
152
|
+
* condition: canSendEmail
|
|
153
|
+
* };
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* @see {@link Condition} for the base condition type
|
|
157
|
+
* @see {@link LimeObject} for the object structure
|
|
28
158
|
*
|
|
29
159
|
* @beta
|
|
30
160
|
* @group Conditions
|
|
@@ -33,7 +163,29 @@ export type LimeObjectCondition = Condition<LimeObject> & {
|
|
|
33
163
|
type: 'limeobject';
|
|
34
164
|
};
|
|
35
165
|
/**
|
|
36
|
-
* A condition
|
|
166
|
+
* A specialized condition type for evaluating {@link Action} instances.
|
|
167
|
+
*
|
|
168
|
+
* Action conditions are used to control the availability or visibility of actions
|
|
169
|
+
* themselves, based on properties of the action. This is less common than {@link LimeObject}
|
|
170
|
+
* conditions but useful for creating dynamic action menus that filter or organize
|
|
171
|
+
* actions based on their metadata.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* Condition to filter bulk actions
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const registry = platform.get(PlatformServiceName.ConditionRegistry);
|
|
177
|
+
*
|
|
178
|
+
* const isBulkAction = {
|
|
179
|
+
* id: 'action.is-bulk',
|
|
180
|
+
* type: 'action',
|
|
181
|
+
* evaluate: (action) => action.command.name.startsWith('bulk-')
|
|
182
|
+
* };
|
|
183
|
+
*
|
|
184
|
+
* registry.addCondition(isBulkAction);
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @see {@link Condition} for the base condition type
|
|
188
|
+
* @see {@link Action} for the action structure
|
|
37
189
|
*
|
|
38
190
|
* @beta
|
|
39
191
|
* @group Conditions
|
|
@@ -42,7 +194,7 @@ export type ActionCondition = Condition<Action> & {
|
|
|
42
194
|
type: 'action';
|
|
43
195
|
};
|
|
44
196
|
/**
|
|
45
|
-
* Check if condition expects a
|
|
197
|
+
* Check if condition expects a {@link LimeObject} to be passed when it is evaluated
|
|
46
198
|
*
|
|
47
199
|
* @param condition - the condition to check
|
|
48
200
|
* @returns true if the condition is a condition for a {@link LimeObject},
|
|
@@ -64,45 +216,176 @@ export declare function isLimeObjectCondition(condition: Condition): condition i
|
|
|
64
216
|
*/
|
|
65
217
|
export declare function isActionCondition(condition: Condition): condition is Condition<Action>;
|
|
66
218
|
/**
|
|
67
|
-
*
|
|
219
|
+
* Central registry for managing conditional evaluation rules across the application.
|
|
220
|
+
*
|
|
221
|
+
* The ConditionRegistry acts as a global repository for {@link Condition} instances,
|
|
222
|
+
* allowing different parts of the application to register, retrieve, and evaluate
|
|
223
|
+
* conditions. This is particularly useful for:
|
|
224
|
+
* - Controlling action visibility based on object state
|
|
225
|
+
* - Implementing permission-based UI rendering
|
|
226
|
+
* - Creating dynamic, context-aware interfaces
|
|
227
|
+
* - Sharing reusable business logic across components
|
|
228
|
+
*
|
|
229
|
+
* Components typically access the registry via the platform service and register
|
|
230
|
+
* their conditions when the application initializes. Conditions can be
|
|
231
|
+
* added and removed dynamically, allowing for flexible runtime configuration.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* Registering and using conditions in a component
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const registry = platform.get(PlatformServiceName.ConditionRegistry);
|
|
237
|
+
*
|
|
238
|
+
* const canWinDeal = {
|
|
239
|
+
* id: 'deal.can-win',
|
|
240
|
+
* type: 'limeobject',
|
|
241
|
+
* evaluate: (deal) => deal.dealstatus === 'proposal' && deal.value > 0
|
|
242
|
+
* };
|
|
243
|
+
*
|
|
244
|
+
* const canLoseDeal = {
|
|
245
|
+
* id: 'deal.can-lose',
|
|
246
|
+
* type: 'limeobject',
|
|
247
|
+
* evaluate: (deal) => deal.dealstatus !== 'lost' && deal.dealstatus !== 'won'
|
|
248
|
+
* };
|
|
249
|
+
*
|
|
250
|
+
* registry.addCondition(canWinDeal);
|
|
251
|
+
* registry.addCondition(canLoseDeal);
|
|
252
|
+
*
|
|
253
|
+
* const actions = [
|
|
254
|
+
* {
|
|
255
|
+
* label: 'Mark as Won',
|
|
256
|
+
* icon: 'trophy',
|
|
257
|
+
* command: { name: 'win-deal' },
|
|
258
|
+
* condition: registry.getCondition('deal.can-win')
|
|
259
|
+
* },
|
|
260
|
+
* {
|
|
261
|
+
* label: 'Mark as Lost',
|
|
262
|
+
* icon: 'times',
|
|
263
|
+
* command: { name: 'lose-deal' },
|
|
264
|
+
* condition: registry.getCondition('deal.can-lose')
|
|
265
|
+
* }
|
|
266
|
+
* ];
|
|
267
|
+
*
|
|
268
|
+
* const availableActions = actions.filter(action => {
|
|
269
|
+
* return !action.condition || action.condition.evaluate(deal);
|
|
270
|
+
* });
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* @see {@link Condition} for the condition structure
|
|
274
|
+
* @see {@link LimeObjectCondition} for object-specific conditions
|
|
275
|
+
* @see {@link ActionCondition} for action-specific conditions
|
|
68
276
|
*
|
|
69
277
|
* @beta
|
|
70
278
|
* @group Conditions
|
|
71
279
|
*/
|
|
72
280
|
export interface ConditionRegistry {
|
|
73
281
|
/**
|
|
74
|
-
*
|
|
282
|
+
* Registers a new condition in the registry.
|
|
283
|
+
*
|
|
284
|
+
* The condition's ID must be unique across all registered conditions.
|
|
285
|
+
* If a condition with the same ID already exists, this method throws an error.
|
|
286
|
+
* It's recommended to register conditions during application startup.
|
|
75
287
|
*
|
|
76
|
-
* @param condition -
|
|
77
|
-
* @throws
|
|
288
|
+
* @param condition - The condition to register. Must have a unique ID.
|
|
289
|
+
* @throws Error if a condition with the same ID already exists in the registry.
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const isActive: LimeObjectCondition = {
|
|
294
|
+
* id: 'deal.is-active',
|
|
295
|
+
* type: 'limeobject',
|
|
296
|
+
* evaluate: (deal) => deal.dealstatus === 'active'
|
|
297
|
+
* };
|
|
298
|
+
*
|
|
299
|
+
* registry.addCondition(isActive);
|
|
300
|
+
* ```
|
|
78
301
|
*/
|
|
79
302
|
addCondition(condition: Condition): any;
|
|
80
303
|
/**
|
|
81
|
-
*
|
|
304
|
+
* Removes a condition from the registry.
|
|
305
|
+
*
|
|
306
|
+
* The condition is identified by its ID. If no condition with the given ID
|
|
307
|
+
* exists in the registry, this method throws an error.
|
|
308
|
+
*
|
|
309
|
+
* @param condition - The condition to remove. Must exist in the registry.
|
|
310
|
+
* @throws Error if the condition's ID does not exist in the registry.
|
|
82
311
|
*
|
|
83
|
-
* @
|
|
84
|
-
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* const condition = registry.getCondition('deal.is-active');
|
|
315
|
+
* registry.removeCondition(condition);
|
|
316
|
+
* ```
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* Safe removal with existence check
|
|
320
|
+
* ```typescript
|
|
321
|
+
* if (registry.hasCondition('deal.is-active')) {
|
|
322
|
+
* registry.removeCondition(registry.getCondition('deal.is-active'));
|
|
323
|
+
* }
|
|
324
|
+
* ```
|
|
85
325
|
*/
|
|
86
326
|
removeCondition(condition: Condition): any;
|
|
87
327
|
/**
|
|
88
|
-
* Checks
|
|
328
|
+
* Checks whether a condition with the given ID exists in the registry.
|
|
329
|
+
*
|
|
330
|
+
* This method is useful for defensive programming, allowing you to verify
|
|
331
|
+
* that a condition exists before attempting to retrieve or remove it.
|
|
332
|
+
*
|
|
333
|
+
* @param id - The unique identifier of the condition to check.
|
|
334
|
+
* @returns `true` if a condition with the ID exists, `false` otherwise.
|
|
89
335
|
*
|
|
90
|
-
* @
|
|
91
|
-
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* if (registry.hasCondition('deal.can-win')) {
|
|
339
|
+
* const condition = registry.getCondition('deal.can-win');
|
|
340
|
+
* const canWin = condition.evaluate(deal);
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
92
343
|
*/
|
|
93
344
|
hasCondition(id: string): boolean;
|
|
94
345
|
/**
|
|
95
|
-
*
|
|
346
|
+
* Retrieves all registered conditions.
|
|
96
347
|
*
|
|
97
|
-
*
|
|
348
|
+
* This method returns a list of all conditions currently in the registry,
|
|
349
|
+
* regardless of their type. This can be useful for debugging, inspection,
|
|
350
|
+
* or building dynamic UIs that need to enumerate available conditions.
|
|
351
|
+
*
|
|
352
|
+
* @returns An array of all registered conditions.
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```typescript
|
|
356
|
+
* const allConditions = registry.getConditions();
|
|
357
|
+
* console.log(`Found ${allConditions.length} conditions`);
|
|
358
|
+
*
|
|
359
|
+
* const limeObjectConditions = allConditions.filter(
|
|
360
|
+
* c => c.type === 'limeobject'
|
|
361
|
+
* );
|
|
362
|
+
* ```
|
|
98
363
|
*/
|
|
99
364
|
getConditions(): Condition[];
|
|
100
365
|
/**
|
|
101
|
-
*
|
|
366
|
+
* Retrieves a specific condition by its unique identifier.
|
|
367
|
+
*
|
|
368
|
+
* If no condition with the given ID exists, this method throws an error.
|
|
369
|
+
* Use {@link ConditionRegistry.hasCondition} first if you need to check for existence.
|
|
370
|
+
*
|
|
371
|
+
* @param id - The unique identifier of the condition to retrieve.
|
|
372
|
+
* @returns The condition with the specified ID.
|
|
373
|
+
* @throws Error if no condition with the given ID exists in the registry.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* const canWin = registry.getCondition('deal.can-win');
|
|
378
|
+
* const isEligible = canWin.evaluate(dealObject);
|
|
379
|
+
* ```
|
|
102
380
|
*
|
|
103
|
-
* @
|
|
104
|
-
*
|
|
105
|
-
*
|
|
381
|
+
* @example
|
|
382
|
+
* Safe retrieval with type checking
|
|
383
|
+
* ```typescript
|
|
384
|
+
* const condition = registry.getCondition('deal.is-active');
|
|
385
|
+
* if (isLimeObjectCondition(condition)) {
|
|
386
|
+
* const result = condition.evaluate(myDeal);
|
|
387
|
+
* }
|
|
388
|
+
* ```
|
|
106
389
|
*/
|
|
107
390
|
getCondition(id: string): Condition;
|
|
108
391
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditionregistry.d.ts","sourceRoot":"","sources":["../../src/conditionregistry/conditionregistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C
|
|
1
|
+
{"version":3,"file":"conditionregistry.d.ts","sourceRoot":"","sources":["../../src/conditionregistry/conditionregistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI;IACjC;;;;;;;;OAQG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IAEpD;;;;;;OAMG;IACH,EAAE,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG;IACtD,IAAI,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG;IAC9C,IAAI,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,SAAS,GACrB,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,CAEpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,SAAS,GACrB,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC,CAEhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,OAAE;IAEnC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,eAAe,CAAC,SAAS,EAAE,SAAS,OAAE;IAEtC;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAElC;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,IAAI,SAAS,EAAE,CAAC;IAE7B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC"}
|
|
@@ -8,10 +8,57 @@ export interface SelectConfigOptions extends StateOptions {
|
|
|
8
8
|
name?: string;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Decorator that subscribes to configuration data from the {@link ConfigRepository}.
|
|
12
|
+
*
|
|
13
|
+
* This decorator automatically updates the decorated property whenever configuration
|
|
14
|
+
* data changes in the platform. Returns an object with all configs where the config
|
|
15
|
+
* key is used as the key. It's the recommended approach over manual subscriptions as
|
|
16
|
+
* it handles subscription lifecycle automatically.
|
|
17
|
+
*
|
|
18
|
+
* @param options - Configuration including key filtering and state transformation via {@link SelectConfigOptions}
|
|
19
|
+
* @returns A PropertyDecorator that sets up automatic subscription to config data
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* Subscribes to: {@link ConfigRepository}
|
|
23
|
+
*
|
|
24
|
+
* Updates: The decorated property with configuration data (object or specific value)
|
|
25
|
+
*
|
|
26
|
+
* Lifecycle: Automatically subscribes in `connectedCallback` and unsubscribes
|
|
27
|
+
* in `disconnectedCallback`
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* Get all configuration data
|
|
31
|
+
* ```typescript
|
|
32
|
+
* @State()
|
|
33
|
+
* @SelectConfig({})
|
|
34
|
+
* private config: Record<string, unknown>;
|
|
35
|
+
*
|
|
36
|
+
* render() {
|
|
37
|
+
* return (
|
|
38
|
+
* <div>
|
|
39
|
+
* <h2>Configuration</h2>
|
|
40
|
+
* <pre>{JSON.stringify(this.config, null, 2)}</pre>
|
|
41
|
+
* </div>
|
|
42
|
+
* );
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* Get specific config value by name
|
|
48
|
+
* ```typescript
|
|
49
|
+
* @State()
|
|
50
|
+
* @SelectConfig({
|
|
51
|
+
* name: 'apiEndpoint',
|
|
52
|
+
* map: [(config) => config?.url || 'https://api.example.com']
|
|
53
|
+
* })
|
|
54
|
+
* private apiUrl: string;
|
|
55
|
+
*
|
|
56
|
+
* async fetchData() {
|
|
57
|
+
* const response = await fetch(`${this.apiUrl}/data`);
|
|
58
|
+
* return response.json();
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
12
61
|
*
|
|
13
|
-
* @param options - state decorator options
|
|
14
|
-
* @returns state decorator
|
|
15
62
|
* @public
|
|
16
63
|
* @group Config
|
|
17
64
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../../src/config/decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EAEf,MAAM,SAAS,CAAC;AAGjB;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../../src/config/decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EAEf,MAAM,SAAS,CAAC;AAGjB;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,iBAAiB,CAM5E"}
|
|
@@ -1,29 +1,150 @@
|
|
|
1
1
|
import { StateRepository } from '../core/state';
|
|
2
2
|
/**
|
|
3
|
+
* Repository for storing and retrieving application-wide configuration data.
|
|
4
|
+
*
|
|
5
|
+
* {@link ConfigRepository} provides persistent key-value storage for configuration
|
|
6
|
+
* that applies to all users across the application. Typical use cases include:
|
|
7
|
+
* - View configurations (card layouts, table columns, form structures)
|
|
8
|
+
* - Plugin-specific configuration settings
|
|
9
|
+
*
|
|
10
|
+
* Each plugin or package typically manages its own configuration namespace,
|
|
11
|
+
* storing settings that define how components should be rendered or behave
|
|
12
|
+
* for all users.
|
|
13
|
+
*
|
|
14
|
+
* **Important:** This repository is NOT for user preferences. User-specific
|
|
15
|
+
* settings should use {@link UserPreferencesRepository} instead.
|
|
16
|
+
*
|
|
17
|
+
* Configuration data is:
|
|
18
|
+
* - Stored persistently in the database
|
|
19
|
+
* - Shared across all users and sessions
|
|
20
|
+
* - Read-only for non-admin users (set method requires admin privileges)
|
|
21
|
+
*
|
|
22
|
+
* The repository extends {@link StateRepository}, providing reactive state
|
|
23
|
+
* management with automatic UI updates when configuration changes.
|
|
24
|
+
*
|
|
25
|
+
* Access the repository through the platform service:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const repo = this.platform.get(PlatformServiceName.ConfigRepository);
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* Read view configuration
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const repo = platform.get(PlatformServiceName.ConfigRepository);
|
|
34
|
+
*
|
|
35
|
+
* if (repo.has('webclient_view.company')) {
|
|
36
|
+
* const cardConfig = repo.get('webclient_view.company').card;
|
|
37
|
+
* renderCard(cardConfig);
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* Read plugin configuration with type safety
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const repo = platform.get(PlatformServiceName.ConfigRepository);
|
|
45
|
+
*
|
|
46
|
+
* if (!repo.has('my_plugin_config')) {
|
|
47
|
+
* return useDefaultConfig();
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* const pluginConfig = repo.get('my_plugin_config');
|
|
51
|
+
* const isEnabled = pluginConfig?.enabled ?? false;
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
3
54
|
* @public
|
|
4
55
|
* @group Config
|
|
56
|
+
* @see {@link StateRepository} for subscription patterns
|
|
5
57
|
*/
|
|
6
58
|
export interface ConfigRepository extends StateRepository {
|
|
7
59
|
/**
|
|
8
|
-
* Check if a
|
|
60
|
+
* Check if a configuration key exists.
|
|
9
61
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
62
|
+
* Returns `true` if configuration data has been stored under the specified key,
|
|
63
|
+
* `false` otherwise. Use this to check for the existence of optional configuration
|
|
64
|
+
* before attempting to retrieve it.
|
|
65
|
+
*
|
|
66
|
+
* @param key - Name of the configuration key to check
|
|
67
|
+
* @returns `true` if the configuration exists, `false` otherwise
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Check before loading view config
|
|
72
|
+
* const repo = platform.get(PlatformServiceName.ConfigRepository);
|
|
73
|
+
*
|
|
74
|
+
* if (repo.has('person_table_columns')) {
|
|
75
|
+
* const columns = repo.get('person_table_columns');
|
|
76
|
+
* renderTable(columns);
|
|
77
|
+
* } else {
|
|
78
|
+
* // Use default columns
|
|
79
|
+
* renderTable(defaultColumns);
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @see {@link ConfigRepository.get} to retrieve configuration values
|
|
84
|
+
* @see {@link ConfigRepository.set} to store configuration values
|
|
12
85
|
*/
|
|
13
86
|
has(key: string): boolean;
|
|
14
87
|
/**
|
|
15
|
-
* Get
|
|
88
|
+
* Get configuration data for a key.
|
|
89
|
+
*
|
|
90
|
+
* Retrieves the configuration value stored under the specified key.
|
|
91
|
+
* Returns the stored data, or `undefined` if the key doesn't exist.
|
|
92
|
+
*
|
|
93
|
+
* Use the type parameter `<T>` to specify the expected type of the configuration
|
|
94
|
+
* data for type safety. The repository does not validate types at runtime.
|
|
95
|
+
*
|
|
96
|
+
* @param key - Name of the configuration key to retrieve
|
|
97
|
+
* @returns The stored configuration data, or `undefined` if not found
|
|
98
|
+
* @throws May throw if the stored data cannot be deserialized
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // Get view configuration
|
|
103
|
+
* const repo = platform.get(PlatformServiceName.ConfigRepository);
|
|
104
|
+
* const cardConfig = repo.get('webclient_view.company').card;
|
|
105
|
+
* ```
|
|
16
106
|
*
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
107
|
+
* @see {@link ConfigRepository.has} to check if a key exists
|
|
108
|
+
* @see {@link ConfigRepository.set} to store configuration values
|
|
19
109
|
*/
|
|
20
110
|
get<T = any>(key: string): T;
|
|
21
111
|
/**
|
|
22
|
-
*
|
|
112
|
+
* Save configuration data under a key.
|
|
113
|
+
*
|
|
114
|
+
* > **Important:** This method requires admin privileges. The backend endpoint
|
|
115
|
+
* > is protected and will reject requests from non-admin users.
|
|
116
|
+
*
|
|
117
|
+
* Stores the provided data persistently under the specified key. If the key
|
|
118
|
+
* already exists, its value is overwritten. The data is serialized and saved
|
|
119
|
+
* to the database, making it available to all users across the application.
|
|
120
|
+
*
|
|
121
|
+
* After saving, the repository state is updated, triggering any subscriptions.
|
|
122
|
+
* The data can be any serializable JavaScript value (objects, arrays, primitives).
|
|
123
|
+
*
|
|
124
|
+
* @param key - Name of the configuration key to set
|
|
125
|
+
* @param data - Configuration data to store (must be serializable)
|
|
126
|
+
* @returns Promise that resolves when the data is saved
|
|
127
|
+
* @throws Error if save fails, data cannot be serialized, or user lacks admin privileges
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* // Admin: Set plugin configuration
|
|
132
|
+
* const repo = platform.get(PlatformServiceName.ConfigRepository);
|
|
133
|
+
*
|
|
134
|
+
* const pluginConfig: PluginConfiguration = {
|
|
135
|
+
* enabled: true,
|
|
136
|
+
* apiEndpoint: 'https://api.example.com',
|
|
137
|
+
* settings: {
|
|
138
|
+
* timeout: 5000,
|
|
139
|
+
* retries: 3
|
|
140
|
+
* }
|
|
141
|
+
* };
|
|
142
|
+
*
|
|
143
|
+
* await repo.set('my_plugin_config', pluginConfig);
|
|
144
|
+
* ```
|
|
23
145
|
*
|
|
24
|
-
* @
|
|
25
|
-
* @
|
|
26
|
-
* @returns a promise that will be resolved when the config has been saved
|
|
146
|
+
* @see {@link ConfigRepository.get} to retrieve stored configuration
|
|
147
|
+
* @see {@link ConfigRepository.has} to check if a key exists
|
|
27
148
|
*/
|
|
28
149
|
set<T = any>(key: string, data: T): Promise<void>;
|
|
29
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/config/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/config/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAE1B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IAEH,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC;IAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IAEH,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
|