@cccteam/ccc-lib 0.0.24 → 0.0.25
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/fesm2022/cccteam-ccc-lib-auth-forms.mjs +13 -13
- package/fesm2022/cccteam-ccc-lib-auth-forms.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-auth-has-permission.mjs +4 -4
- package/fesm2022/cccteam-ccc-lib-auth-has-permission.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-auth-service.mjs +15 -8
- package/fesm2022/cccteam-ccc-lib-auth-service.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ccc-camel-case-to-title.mjs +3 -3
- package/fesm2022/cccteam-ccc-lib-ccc-grid.mjs +20 -20
- package/fesm2022/cccteam-ccc-lib-ccc-grid.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ccc-resource-modals.mjs +3 -3
- package/fesm2022/cccteam-ccc-lib-ccc-resource-services.mjs +5 -5
- package/fesm2022/cccteam-ccc-lib-ccc-resource-services.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ccc-resource.mjs +287 -281
- package/fesm2022/cccteam-ccc-lib-ccc-resource.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-types.mjs +70 -18
- package/fesm2022/cccteam-ccc-lib-types.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ui-alert.mjs +3 -3
- package/fesm2022/cccteam-ccc-lib-ui-core-service.mjs +7 -7
- package/fesm2022/cccteam-ccc-lib-ui-core-service.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ui-idle-service.mjs +18 -11
- package/fesm2022/cccteam-ccc-lib-ui-idle-service.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ui-interceptor.mjs +3 -3
- package/fesm2022/cccteam-ccc-lib-ui-notification-service.mjs +5 -5
- package/fesm2022/cccteam-ccc-lib-ui-notification-service.mjs.map +1 -1
- package/fesm2022/cccteam-ccc-lib-ui-sidenav.mjs +4 -4
- package/fesm2022/cccteam-ccc-lib-ui-sidenav.mjs.map +1 -1
- package/package.json +1 -1
- package/types/cccteam-ccc-lib-auth-service.d.ts +2 -1
- package/types/cccteam-ccc-lib-forms.d.ts +1 -1
- package/types/cccteam-ccc-lib-types.d.ts +45 -1
- package/types/cccteam-ccc-lib-ui-idle-service.d.ts +2 -1
|
@@ -224,13 +224,13 @@ function rootConfig(config) {
|
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
226
|
class CustomConfigComponent {
|
|
227
|
-
uuid = input(
|
|
228
|
-
parentData = input(
|
|
229
|
-
config = input(
|
|
230
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
231
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.
|
|
227
|
+
uuid = input(...(ngDevMode ? [undefined, { debugName: "uuid" }] : []));
|
|
228
|
+
parentData = input(...(ngDevMode ? [undefined, { debugName: "parentData" }] : []));
|
|
229
|
+
config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : []));
|
|
230
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CustomConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
231
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: CustomConfigComponent, isStandalone: true, inputs: { uuid: { classPropertyName: "uuid", publicName: "uuid", isSignal: true, isRequired: false, transformFunction: null }, parentData: { classPropertyName: "parentData", publicName: "parentData", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
232
232
|
}
|
|
233
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
233
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CustomConfigComponent, decorators: [{
|
|
234
234
|
type: Directive
|
|
235
235
|
}], propDecorators: { uuid: [{ type: i0.Input, args: [{ isSignal: true, alias: "uuid", required: false }] }], parentData: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentData", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }] } });
|
|
236
236
|
function componentConfig(config) {
|
|
@@ -378,28 +378,80 @@ const UpdatePermission = 'Update';
|
|
|
378
378
|
|
|
379
379
|
/**
|
|
380
380
|
* The base URL for API requests (e.g., 'https://api.example.com/').
|
|
381
|
+
* @defaultValue '/'
|
|
381
382
|
*/
|
|
382
|
-
const BASE_URL = new InjectionToken('BASE_URL');
|
|
383
|
+
const BASE_URL = new InjectionToken('BASE_URL', { factory: () => '/' });
|
|
383
384
|
/**
|
|
384
385
|
* The path to the frontend login page (e.g., '/login').
|
|
386
|
+
* @defaultValue '/login'
|
|
385
387
|
*/
|
|
386
|
-
const FRONTEND_LOGIN_PATH = new InjectionToken('FRONTEND_LOGIN_PATH');
|
|
388
|
+
const FRONTEND_LOGIN_PATH = new InjectionToken('FRONTEND_LOGIN_PATH', { factory: () => '/login' });
|
|
387
389
|
/**
|
|
388
390
|
* The path to the session endpoint (e.g., 'user/session').
|
|
391
|
+
* @defaultValue 'user/session'
|
|
389
392
|
*/
|
|
390
|
-
const SESSION_PATH = new InjectionToken('SESSION_PATH');
|
|
393
|
+
const SESSION_PATH = new InjectionToken('SESSION_PATH', { factory: () => 'user/session' });
|
|
391
394
|
/**
|
|
392
395
|
* The base URL for API requests (e.g., '/api').
|
|
396
|
+
* @defaultValue '/api'
|
|
397
|
+
*/
|
|
398
|
+
const API_URL = new InjectionToken('API_URL', { factory: () => '/api' });
|
|
399
|
+
/**
|
|
400
|
+
* A function to determine if a specific permission is required for a given resource.
|
|
401
|
+
* @defaultValue a function that always returns false
|
|
402
|
+
*/
|
|
403
|
+
const PERMISSION_REQUIRED = new InjectionToken('PERMISSION_REQUIRED', { factory: () => () => false });
|
|
404
|
+
/**
|
|
405
|
+
* The available permissions in the system.
|
|
406
|
+
* @defaultValue an empty array
|
|
393
407
|
*/
|
|
394
|
-
const API_URL = new InjectionToken('API_URL');
|
|
395
|
-
const PERMISSION_REQUIRED = new InjectionToken('PERMISSION_REQUIRED');
|
|
396
408
|
const AVAILABLE_PERMISSIONS = new InjectionToken('AVAILABLE_PERMISSIONS');
|
|
397
|
-
const AVAILABLE_DOMAINS = new InjectionToken('AVAILABLE_DOMAINS'
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
409
|
+
const AVAILABLE_DOMAINS = new InjectionToken('AVAILABLE_DOMAINS', {
|
|
410
|
+
factory: () => [],
|
|
411
|
+
});
|
|
412
|
+
/**
|
|
413
|
+
* The generated resourceMeta from the output of the [ccc package](https://github.com/cccteam/ccc) typescript generator
|
|
414
|
+
* Required to work with generated routes and resource metadata
|
|
415
|
+
* @defaultValue a no-op function that returns an empty object
|
|
416
|
+
*/
|
|
417
|
+
const RESOURCE_META = new InjectionToken('RESOURCE_META', {
|
|
418
|
+
factory: () => () => ({}),
|
|
419
|
+
});
|
|
420
|
+
/**
|
|
421
|
+
* The generated methodMeta from the output of the [ccc package](https://github.com/cccteam/ccc) typescript generator
|
|
422
|
+
* Required to work with generated method data
|
|
423
|
+
* @defaultValue a no-op function that returns an empty object
|
|
424
|
+
*/
|
|
425
|
+
const METHOD_META = new InjectionToken('METHOD_META', {
|
|
426
|
+
factory: () => () => ({}),
|
|
427
|
+
});
|
|
428
|
+
/**
|
|
429
|
+
* The duration in seconds for the session to be considered idle.
|
|
430
|
+
* @defaultValue 300 seconds
|
|
431
|
+
*/
|
|
432
|
+
const IDLE_SESSION_DURATION = new InjectionToken('IDLE_SESSION_DURATION', { factory: () => 300 });
|
|
433
|
+
/**
|
|
434
|
+
* The duration in seconds for the warning to be shown to the user before the session times out due to inactivity.
|
|
435
|
+
* @defaultValue 60 seconds
|
|
436
|
+
*/
|
|
437
|
+
const IDLE_WARNING_DURATION = new InjectionToken('IDLE_WARNING_DURATION', { factory: () => 60 });
|
|
438
|
+
/**
|
|
439
|
+
* The duration in seconds for the keepalive ping to be sent to the server to keep the session alive.
|
|
440
|
+
* @defaultValue 30 seconds
|
|
441
|
+
*/
|
|
442
|
+
const IDLE_KEEPALIVE_DURATION = new InjectionToken('IDLE_KEEPALIVE_DURATION', { factory: () => 30 });
|
|
443
|
+
/**
|
|
444
|
+
* A function to be called when the user logs out.
|
|
445
|
+
* @defaultValue a no-op function that returns 0
|
|
446
|
+
*/
|
|
447
|
+
const LOGOUT_ACTION = new InjectionToken('LOGOUT_ACTION', { factory: () => () => 0 });
|
|
448
|
+
/**
|
|
449
|
+
* A function to be called when the user is logged out due to inactivity.
|
|
450
|
+
* @defaultValue a no-op function that returns 0
|
|
451
|
+
*/
|
|
452
|
+
const IDLE_LOGOUT_ACTION = new InjectionToken('IDLE_LOGOUT_ACTION', {
|
|
453
|
+
factory: () => () => 0,
|
|
454
|
+
});
|
|
403
455
|
|
|
404
456
|
const validatorsPresent = (control, validators, previousValidatorCount) => {
|
|
405
457
|
if (validators.length === previousValidatorCount) {
|
|
@@ -433,5 +485,5 @@ function createResourceValidator(validator) {
|
|
|
433
485
|
* Generated bundle index. Do not edit.
|
|
434
486
|
*/
|
|
435
487
|
|
|
436
|
-
export { API_URL, AVAILABLE_DOMAINS, AVAILABLE_PERMISSIONS, AlertLevel, BASE_URL, CustomConfigComponent, FRONTEND_LOGIN_PATH, IDLE_KEEPALIVE_DURATION, IDLE_SESSION_DURATION, IDLE_WARNING_DURATION, METHOD_META, PERMISSION_REQUIRED, RESOURCE_META, ReadPermission, SESSION_PATH, UpdatePermission, actionButtonConfig, actionButtonConfigDefaults, additionalResourceConfig, additionalResourceConfigDefaults, arrayConfig, arrayConfigDefaults, componentConfig, componentConfigDefaults, computedDisplayField, computedDisplayFieldElementDefaults, createResourceValidator, defaultEmptyFieldValue, enumeratedConfig, enumeratedConfigDefaults, field, fieldElementDefaults, fieldSort, fieldSortDefaults, foreignKeyDefault, foreignKeyDefaultDefaults, listViewConfig, listViewConfigDefaults, multiColumnConfig, multiColumnConfigDefaults, nullBooleanConfig, nullBooleanConfigDefaults, padding, paddingElementDefaults, requiredIf, rootConfig, rootConfigDefaults, rpcConfig, rpcConfigDefaults, section, sectionElementDefaults, singleColumnConfig, singleColumnConfigDefaults, staticDefault, staticDefaultDefaults, switchParams, switchParamsDefaults, validatorsPresent, viewConfig, viewConfigDefaults };
|
|
488
|
+
export { API_URL, AVAILABLE_DOMAINS, AVAILABLE_PERMISSIONS, AlertLevel, BASE_URL, CustomConfigComponent, FRONTEND_LOGIN_PATH, IDLE_KEEPALIVE_DURATION, IDLE_LOGOUT_ACTION, IDLE_SESSION_DURATION, IDLE_WARNING_DURATION, LOGOUT_ACTION, METHOD_META, PERMISSION_REQUIRED, RESOURCE_META, ReadPermission, SESSION_PATH, UpdatePermission, actionButtonConfig, actionButtonConfigDefaults, additionalResourceConfig, additionalResourceConfigDefaults, arrayConfig, arrayConfigDefaults, componentConfig, componentConfigDefaults, computedDisplayField, computedDisplayFieldElementDefaults, createResourceValidator, defaultEmptyFieldValue, enumeratedConfig, enumeratedConfigDefaults, field, fieldElementDefaults, fieldSort, fieldSortDefaults, foreignKeyDefault, foreignKeyDefaultDefaults, listViewConfig, listViewConfigDefaults, multiColumnConfig, multiColumnConfigDefaults, nullBooleanConfig, nullBooleanConfigDefaults, padding, paddingElementDefaults, requiredIf, rootConfig, rootConfigDefaults, rpcConfig, rpcConfigDefaults, section, sectionElementDefaults, singleColumnConfig, singleColumnConfigDefaults, staticDefault, staticDefaultDefaults, switchParams, switchParamsDefaults, validatorsPresent, viewConfig, viewConfigDefaults };
|
|
437
489
|
//# sourceMappingURL=cccteam-ccc-lib-types.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cccteam-ccc-lib-types.mjs","sources":["../../../projects/ccc-lib/types/resource-types.ts","../../../projects/ccc-lib/types/configs.ts","../../../projects/ccc-lib/types/notification-message.ts","../../../projects/ccc-lib/types/permissions.ts","../../../projects/ccc-lib/types/tokens.ts","../../../projects/ccc-lib/types/validators.ts","../../../projects/ccc-lib/types/cccteam-ccc-lib-types.ts"],"sourcesContent":["export const defaultEmptyFieldValue = '-';\n\nexport type NullBoolean = null | true | false;\n\nexport type ConcatFn = 'space-concat' | 'hyphen-concat' | 'space-hyphen-concat' | 'hyphen-space-concat';\n","import { Directive, input, Type } from '@angular/core';\nimport { TooltipPosition } from '@angular/material/tooltip';\nimport { FieldName, Method, Resource } from './permissions';\nimport { ResourceMeta } from './resource-meta';\nimport { ConcatFn, defaultEmptyFieldValue, NullBoolean } from './resource-types';\nimport { ResourceValidatorFn } from './validators';\n\nexport type ResourceMap = Record<Resource, ResourceMeta>;\n\nexport interface FieldPointer {\n field: FieldName;\n}\n\nexport interface MenuItem {\n label: string;\n route?: string[];\n children?: MenuItem[];\n}\n\nexport interface RouteResourceData {\n config: RootConfig;\n}\n\nexport type DataType = string | number | number[] | string[] | boolean | undefined | Date;\nexport type RecordData = Record<string, DataType | null>;\n\nexport type RPCDataType = string | number | string[] | number[] | boolean | Date;\nexport type RPCRecordData = Record<string, RPCDataType>;\nexport type RpcMethod = Record<string, DataType>;\n\nexport type ParentResourceConfig = ListViewConfig | ViewConfig | ArrayConfig;\nexport type ChildResourceConfig = ListViewConfig | ViewConfig | ComponentConfig | ArrayConfig;\n\nexport type ActionType = 'function' | 'link';\n\nexport type ListConcatFn =\n | 'space-concat'\n | 'hyphen-concat'\n | 'space-hyphen-concat'\n | 'hyphen-space-concat'\n | 'no-space-concat';\nexport type ConfigType = ChildResourceConfig;\nexport type FormatType = 'simpleSlashDateFormat';\nexport type RPCPlacement = 'inline' | 'end';\n\nexport type ColumnConfig = SingleColumnConfig | MultiColumnConfig;\n\nexport interface ActionButtonConfig {\n label: string;\n icon: string;\n action?: (resource: { id: string }) => void;\n viewRoute?: string;\n actionType?: ActionType;\n color?: string;\n disabledLabel?: string;\n}\nexport interface ActionButtonConfigOptions {\n label: string;\n icon: string;\n action?: (resource: { id: string }) => void;\n viewRoute?: string;\n actionType?: ActionType;\n color?: string;\n disabledLabel?: string;\n}\n\nexport function actionButtonConfig(config: ActionButtonConfigOptions): ActionButtonConfig {\n return {\n ...actionButtonConfigDefaults,\n ...config,\n } satisfies ActionButtonConfig;\n}\n\nexport const actionButtonConfigDefaults = {\n label: '',\n icon: '',\n actionType: 'function' as ActionType,\n color: '',\n disabledLabel: '',\n} satisfies ActionButtonConfig;\n\nexport interface SingleColumnConfig {\n id: FieldName;\n header?: string;\n width?: number;\n resizable?: boolean;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n valueGetter?: (data: any) => string;\n valueFormatter?: (data: any) => string;\n tooltipPosition?: TooltipPosition;\n viewRoute?: Resource;\n buttonConfig?: ActionButtonConfig;\n actionType?: ActionType;\n formatType?: FormatType | string;\n hidden?: boolean;\n emptyDataValue?: DataType;\n filterable?: boolean;\n hideHeader?: boolean;\n}\nexport interface SingleColumnConfigOptions {\n id: FieldName;\n header?: string;\n width?: number;\n resizable?: boolean;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n valueGetter?: (data: any) => string;\n valueFormatter?: (data: any) => string;\n tooltipPosition?: TooltipPosition;\n viewRoute?: Resource;\n buttonConfig?: ActionButtonConfig;\n actionType?: ActionType;\n formatType?: FormatType | string;\n hidden?: boolean;\n emptyDataValue?: DataType;\n filterable?: boolean;\n hideHeader?: boolean;\n}\n\nexport function singleColumnConfig(config: SingleColumnConfigOptions): SingleColumnConfig {\n return {\n ...singleColumnConfigDefaults,\n ...config,\n } satisfies SingleColumnConfig;\n}\n\nexport const singleColumnConfigDefaults = {\n id: '' as FieldName,\n header: '',\n resizable: true,\n actionType: 'function' as ActionType,\n hidden: false,\n filterable: true,\n hideHeader: false,\n} satisfies SingleColumnConfig;\n\nexport interface MultiColumnConfig extends SingleColumnConfig {\n // todo: additionalIds name is not clear. the id provided is fetched from a different resource, such as a typeId\n additionalIds: AdditionalResourceConfig[];\n concatFn: ListConcatFn;\n}\nexport interface MultiColumnConfigOptions extends SingleColumnConfigOptions {\n additionalIds: AdditionalResourceConfig[];\n concatFn: ListConcatFn;\n}\n\nexport function multiColumnConfig(config: MultiColumnConfigOptions): MultiColumnConfig {\n return {\n ...multiColumnConfigDefaults,\n ...config,\n } satisfies MultiColumnConfig;\n}\n\nexport const multiColumnConfigDefaults = {\n ...singleColumnConfigDefaults,\n additionalIds: [] as AdditionalResourceConfig[],\n concatFn: 'hyphen-concat' as ListConcatFn,\n} satisfies MultiColumnConfig;\n\nexport interface AdditionalResourceConfig {\n resource?: Resource;\n id: FieldName;\n field?: FieldName;\n hidden?: boolean;\n}\nexport interface AdditionalResourceConfigOptions {\n id: FieldName;\n resource?: Resource;\n field?: FieldName;\n hidden?: boolean;\n}\n\nexport function additionalResourceConfig(config: AdditionalResourceConfigOptions): AdditionalResourceConfig {\n return {\n ...additionalResourceConfigDefaults,\n ...config,\n } satisfies AdditionalResourceConfig;\n}\n\nexport const additionalResourceConfigDefaults = {\n id: '' as FieldName,\n resource: '' as Resource,\n field: '' as FieldName,\n hidden: false,\n} satisfies AdditionalResourceConfig;\n\nexport interface FieldSort {\n field: FieldName;\n direction: 'asc' | 'desc';\n}\nexport interface FieldSortOptions {\n field: FieldName;\n direction?: 'asc' | 'desc';\n}\n\nexport function fieldSort(config: FieldSortOptions): FieldSort {\n return {\n ...fieldSortDefaults,\n ...config,\n } satisfies FieldSort;\n}\n\nexport const fieldSortDefaults = {\n field: '' as FieldName,\n direction: 'asc' as 'asc' | 'desc',\n} satisfies FieldSort;\n\nexport interface EnumeratedConfigOptions {\n // primaryResource comes from the metadata\n overrideResource?: Resource;\n /* A function to filter the list of enumerated options.\n * The `parentResource` argument contains the data of the resource that this enumerated field is part of.\n * It will be an object with the current form values, which can be empty during resource creation.\n */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter?: (resource: any) => string;\n /**\n * Set disableCacheForFilterPii to `true` to promote the GET to a POST when PII is used in the filter\n * POST requests cannot be cached\n */\n disableCacheForFilterPii?: boolean;\n /**\n * Specifies which resource data to pass to the filter function:\n * - 'rootResource': Pass in the root resource data\n * - 'parentResource': Pass in the parent resource data\n * @default 'parentResource'\n */\n filterType?: FilterType;\n sorts?: FieldSort[];\n listDisplay?: FieldName[];\n viewDisplay: FieldName[];\n viewConcatFn?: ConcatFn;\n listConcatFn?: ConcatFn;\n viewDetails?: boolean;\n searchable?: boolean;\n}\n\ntype FilterType = 'parentResource' | 'rootResource';\nexport interface EnumeratedConfig {\n overrideResource: Resource;\n filter: (resource: any) => string;\n disableCacheForFilterPii: boolean;\n filterType: FilterType;\n sorts: FieldSort[];\n listDisplay: FieldName[];\n viewDisplay: FieldName[];\n viewConcatFn: ConcatFn;\n listConcatFn: ConcatFn;\n viewDetails: boolean;\n searchable: boolean;\n}\nexport function enumeratedConfig(config: EnumeratedConfigOptions): EnumeratedConfig {\n return {\n ...enumeratedConfigDefaults,\n ...config,\n } satisfies EnumeratedConfig;\n}\nexport const enumeratedConfigDefaults = {\n overrideResource: '' as Resource,\n filter: (): string => '',\n disableCacheForFilterPii: false,\n filterType: 'parentResource' as FilterType,\n sorts: [] as FieldSort[],\n listDisplay: [] as FieldName[],\n viewDisplay: [] as FieldName[],\n viewConcatFn: 'hyphen-concat' as ConcatFn,\n listConcatFn: 'hyphen-concat' as ConcatFn,\n viewDetails: false,\n searchable: false,\n};\n\nexport type FieldDefault = ForeignKeyDefault | StaticDefault | null;\n\nexport interface NullBooleanConfigOptions {\n displayValues?: Record<'null' | 'true' | 'false', { label: string; value: NullBoolean }>;\n}\nexport interface NullBooleanConfig {\n /** This property maps the three possible values for this\n * nullboolean field with the display values users will see\n * on the screen for each\n */\n displayValues: Record<'null' | 'true' | 'false', { label: string; value: NullBoolean }>;\n}\nexport function nullBooleanConfig(config: NullBooleanConfigOptions): NullBooleanConfig {\n return {\n ...nullBooleanConfigDefaults,\n ...config,\n } satisfies NullBooleanConfig;\n}\nconst defaultBooleanDisplay = Object.freeze({\n null: {\n label: defaultEmptyFieldValue,\n value: null,\n },\n true: {\n label: 'Yes',\n value: true,\n },\n false: {\n label: 'No',\n value: false,\n },\n});\n\nexport const nullBooleanConfigDefaults = {\n displayValues: defaultBooleanDisplay,\n};\n\nexport interface ForeignKeyDefaultOptions {\n parentId: FieldName;\n}\nexport interface ForeignKeyDefault {\n type: 'foreignKey';\n parentId: FieldName;\n}\nexport function foreignKeyDefault(config: ForeignKeyDefaultOptions): ForeignKeyDefault {\n return {\n ...foreignKeyDefaultDefaults,\n ...config,\n } satisfies ForeignKeyDefault;\n}\nexport const foreignKeyDefaultDefaults = {\n type: 'foreignKey',\n parentId: '' as FieldName,\n} satisfies ForeignKeyDefault;\n\nexport interface StaticDefault {\n type: 'static';\n value: string | boolean;\n}\nexport interface staticDefaultOptions {\n value: string | boolean;\n}\nexport function staticDefault(config: staticDefaultOptions): StaticDefault {\n return {\n ...staticDefaultDefaults,\n ...config,\n } satisfies StaticDefault;\n}\nexport const staticDefaultDefaults = {\n type: 'static',\n value: '',\n} satisfies StaticDefault;\n\nexport type Affix = string | remoteData | parentData;\n\ninterface remoteData {\n resource: Resource;\n id: FieldName;\n field: FieldName;\n}\n\ninterface parentData {\n field: FieldName;\n}\n\nexport type ConfigElement = FieldElement | SectionElement | ComputedDisplayFieldElement | PaddingElement;\n\nexport type ColSize = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\n\nexport interface ComputedDisplayFieldElementOptions {\n label?: string;\n class?: string;\n cols?: ColSize;\n calculatedValue?: (data: any) => string;\n shouldRender?: ((data: any) => boolean) | boolean;\n}\nexport interface ComputedDisplayFieldElement {\n type: 'computedDisplayField';\n label: string;\n class: string;\n cols: ColSize;\n calculatedValue: (data: any) => string;\n shouldRender: ((data: any) => boolean) | boolean;\n}\nexport function computedDisplayField(config: ComputedDisplayFieldElementOptions): ComputedDisplayFieldElement {\n return {\n ...computedDisplayFieldElementDefaults,\n ...config,\n } satisfies ComputedDisplayFieldElement;\n}\nexport const computedDisplayFieldElementDefaults = {\n type: 'computedDisplayField',\n label: '',\n class: '',\n cols: 6,\n calculatedValue: (): string => '',\n shouldRender: true,\n} satisfies ComputedDisplayFieldElement;\n\nexport interface PaddingElementOptions {\n cols?: ColSize;\n shouldRender?: ((data: any) => boolean) | boolean;\n}\nexport interface PaddingElement {\n type: 'padding';\n cols: ColSize;\n /** Determines whether the padding is shown\n */\n shouldRender: ((data: any) => boolean) | boolean;\n}\nexport function padding(config?: PaddingElementOptions): PaddingElement {\n return {\n ...paddingElementDefaults,\n ...config,\n } satisfies PaddingElement;\n}\nexport const paddingElementDefaults = {\n type: 'padding',\n cols: 12,\n shouldRender: true,\n} satisfies PaddingElement;\n\nexport interface SectionElementOptions {\n label?: string;\n class?: string;\n cols?: ColSize;\n shouldRender?: ((data: any) => boolean) | boolean;\n nullAllChildrenIfConditionallyHidden?: boolean;\n children?: ConfigElement[];\n}\nexport interface SectionElement {\n type: 'section';\n label: string;\n class: string;\n cols: ColSize;\n /**\n * shouldRender is used to determine if the section should be\n * displayed to users.\n * When assigning shouldRender a function, the first argument\n * is the current state of the resource being displayed\n * Hides the layout AND all of its children\n */\n shouldRender: ((data: any) => boolean) | boolean;\n /** If shouldRender is NOT a function, this property does nothing\n * If shouldRender is a function, this property\n * sets children's values to null if shouldRender hides it (returns false)\n * within the resource-layout.component\n */\n nullAllChildrenIfConditionallyHidden: boolean;\n children: ConfigElement[];\n}\nexport function section(config: SectionElementOptions): SectionElement {\n return {\n ...sectionElementDefaults,\n ...config,\n } satisfies SectionElement;\n}\nexport const sectionElementDefaults = {\n type: 'section',\n label: '',\n class: '',\n cols: 12,\n shouldRender: true,\n nullAllChildrenIfConditionallyHidden: false,\n children: [],\n} satisfies SectionElement;\n\nexport interface FieldElementOptions {\n name: FieldName;\n label?: string;\n cols?: ColSize;\n class?: string;\n enumeratedConfig?: EnumeratedConfig;\n default?: FieldDefault;\n nullBooleanConfig?: NullBooleanConfig;\n validators?: ((data: any) => ResourceValidatorFn[]) | ResourceValidatorFn[];\n readOnly?: boolean;\n prefixes?: Affix[];\n suffixes?: Affix[];\n shouldRender?: ((data: any) => boolean) | boolean;\n nullIfConditionallyHidden?: boolean;\n}\nexport interface FieldElement {\n type: 'field';\n name: string;\n label: string;\n cols: ColSize;\n class: string;\n enumeratedConfig: EnumeratedConfig;\n default: FieldDefault;\n nullBooleanConfig: NullBooleanConfig;\n /**\n * A list of validators that must pass to allow a field to be submitted.\n * Utilize existing validators in the resourceValidators object, and\n * add any new or custom validators to it\n */\n validators: ((data: any) => ResourceValidatorFn[]) | ResourceValidatorFn[];\n readOnly: boolean;\n prefixes: Affix[];\n suffixes: Affix[];\n /**\n * shouldRender is used to determine if the element should be\n * displayed to users.\n * When assigning shouldRender a function, the first argument\n * is the current state of the resource being displayed\n */\n shouldRender: ((data: any) => boolean) | boolean;\n /** If shouldRender is NOT a function, this property does nothing\n * If shouldRender is a function, this property\n * determines whether the form control associated\n * with this config element should have its value\n * set to null if shouldRender hides it (returns false)\n */\n nullIfConditionallyHidden: boolean;\n}\n\nexport function field(config: FieldElementOptions): FieldElement {\n return {\n ...fieldElementDefaults,\n ...config,\n } satisfies FieldElement;\n}\nexport const fieldElementDefaults = {\n type: 'field',\n name: '',\n label: '',\n cols: 6,\n class: '',\n enumeratedConfig: { ...enumeratedConfigDefaults },\n default: null,\n validators: [],\n nullBooleanConfig: { ...nullBooleanConfigDefaults },\n readOnly: false,\n prefixes: [],\n suffixes: [],\n shouldRender: true,\n nullIfConditionallyHidden: false,\n} satisfies FieldElement;\n\n/**\n * RouteData is used to define the route for a config\n * route: the route for the config\n * hasViewRoute: when true, a route will be created for route/:uuid\n */\nexport interface RootRouteData {\n route?: string;\n hasViewRoute?: boolean;\n}\n\nexport interface RPCConfigOptions {\n label: string;\n afterMethodRedirect?: string;\n conditions: {\n field: FieldName;\n matchValues: string[];\n }[];\n methodBodyTemplate?: any;\n successMessage?: string;\n elements?: ConfigElement[];\n placement?: RPCPlacement;\n method: Method;\n customComponent?: ComponentConfig;\n refreshResources?: Resource[];\n defaultModalWidth?: string;\n shouldRender?: () => boolean;\n}\nexport interface RPCConfig {\n label: string;\n afterMethodRedirect: string | string[];\n conditions: {\n field: FieldName;\n matchValues: string[];\n }[];\n methodBodyTemplate: any;\n method: Method;\n successMessage: string;\n elements: ConfigElement[];\n placement: RPCPlacement;\n customComponent: ComponentConfig;\n refreshResources: Resource[];\n defaultModalWidth: string;\n shouldRender: () => boolean;\n}\nexport function rpcConfig(config: RPCConfigOptions): RPCConfig {\n return {\n ...rpcConfigDefaults,\n ...config,\n } satisfies RPCConfig;\n}\nexport const rpcConfigDefaults = {\n label: '',\n afterMethodRedirect: '',\n conditions: [] as {\n field: FieldName;\n matchValues: string[];\n }[],\n methodBodyTemplate: {} as any,\n successMessage: '',\n elements: [] as ConfigElement[],\n placement: 'end' as RPCPlacement,\n method: '' as Method,\n customComponent: {} as ComponentConfig,\n refreshResources: [] as Resource[],\n defaultModalWidth: '',\n shouldRender: (): boolean => true,\n} satisfies RPCConfig;\n\nexport interface RPCBaseFormData {\n elements: FieldElement[];\n label: string;\n method: Method;\n}\n\n// Config is the base type that all configurations should start with\nexport interface RootConfigOptions {\n routeData?: RootRouteData;\n nav?: {\n navItem: MenuItem;\n group?: string;\n };\n parentConfig: ParentResourceConfig;\n relatedConfigs?: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n}\nexport interface RootConfig {\n routeData: RootRouteData;\n nav: {\n navItem: MenuItem;\n group?: string;\n };\n parentConfig: ParentResourceConfig;\n relatedConfigs: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n}\nexport const rootConfigDefaults = {\n routeData: {} as RootRouteData,\n nav: {\n navItem: {} as MenuItem,\n },\n parentConfig: {} as ParentResourceConfig,\n relatedConfigs: [] as ChildResourceConfig[],\n rpcConfigs: [] as RPCConfig[],\n} satisfies RootConfig;\n\nexport function rootConfig(config: RootConfigOptions): RootConfig {\n return {\n ...rootConfigDefaults,\n ...config,\n } satisfies RootConfig;\n}\n\n// Base type config is the base type for all resource configurations\nexport interface BaseConfigOptions {\n title?: string;\n createTitle?: string;\n createButtonLabel?: string;\n primaryResource: Resource;\n parentClass?: string;\n fieldClass?: string;\n elements: ConfigElement[];\n createConfig?: ConfigType;\n parentRelation?: {\n parentKey: FieldName;\n childKey: FieldName;\n };\n showBackButton?: boolean;\n createNavigation?: string[];\n}\nexport interface BaseConfig {\n title: string;\n createTitle: string;\n createButtonLabel: string;\n primaryResource: Resource;\n parentClass: string;\n fieldClass: string;\n elements: ConfigElement[];\n createConfig: ConfigType;\n parentRelation: {\n parentKey: FieldName;\n childKey: FieldName;\n };\n showBackButton: boolean;\n createNavigation: string[];\n}\n\n@Directive()\nexport abstract class CustomConfigComponent {\n uuid = input<string>();\n parentData = input<RecordData>();\n config = input<ComponentConfig>();\n}\n\n// Available param types for a component config\nexport type ConfigParam = SwitchConfigParam;\n\n// Custom component config renders a custom component and supplies params to it\nexport interface ComponentConfigOptions {\n // todo: it's weird that we have a primary resource here. Would be nice to remove but this adds a null check to all other configs\n primaryResource: Resource;\n component: Type<CustomConfigComponent> | 'SwitchResolver';\n params?: ConfigParam;\n relatedConfig?: ParentResourceConfig[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ComponentConfig {\n type: 'Component';\n primaryResource: Resource;\n component: Type<CustomConfigComponent> | 'SwitchResolver';\n params: ConfigParam;\n relatedConfig: ParentResourceConfig[];\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport function componentConfig(config: ComponentConfigOptions): ComponentConfig {\n return {\n ...componentConfigDefaults,\n ...config,\n } satisfies ComponentConfig;\n}\nexport const componentConfigDefaults = {\n type: 'Component',\n primaryResource: '' as Resource,\n component: 'SwitchResolver',\n params: {\n cases: [],\n } satisfies ConfigParam,\n relatedConfig: [] as ParentResourceConfig[],\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ComponentConfig;\n\n// A switch is a component type that allows for conditional rendering of child components based on the value of a parent field\n// When parentData[c.parentField] equals c.caseId render the caseConfig with parentData[c.childId] as the uuid\nexport interface switchCase {\n caseId: string;\n parentField: string;\n childId: string;\n config: ChildResourceConfig;\n}\nexport interface SwitchConfigParamOptions {\n cases: switchCase[];\n}\nexport interface SwitchConfigParam {\n cases: switchCase[];\n}\nexport function switchParams(config: SwitchConfigParamOptions): SwitchConfigParam {\n return {\n ...switchParamsDefaults,\n ...config,\n } satisfies SwitchConfigParam;\n}\nexport const switchParamsDefaults = {\n cases: [] as switchCase[],\n} satisfies SwitchConfigParam;\n\nexport interface ListViewConfigOptions extends BaseConfigOptions {\n showViewButton?: boolean;\n loadCreatedResource?: boolean;\n collapsible?: boolean;\n overrideResource?: Resource;\n searchable?: boolean;\n enableRowExpansion?: boolean;\n rowExpansionConfig?: ChildResourceConfig;\n requireSearchToDisplayResults?: boolean;\n listColumns: ColumnConfig[];\n relatedConfigs?: ChildResourceConfig[];\n viewResource?: Resource | string;\n actionType?: ActionType;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter?: (parentResource: any) => string;\n disableCacheForFilterPii?: boolean;\n rpcConfigs?: RPCConfig[];\n sorts?: FieldSort[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ListViewConfig extends BaseConfig {\n type: 'ListView';\n showViewButton: boolean;\n loadCreatedResource: boolean;\n collapsible: boolean;\n overrideResource: Resource;\n searchable: boolean;\n enableRowExpansion: boolean;\n rowExpansionConfig: ChildResourceConfig;\n requireSearchToDisplayResults: boolean;\n listColumns: ColumnConfig[];\n relatedConfigs: ChildResourceConfig[];\n viewResource: Resource | string;\n actionType: ActionType;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter: (parentResource: any) => string;\n disableCacheForFilterPii: boolean;\n rpcConfigs?: RPCConfig[];\n sorts: FieldSort[];\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\n\nexport function listViewConfig(config: ListViewConfigOptions): ListViewConfig {\n return {\n ...listViewConfigDefaults,\n ...config,\n } satisfies ListViewConfig;\n}\nexport const listViewConfigDefaults = {\n title: '',\n primaryResource: '' as Resource,\n type: 'ListView',\n createTitle: '',\n createButtonLabel: 'Create',\n loadCreatedResource: false,\n showViewButton: true,\n collapsible: false,\n listColumns: [],\n elements: [],\n parentClass: '',\n fieldClass: '',\n createConfig: {} as ListViewConfig,\n createNavigation: [],\n relatedConfigs: [],\n parentRelation: {\n parentKey: '' as FieldName,\n childKey: '' as FieldName,\n },\n overrideResource: '' as Resource,\n searchable: false,\n enableRowExpansion: false,\n rowExpansionConfig: {} as ChildResourceConfig,\n requireSearchToDisplayResults: false,\n showBackButton: true,\n filter: (): string => '',\n disableCacheForFilterPii: false,\n sorts: [] as FieldSort[],\n viewResource: '' as Resource,\n actionType: 'function' as ActionType,\n rpcConfigs: [],\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ListViewConfig;\n\nexport type ViewType = 'OneToOne' | 'OneToMany';\n\nexport interface ViewConfigOptions extends BaseConfigOptions {\n collapsible?: boolean;\n connectorResource?: Resource;\n relatedConfigs?: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ViewConfig extends BaseConfig {\n type: 'View';\n collapsible: boolean;\n // todo: remove this comment once full documentation has been added. Populate this value when a database view resource is used to connect the ViewConfig's parent resource to its primary resource\n connectorResource: Resource;\n rpcConfigs?: RPCConfig[];\n relatedConfigs: ChildResourceConfig[];\n /** A set of functions that allows for\n * conditional display of non-RPC\n * actions based on the pristine state of the resource\n * (if such a state is applicable. Creation for example won't\n * have such data)\n * This is separate from ABAC control which takes\n * precedence and is based on a user's attributes\n */\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\n\nexport function viewConfig(config: ViewConfigOptions): ViewConfig {\n return {\n ...viewConfigDefaults,\n ...config,\n } satisfies ViewConfig;\n}\nexport const viewConfigDefaults = {\n title: '',\n primaryResource: '' as Resource,\n type: 'View',\n createTitle: '',\n createButtonLabel: 'Create',\n parentClass: '',\n fieldClass: '',\n elements: [],\n collapsible: true,\n connectorResource: '' as Resource,\n relatedConfigs: [],\n createConfig: {} as ViewConfig,\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n createNavigation: [],\n parentRelation: {\n parentKey: '' as FieldName,\n childKey: '' as FieldName,\n },\n showBackButton: true,\n rpcConfigs: [],\n} satisfies ViewConfig;\n\nexport interface arrayConfigOptions {\n iteratedConfig: ChildResourceConfig;\n viewType?: ViewType;\n collapsible?: boolean;\n createConfig?: ConfigType;\n connectorResource?: Resource;\n connectorField?: FieldName;\n primaryResource: Resource;\n listFilter: (parentResource: any) => string;\n disableCacheForFilterPii?: boolean;\n sorts?: FieldSort[];\n title?: string;\n createButtonLabel?: string;\n limit?: number;\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ArrayConfig {\n type: 'Array';\n iteratedConfig: ChildResourceConfig;\n viewType: ViewType;\n collapsible: boolean;\n createConfig: ConfigType;\n connectorResource: Resource;\n connectorField: FieldName;\n primaryResource: Resource;\n listFilter: (parentResource: any) => string;\n disableCacheForFilterPii: boolean;\n sorts: FieldSort[];\n title: string;\n createButtonLabel: string;\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n limit: number;\n}\nexport function arrayConfig(config: arrayConfigOptions): ArrayConfig {\n return {\n ...arrayConfigDefaults,\n ...config,\n } satisfies ArrayConfig;\n}\nexport const arrayConfigDefaults = {\n type: 'Array',\n iteratedConfig: {} as ChildResourceConfig,\n viewType: 'OneToMany' as ViewType,\n collapsible: true,\n createConfig: {} as ViewConfig,\n connectorResource: '' as Resource,\n connectorField: '' as FieldName,\n primaryResource: '' as Resource,\n listFilter: (): string => '',\n disableCacheForFilterPii: false,\n sorts: [] as FieldSort[],\n title: '',\n createButtonLabel: 'Create',\n limit: Infinity,\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ArrayConfig;\n","export enum AlertLevel {\n ERROR = 'warn',\n INFO = 'accent',\n SUCCESS = 'success',\n}\n\nexport interface CreateNotificationMessage {\n duration?: number;\n message: string;\n link: string;\n level: AlertLevel;\n}\n\nexport interface NotificationMessage {\n id: number;\n duration?: number;\n message: string;\n link: string;\n level: AlertLevel;\n}\n","type Brand<K, T> = K & { __brand: T };\n\nexport type Permission = Brand<string, 'Permission'>;\nexport type Resource = Brand<string, 'Resource'>;\nexport type Domain = Brand<string, 'Domain'>;\nexport type FieldName = Brand<string, 'FieldName'>;\nexport type Method = Brand<string, 'Method'>;\nexport type DomainPermissions = Record<Domain, Record<Resource, Record<Permission, Permissions>>>;\n\nexport interface PermissionScope {\n resource: Resource;\n permission: Permission;\n domain: Domain;\n}\n\nexport const ReadPermission = 'Read' as Permission;\nexport const UpdatePermission = 'Update' as Permission;\n","import { InjectionToken } from '@angular/core';\nimport { Domain, Permission, Resource } from './permissions';\nimport { MethodMeta, ResourceMeta } from './resource-meta';\n\n/**\n * The base URL for API requests (e.g., 'https://api.example.com/').\n */\nexport const BASE_URL = new InjectionToken<string>('BASE_URL');\n\n/**\n * The path to the frontend login page (e.g., '/login').\n */\nexport const FRONTEND_LOGIN_PATH = new InjectionToken<string>('FRONTEND_LOGIN_PATH');\n\n/**\n * The path to the session endpoint (e.g., 'user/session').\n */\nexport const SESSION_PATH = new InjectionToken<string>('SESSION_PATH');\n\n/**\n * The base URL for API requests (e.g., '/api').\n */\nexport const API_URL = new InjectionToken<string>('API_URL');\n\nexport const PERMISSION_REQUIRED = new InjectionToken<(resource: Resource, permission: Permission) => boolean>(\n 'PERMISSION_REQUIRED',\n);\n\nexport const AVAILABLE_PERMISSIONS = new InjectionToken<{\n Create: Permission;\n Delete: Permission;\n List: Permission;\n Read: Permission;\n Update: Permission;\n}>('AVAILABLE_PERMISSIONS');\nexport const AVAILABLE_DOMAINS = new InjectionToken<Record<string, Domain>[]>('AVAILABLE_DOMAINS');\n\nexport const RESOURCE_META = new InjectionToken<(resource: Resource) => ResourceMeta>('RESOURCE_META');\nexport const METHOD_META = new InjectionToken<(method: string) => MethodMeta>('METHOD_META');\n\nexport const IDLE_SESSION_DURATION = new InjectionToken<number>('IDLE_SESSION_DURATION');\nexport const IDLE_WARNING_DURATION = new InjectionToken<number>('IDLE_WARNING_DURATION');\nexport const IDLE_KEEPALIVE_DURATION = new InjectionToken<number>('IDLE_KEEPALIVE_DURATION');\n","import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nexport const validatorsPresent = (\n control: AbstractControl<unknown, unknown>,\n validators: ValidatorFn[],\n previousValidatorCount: number,\n): boolean => {\n if (validators.length === previousValidatorCount) {\n return true;\n }\n\n let hasAllValidators = true;\n for (const validator of validators) {\n if (!control.hasValidator(validator)) {\n hasAllValidators = false;\n break;\n }\n }\n return hasAllValidators;\n};\n\nexport const requiredIf = (predicate: () => boolean, validator: ValidatorFn) => {\n return (formControl: AbstractControl): ValidationErrors | null => {\n if (!formControl.parent) {\n return null;\n }\n if (predicate()) {\n return validator(formControl);\n }\n return null;\n };\n};\n\ndeclare const __singletonValidatorBrand: unique symbol;\nexport type ResourceValidatorFn = ValidatorFn & {\n readonly [__singletonValidatorBrand]: true;\n};\nexport function createResourceValidator(validator: ValidatorFn): ResourceValidatorFn {\n return validator as ResourceValidatorFn;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cccteam-ccc-lib-types.mjs","sources":["../../../projects/ccc-lib/types/resource-types.ts","../../../projects/ccc-lib/types/configs.ts","../../../projects/ccc-lib/types/notification-message.ts","../../../projects/ccc-lib/types/permissions.ts","../../../projects/ccc-lib/types/tokens.ts","../../../projects/ccc-lib/types/validators.ts","../../../projects/ccc-lib/types/cccteam-ccc-lib-types.ts"],"sourcesContent":["export const defaultEmptyFieldValue = '-';\n\nexport type NullBoolean = null | true | false;\n\nexport type ConcatFn = 'space-concat' | 'hyphen-concat' | 'space-hyphen-concat' | 'hyphen-space-concat';\n","import { Directive, input, Type } from '@angular/core';\nimport { TooltipPosition } from '@angular/material/tooltip';\nimport { FieldName, Method, Resource } from './permissions';\nimport { ResourceMeta } from './resource-meta';\nimport { ConcatFn, defaultEmptyFieldValue, NullBoolean } from './resource-types';\nimport { ResourceValidatorFn } from './validators';\n\nexport type ResourceMap = Record<Resource, ResourceMeta>;\n\nexport interface FieldPointer {\n field: FieldName;\n}\n\nexport interface MenuItem {\n label: string;\n route?: string[];\n children?: MenuItem[];\n}\n\nexport interface RouteResourceData {\n config: RootConfig;\n}\n\nexport type DataType = string | number | number[] | string[] | boolean | undefined | Date;\nexport type RecordData = Record<string, DataType | null>;\n\nexport type RPCDataType = string | number | string[] | number[] | boolean | Date;\nexport type RPCRecordData = Record<string, RPCDataType>;\nexport type RpcMethod = Record<string, DataType>;\n\nexport type ParentResourceConfig = ListViewConfig | ViewConfig | ArrayConfig;\nexport type ChildResourceConfig = ListViewConfig | ViewConfig | ComponentConfig | ArrayConfig;\n\nexport type ActionType = 'function' | 'link';\n\nexport type ListConcatFn =\n | 'space-concat'\n | 'hyphen-concat'\n | 'space-hyphen-concat'\n | 'hyphen-space-concat'\n | 'no-space-concat';\nexport type ConfigType = ChildResourceConfig;\nexport type FormatType = 'simpleSlashDateFormat';\nexport type RPCPlacement = 'inline' | 'end';\n\nexport type ColumnConfig = SingleColumnConfig | MultiColumnConfig;\n\nexport interface ActionButtonConfig {\n label: string;\n icon: string;\n action?: (resource: { id: string }) => void;\n viewRoute?: string;\n actionType?: ActionType;\n color?: string;\n disabledLabel?: string;\n}\nexport interface ActionButtonConfigOptions {\n label: string;\n icon: string;\n action?: (resource: { id: string }) => void;\n viewRoute?: string;\n actionType?: ActionType;\n color?: string;\n disabledLabel?: string;\n}\n\nexport function actionButtonConfig(config: ActionButtonConfigOptions): ActionButtonConfig {\n return {\n ...actionButtonConfigDefaults,\n ...config,\n } satisfies ActionButtonConfig;\n}\n\nexport const actionButtonConfigDefaults = {\n label: '',\n icon: '',\n actionType: 'function' as ActionType,\n color: '',\n disabledLabel: '',\n} satisfies ActionButtonConfig;\n\nexport interface SingleColumnConfig {\n id: FieldName;\n header?: string;\n width?: number;\n resizable?: boolean;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n valueGetter?: (data: any) => string;\n valueFormatter?: (data: any) => string;\n tooltipPosition?: TooltipPosition;\n viewRoute?: Resource;\n buttonConfig?: ActionButtonConfig;\n actionType?: ActionType;\n formatType?: FormatType | string;\n hidden?: boolean;\n emptyDataValue?: DataType;\n filterable?: boolean;\n hideHeader?: boolean;\n}\nexport interface SingleColumnConfigOptions {\n id: FieldName;\n header?: string;\n width?: number;\n resizable?: boolean;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n valueGetter?: (data: any) => string;\n valueFormatter?: (data: any) => string;\n tooltipPosition?: TooltipPosition;\n viewRoute?: Resource;\n buttonConfig?: ActionButtonConfig;\n actionType?: ActionType;\n formatType?: FormatType | string;\n hidden?: boolean;\n emptyDataValue?: DataType;\n filterable?: boolean;\n hideHeader?: boolean;\n}\n\nexport function singleColumnConfig(config: SingleColumnConfigOptions): SingleColumnConfig {\n return {\n ...singleColumnConfigDefaults,\n ...config,\n } satisfies SingleColumnConfig;\n}\n\nexport const singleColumnConfigDefaults = {\n id: '' as FieldName,\n header: '',\n resizable: true,\n actionType: 'function' as ActionType,\n hidden: false,\n filterable: true,\n hideHeader: false,\n} satisfies SingleColumnConfig;\n\nexport interface MultiColumnConfig extends SingleColumnConfig {\n // todo: additionalIds name is not clear. the id provided is fetched from a different resource, such as a typeId\n additionalIds: AdditionalResourceConfig[];\n concatFn: ListConcatFn;\n}\nexport interface MultiColumnConfigOptions extends SingleColumnConfigOptions {\n additionalIds: AdditionalResourceConfig[];\n concatFn: ListConcatFn;\n}\n\nexport function multiColumnConfig(config: MultiColumnConfigOptions): MultiColumnConfig {\n return {\n ...multiColumnConfigDefaults,\n ...config,\n } satisfies MultiColumnConfig;\n}\n\nexport const multiColumnConfigDefaults = {\n ...singleColumnConfigDefaults,\n additionalIds: [] as AdditionalResourceConfig[],\n concatFn: 'hyphen-concat' as ListConcatFn,\n} satisfies MultiColumnConfig;\n\nexport interface AdditionalResourceConfig {\n resource?: Resource;\n id: FieldName;\n field?: FieldName;\n hidden?: boolean;\n}\nexport interface AdditionalResourceConfigOptions {\n id: FieldName;\n resource?: Resource;\n field?: FieldName;\n hidden?: boolean;\n}\n\nexport function additionalResourceConfig(config: AdditionalResourceConfigOptions): AdditionalResourceConfig {\n return {\n ...additionalResourceConfigDefaults,\n ...config,\n } satisfies AdditionalResourceConfig;\n}\n\nexport const additionalResourceConfigDefaults = {\n id: '' as FieldName,\n resource: '' as Resource,\n field: '' as FieldName,\n hidden: false,\n} satisfies AdditionalResourceConfig;\n\nexport interface FieldSort {\n field: FieldName;\n direction: 'asc' | 'desc';\n}\nexport interface FieldSortOptions {\n field: FieldName;\n direction?: 'asc' | 'desc';\n}\n\nexport function fieldSort(config: FieldSortOptions): FieldSort {\n return {\n ...fieldSortDefaults,\n ...config,\n } satisfies FieldSort;\n}\n\nexport const fieldSortDefaults = {\n field: '' as FieldName,\n direction: 'asc' as 'asc' | 'desc',\n} satisfies FieldSort;\n\nexport interface EnumeratedConfigOptions {\n // primaryResource comes from the metadata\n overrideResource?: Resource;\n /* A function to filter the list of enumerated options.\n * The `parentResource` argument contains the data of the resource that this enumerated field is part of.\n * It will be an object with the current form values, which can be empty during resource creation.\n */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter?: (resource: any) => string;\n /**\n * Set disableCacheForFilterPii to `true` to promote the GET to a POST when PII is used in the filter\n * POST requests cannot be cached\n */\n disableCacheForFilterPii?: boolean;\n /**\n * Specifies which resource data to pass to the filter function:\n * - 'rootResource': Pass in the root resource data\n * - 'parentResource': Pass in the parent resource data\n * @default 'parentResource'\n */\n filterType?: FilterType;\n sorts?: FieldSort[];\n listDisplay?: FieldName[];\n viewDisplay: FieldName[];\n viewConcatFn?: ConcatFn;\n listConcatFn?: ConcatFn;\n viewDetails?: boolean;\n searchable?: boolean;\n}\n\ntype FilterType = 'parentResource' | 'rootResource';\nexport interface EnumeratedConfig {\n overrideResource: Resource;\n filter: (resource: any) => string;\n disableCacheForFilterPii: boolean;\n filterType: FilterType;\n sorts: FieldSort[];\n listDisplay: FieldName[];\n viewDisplay: FieldName[];\n viewConcatFn: ConcatFn;\n listConcatFn: ConcatFn;\n viewDetails: boolean;\n searchable: boolean;\n}\nexport function enumeratedConfig(config: EnumeratedConfigOptions): EnumeratedConfig {\n return {\n ...enumeratedConfigDefaults,\n ...config,\n } satisfies EnumeratedConfig;\n}\nexport const enumeratedConfigDefaults = {\n overrideResource: '' as Resource,\n filter: (): string => '',\n disableCacheForFilterPii: false,\n filterType: 'parentResource' as FilterType,\n sorts: [] as FieldSort[],\n listDisplay: [] as FieldName[],\n viewDisplay: [] as FieldName[],\n viewConcatFn: 'hyphen-concat' as ConcatFn,\n listConcatFn: 'hyphen-concat' as ConcatFn,\n viewDetails: false,\n searchable: false,\n};\n\nexport type FieldDefault = ForeignKeyDefault | StaticDefault | null;\n\nexport interface NullBooleanConfigOptions {\n displayValues?: Record<'null' | 'true' | 'false', { label: string; value: NullBoolean }>;\n}\nexport interface NullBooleanConfig {\n /** This property maps the three possible values for this\n * nullboolean field with the display values users will see\n * on the screen for each\n */\n displayValues: Record<'null' | 'true' | 'false', { label: string; value: NullBoolean }>;\n}\nexport function nullBooleanConfig(config: NullBooleanConfigOptions): NullBooleanConfig {\n return {\n ...nullBooleanConfigDefaults,\n ...config,\n } satisfies NullBooleanConfig;\n}\nconst defaultBooleanDisplay = Object.freeze({\n null: {\n label: defaultEmptyFieldValue,\n value: null,\n },\n true: {\n label: 'Yes',\n value: true,\n },\n false: {\n label: 'No',\n value: false,\n },\n});\n\nexport const nullBooleanConfigDefaults = {\n displayValues: defaultBooleanDisplay,\n};\n\nexport interface ForeignKeyDefaultOptions {\n parentId: FieldName;\n}\nexport interface ForeignKeyDefault {\n type: 'foreignKey';\n parentId: FieldName;\n}\nexport function foreignKeyDefault(config: ForeignKeyDefaultOptions): ForeignKeyDefault {\n return {\n ...foreignKeyDefaultDefaults,\n ...config,\n } satisfies ForeignKeyDefault;\n}\nexport const foreignKeyDefaultDefaults = {\n type: 'foreignKey',\n parentId: '' as FieldName,\n} satisfies ForeignKeyDefault;\n\nexport interface StaticDefault {\n type: 'static';\n value: string | boolean;\n}\nexport interface staticDefaultOptions {\n value: string | boolean;\n}\nexport function staticDefault(config: staticDefaultOptions): StaticDefault {\n return {\n ...staticDefaultDefaults,\n ...config,\n } satisfies StaticDefault;\n}\nexport const staticDefaultDefaults = {\n type: 'static',\n value: '',\n} satisfies StaticDefault;\n\nexport type Affix = string | remoteData | parentData;\n\ninterface remoteData {\n resource: Resource;\n id: FieldName;\n field: FieldName;\n}\n\ninterface parentData {\n field: FieldName;\n}\n\nexport type ConfigElement = FieldElement | SectionElement | ComputedDisplayFieldElement | PaddingElement;\n\nexport type ColSize = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\n\nexport interface ComputedDisplayFieldElementOptions {\n label?: string;\n class?: string;\n cols?: ColSize;\n calculatedValue?: (data: any) => string;\n shouldRender?: ((data: any) => boolean) | boolean;\n}\nexport interface ComputedDisplayFieldElement {\n type: 'computedDisplayField';\n label: string;\n class: string;\n cols: ColSize;\n calculatedValue: (data: any) => string;\n shouldRender: ((data: any) => boolean) | boolean;\n}\nexport function computedDisplayField(config: ComputedDisplayFieldElementOptions): ComputedDisplayFieldElement {\n return {\n ...computedDisplayFieldElementDefaults,\n ...config,\n } satisfies ComputedDisplayFieldElement;\n}\nexport const computedDisplayFieldElementDefaults = {\n type: 'computedDisplayField',\n label: '',\n class: '',\n cols: 6,\n calculatedValue: (): string => '',\n shouldRender: true,\n} satisfies ComputedDisplayFieldElement;\n\nexport interface PaddingElementOptions {\n cols?: ColSize;\n shouldRender?: ((data: any) => boolean) | boolean;\n}\nexport interface PaddingElement {\n type: 'padding';\n cols: ColSize;\n /** Determines whether the padding is shown\n */\n shouldRender: ((data: any) => boolean) | boolean;\n}\nexport function padding(config?: PaddingElementOptions): PaddingElement {\n return {\n ...paddingElementDefaults,\n ...config,\n } satisfies PaddingElement;\n}\nexport const paddingElementDefaults = {\n type: 'padding',\n cols: 12,\n shouldRender: true,\n} satisfies PaddingElement;\n\nexport interface SectionElementOptions {\n label?: string;\n class?: string;\n cols?: ColSize;\n shouldRender?: ((data: any) => boolean) | boolean;\n nullAllChildrenIfConditionallyHidden?: boolean;\n children?: ConfigElement[];\n}\nexport interface SectionElement {\n type: 'section';\n label: string;\n class: string;\n cols: ColSize;\n /**\n * shouldRender is used to determine if the section should be\n * displayed to users.\n * When assigning shouldRender a function, the first argument\n * is the current state of the resource being displayed\n * Hides the layout AND all of its children\n */\n shouldRender: ((data: any) => boolean) | boolean;\n /** If shouldRender is NOT a function, this property does nothing\n * If shouldRender is a function, this property\n * sets children's values to null if shouldRender hides it (returns false)\n * within the resource-layout.component\n */\n nullAllChildrenIfConditionallyHidden: boolean;\n children: ConfigElement[];\n}\nexport function section(config: SectionElementOptions): SectionElement {\n return {\n ...sectionElementDefaults,\n ...config,\n } satisfies SectionElement;\n}\nexport const sectionElementDefaults = {\n type: 'section',\n label: '',\n class: '',\n cols: 12,\n shouldRender: true,\n nullAllChildrenIfConditionallyHidden: false,\n children: [],\n} satisfies SectionElement;\n\nexport interface FieldElementOptions {\n name: FieldName;\n label?: string;\n cols?: ColSize;\n class?: string;\n enumeratedConfig?: EnumeratedConfig;\n default?: FieldDefault;\n nullBooleanConfig?: NullBooleanConfig;\n validators?: ((data: any) => ResourceValidatorFn[]) | ResourceValidatorFn[];\n readOnly?: boolean;\n prefixes?: Affix[];\n suffixes?: Affix[];\n shouldRender?: ((data: any) => boolean) | boolean;\n nullIfConditionallyHidden?: boolean;\n}\nexport interface FieldElement {\n type: 'field';\n name: string;\n label: string;\n cols: ColSize;\n class: string;\n enumeratedConfig: EnumeratedConfig;\n default: FieldDefault;\n nullBooleanConfig: NullBooleanConfig;\n /**\n * A list of validators that must pass to allow a field to be submitted.\n * Utilize existing validators in the resourceValidators object, and\n * add any new or custom validators to it\n */\n validators: ((data: any) => ResourceValidatorFn[]) | ResourceValidatorFn[];\n readOnly: boolean;\n prefixes: Affix[];\n suffixes: Affix[];\n /**\n * shouldRender is used to determine if the element should be\n * displayed to users.\n * When assigning shouldRender a function, the first argument\n * is the current state of the resource being displayed\n */\n shouldRender: ((data: any) => boolean) | boolean;\n /** If shouldRender is NOT a function, this property does nothing\n * If shouldRender is a function, this property\n * determines whether the form control associated\n * with this config element should have its value\n * set to null if shouldRender hides it (returns false)\n */\n nullIfConditionallyHidden: boolean;\n}\n\nexport function field(config: FieldElementOptions): FieldElement {\n return {\n ...fieldElementDefaults,\n ...config,\n } satisfies FieldElement;\n}\nexport const fieldElementDefaults = {\n type: 'field',\n name: '',\n label: '',\n cols: 6,\n class: '',\n enumeratedConfig: { ...enumeratedConfigDefaults },\n default: null,\n validators: [],\n nullBooleanConfig: { ...nullBooleanConfigDefaults },\n readOnly: false,\n prefixes: [],\n suffixes: [],\n shouldRender: true,\n nullIfConditionallyHidden: false,\n} satisfies FieldElement;\n\n/**\n * RouteData is used to define the route for a config\n * route: the route for the config\n * hasViewRoute: when true, a route will be created for route/:uuid\n */\nexport interface RootRouteData {\n route?: string;\n hasViewRoute?: boolean;\n}\n\nexport interface RPCConfigOptions {\n label: string;\n afterMethodRedirect?: string;\n conditions: {\n field: FieldName;\n matchValues: string[];\n }[];\n methodBodyTemplate?: any;\n successMessage?: string;\n elements?: ConfigElement[];\n placement?: RPCPlacement;\n method: Method;\n customComponent?: ComponentConfig;\n refreshResources?: Resource[];\n defaultModalWidth?: string;\n shouldRender?: () => boolean;\n}\nexport interface RPCConfig {\n label: string;\n afterMethodRedirect: string | string[];\n conditions: {\n field: FieldName;\n matchValues: string[];\n }[];\n methodBodyTemplate: any;\n method: Method;\n successMessage: string;\n elements: ConfigElement[];\n placement: RPCPlacement;\n customComponent: ComponentConfig;\n refreshResources: Resource[];\n defaultModalWidth: string;\n shouldRender: () => boolean;\n}\nexport function rpcConfig(config: RPCConfigOptions): RPCConfig {\n return {\n ...rpcConfigDefaults,\n ...config,\n } satisfies RPCConfig;\n}\nexport const rpcConfigDefaults = {\n label: '',\n afterMethodRedirect: '',\n conditions: [] as {\n field: FieldName;\n matchValues: string[];\n }[],\n methodBodyTemplate: {} as any,\n successMessage: '',\n elements: [] as ConfigElement[],\n placement: 'end' as RPCPlacement,\n method: '' as Method,\n customComponent: {} as ComponentConfig,\n refreshResources: [] as Resource[],\n defaultModalWidth: '',\n shouldRender: (): boolean => true,\n} satisfies RPCConfig;\n\nexport interface RPCBaseFormData {\n elements: FieldElement[];\n label: string;\n method: Method;\n}\n\n// Config is the base type that all configurations should start with\nexport interface RootConfigOptions {\n routeData?: RootRouteData;\n nav?: {\n navItem: MenuItem;\n group?: string;\n };\n parentConfig: ParentResourceConfig;\n relatedConfigs?: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n}\nexport interface RootConfig {\n routeData: RootRouteData;\n nav: {\n navItem: MenuItem;\n group?: string;\n };\n parentConfig: ParentResourceConfig;\n relatedConfigs: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n}\nexport const rootConfigDefaults = {\n routeData: {} as RootRouteData,\n nav: {\n navItem: {} as MenuItem,\n },\n parentConfig: {} as ParentResourceConfig,\n relatedConfigs: [] as ChildResourceConfig[],\n rpcConfigs: [] as RPCConfig[],\n} satisfies RootConfig;\n\nexport function rootConfig(config: RootConfigOptions): RootConfig {\n return {\n ...rootConfigDefaults,\n ...config,\n } satisfies RootConfig;\n}\n\n// Base type config is the base type for all resource configurations\nexport interface BaseConfigOptions {\n title?: string;\n createTitle?: string;\n createButtonLabel?: string;\n primaryResource: Resource;\n parentClass?: string;\n fieldClass?: string;\n elements: ConfigElement[];\n createConfig?: ConfigType;\n parentRelation?: {\n parentKey: FieldName;\n childKey: FieldName;\n };\n showBackButton?: boolean;\n createNavigation?: string[];\n}\nexport interface BaseConfig {\n title: string;\n createTitle: string;\n createButtonLabel: string;\n primaryResource: Resource;\n parentClass: string;\n fieldClass: string;\n elements: ConfigElement[];\n createConfig: ConfigType;\n parentRelation: {\n parentKey: FieldName;\n childKey: FieldName;\n };\n showBackButton: boolean;\n createNavigation: string[];\n}\n\n@Directive()\nexport abstract class CustomConfigComponent {\n uuid = input<string>();\n parentData = input<RecordData>();\n config = input<ComponentConfig>();\n}\n\n// Available param types for a component config\nexport type ConfigParam = SwitchConfigParam;\n\n// Custom component config renders a custom component and supplies params to it\nexport interface ComponentConfigOptions {\n // todo: it's weird that we have a primary resource here. Would be nice to remove but this adds a null check to all other configs\n primaryResource: Resource;\n component: Type<CustomConfigComponent> | 'SwitchResolver';\n params?: ConfigParam;\n relatedConfig?: ParentResourceConfig[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ComponentConfig {\n type: 'Component';\n primaryResource: Resource;\n component: Type<CustomConfigComponent> | 'SwitchResolver';\n params: ConfigParam;\n relatedConfig: ParentResourceConfig[];\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport function componentConfig(config: ComponentConfigOptions): ComponentConfig {\n return {\n ...componentConfigDefaults,\n ...config,\n } satisfies ComponentConfig;\n}\nexport const componentConfigDefaults = {\n type: 'Component',\n primaryResource: '' as Resource,\n component: 'SwitchResolver',\n params: {\n cases: [],\n } satisfies ConfigParam,\n relatedConfig: [] as ParentResourceConfig[],\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ComponentConfig;\n\n// A switch is a component type that allows for conditional rendering of child components based on the value of a parent field\n// When parentData[c.parentField] equals c.caseId render the caseConfig with parentData[c.childId] as the uuid\nexport interface switchCase {\n caseId: string;\n parentField: string;\n childId: string;\n config: ChildResourceConfig;\n}\nexport interface SwitchConfigParamOptions {\n cases: switchCase[];\n}\nexport interface SwitchConfigParam {\n cases: switchCase[];\n}\nexport function switchParams(config: SwitchConfigParamOptions): SwitchConfigParam {\n return {\n ...switchParamsDefaults,\n ...config,\n } satisfies SwitchConfigParam;\n}\nexport const switchParamsDefaults = {\n cases: [] as switchCase[],\n} satisfies SwitchConfigParam;\n\nexport interface ListViewConfigOptions extends BaseConfigOptions {\n showViewButton?: boolean;\n loadCreatedResource?: boolean;\n collapsible?: boolean;\n overrideResource?: Resource;\n searchable?: boolean;\n enableRowExpansion?: boolean;\n rowExpansionConfig?: ChildResourceConfig;\n requireSearchToDisplayResults?: boolean;\n listColumns: ColumnConfig[];\n relatedConfigs?: ChildResourceConfig[];\n viewResource?: Resource | string;\n actionType?: ActionType;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter?: (parentResource: any) => string;\n disableCacheForFilterPii?: boolean;\n rpcConfigs?: RPCConfig[];\n sorts?: FieldSort[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ListViewConfig extends BaseConfig {\n type: 'ListView';\n showViewButton: boolean;\n loadCreatedResource: boolean;\n collapsible: boolean;\n overrideResource: Resource;\n searchable: boolean;\n enableRowExpansion: boolean;\n rowExpansionConfig: ChildResourceConfig;\n requireSearchToDisplayResults: boolean;\n listColumns: ColumnConfig[];\n relatedConfigs: ChildResourceConfig[];\n viewResource: Resource | string;\n actionType: ActionType;\n /* eslint-disable @typescript-eslint/no-explicit-any */\n filter: (parentResource: any) => string;\n disableCacheForFilterPii: boolean;\n rpcConfigs?: RPCConfig[];\n sorts: FieldSort[];\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\n\nexport function listViewConfig(config: ListViewConfigOptions): ListViewConfig {\n return {\n ...listViewConfigDefaults,\n ...config,\n } satisfies ListViewConfig;\n}\nexport const listViewConfigDefaults = {\n title: '',\n primaryResource: '' as Resource,\n type: 'ListView',\n createTitle: '',\n createButtonLabel: 'Create',\n loadCreatedResource: false,\n showViewButton: true,\n collapsible: false,\n listColumns: [],\n elements: [],\n parentClass: '',\n fieldClass: '',\n createConfig: {} as ListViewConfig,\n createNavigation: [],\n relatedConfigs: [],\n parentRelation: {\n parentKey: '' as FieldName,\n childKey: '' as FieldName,\n },\n overrideResource: '' as Resource,\n searchable: false,\n enableRowExpansion: false,\n rowExpansionConfig: {} as ChildResourceConfig,\n requireSearchToDisplayResults: false,\n showBackButton: true,\n filter: (): string => '',\n disableCacheForFilterPii: false,\n sorts: [] as FieldSort[],\n viewResource: '' as Resource,\n actionType: 'function' as ActionType,\n rpcConfigs: [],\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ListViewConfig;\n\nexport type ViewType = 'OneToOne' | 'OneToMany';\n\nexport interface ViewConfigOptions extends BaseConfigOptions {\n collapsible?: boolean;\n connectorResource?: Resource;\n relatedConfigs?: ChildResourceConfig[];\n rpcConfigs?: RPCConfig[];\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ViewConfig extends BaseConfig {\n type: 'View';\n collapsible: boolean;\n // todo: remove this comment once full documentation has been added. Populate this value when a database view resource is used to connect the ViewConfig's parent resource to its primary resource\n connectorResource: Resource;\n rpcConfigs?: RPCConfig[];\n relatedConfigs: ChildResourceConfig[];\n /** A set of functions that allows for\n * conditional display of non-RPC\n * actions based on the pristine state of the resource\n * (if such a state is applicable. Creation for example won't\n * have such data)\n * This is separate from ABAC control which takes\n * precedence and is based on a user's attributes\n */\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\n\nexport function viewConfig(config: ViewConfigOptions): ViewConfig {\n return {\n ...viewConfigDefaults,\n ...config,\n } satisfies ViewConfig;\n}\nexport const viewConfigDefaults = {\n title: '',\n primaryResource: '' as Resource,\n type: 'View',\n createTitle: '',\n createButtonLabel: 'Create',\n parentClass: '',\n fieldClass: '',\n elements: [],\n collapsible: true,\n connectorResource: '' as Resource,\n relatedConfigs: [],\n createConfig: {} as ViewConfig,\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n createNavigation: [],\n parentRelation: {\n parentKey: '' as FieldName,\n childKey: '' as FieldName,\n },\n showBackButton: true,\n rpcConfigs: [],\n} satisfies ViewConfig;\n\nexport interface arrayConfigOptions {\n iteratedConfig: ChildResourceConfig;\n viewType?: ViewType;\n collapsible?: boolean;\n createConfig?: ConfigType;\n connectorResource?: Resource;\n connectorField?: FieldName;\n primaryResource: Resource;\n listFilter: (parentResource: any) => string;\n disableCacheForFilterPii?: boolean;\n sorts?: FieldSort[];\n title?: string;\n createButtonLabel?: string;\n limit?: number;\n shouldRenderActions?: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n}\nexport interface ArrayConfig {\n type: 'Array';\n iteratedConfig: ChildResourceConfig;\n viewType: ViewType;\n collapsible: boolean;\n createConfig: ConfigType;\n connectorResource: Resource;\n connectorField: FieldName;\n primaryResource: Resource;\n listFilter: (parentResource: any) => string;\n disableCacheForFilterPii: boolean;\n sorts: FieldSort[];\n title: string;\n createButtonLabel: string;\n shouldRenderActions: Record<'edit' | 'delete' | 'create', (data: any) => boolean>;\n limit: number;\n}\nexport function arrayConfig(config: arrayConfigOptions): ArrayConfig {\n return {\n ...arrayConfigDefaults,\n ...config,\n } satisfies ArrayConfig;\n}\nexport const arrayConfigDefaults = {\n type: 'Array',\n iteratedConfig: {} as ChildResourceConfig,\n viewType: 'OneToMany' as ViewType,\n collapsible: true,\n createConfig: {} as ViewConfig,\n connectorResource: '' as Resource,\n connectorField: '' as FieldName,\n primaryResource: '' as Resource,\n listFilter: (): string => '',\n disableCacheForFilterPii: false,\n sorts: [] as FieldSort[],\n title: '',\n createButtonLabel: 'Create',\n limit: Infinity,\n shouldRenderActions: {\n create: (): boolean => true,\n edit: (): boolean => true,\n delete: (): boolean => true,\n },\n} satisfies ArrayConfig;\n","export enum AlertLevel {\n ERROR = 'warn',\n INFO = 'accent',\n SUCCESS = 'success',\n}\n\nexport interface CreateNotificationMessage {\n duration?: number;\n message: string;\n link: string;\n level: AlertLevel;\n}\n\nexport interface NotificationMessage {\n id: number;\n duration?: number;\n message: string;\n link: string;\n level: AlertLevel;\n}\n","type Brand<K, T> = K & { __brand: T };\n\nexport type Permission = Brand<string, 'Permission'>;\nexport type Resource = Brand<string, 'Resource'>;\nexport type Domain = Brand<string, 'Domain'>;\nexport type FieldName = Brand<string, 'FieldName'>;\nexport type Method = Brand<string, 'Method'>;\nexport type DomainPermissions = Record<Domain, Record<Resource, Record<Permission, Permissions>>>;\n\nexport interface PermissionScope {\n resource: Resource;\n permission: Permission;\n domain: Domain;\n}\n\nexport const ReadPermission = 'Read' as Permission;\nexport const UpdatePermission = 'Update' as Permission;\n","import { InjectionToken } from '@angular/core';\nimport { Domain, Permission, Resource } from './permissions';\nimport { MethodMeta, ResourceMeta } from './resource-meta';\n\n/**\n * The base URL for API requests (e.g., 'https://api.example.com/').\n * @defaultValue '/'\n */\nexport const BASE_URL = new InjectionToken<string>('BASE_URL', { factory: () => '/' });\n\n/**\n * The path to the frontend login page (e.g., '/login').\n * @defaultValue '/login'\n */\nexport const FRONTEND_LOGIN_PATH = new InjectionToken<string>('FRONTEND_LOGIN_PATH', { factory: () => '/login' });\n\n/**\n * The path to the session endpoint (e.g., 'user/session').\n * @defaultValue 'user/session'\n */\nexport const SESSION_PATH = new InjectionToken<string>('SESSION_PATH', { factory: () => 'user/session' });\n\n/**\n * The base URL for API requests (e.g., '/api').\n * @defaultValue '/api'\n */\nexport const API_URL = new InjectionToken<string>('API_URL', { factory: () => '/api' });\n\n/**\n * A function to determine if a specific permission is required for a given resource.\n * @defaultValue a function that always returns false\n */\nexport const PERMISSION_REQUIRED = new InjectionToken<(resource: Resource, permission: Permission) => boolean>(\n 'PERMISSION_REQUIRED',\n { factory: () => () => false },\n);\n\n/**\n * The available permissions in the system.\n * @defaultValue an empty array\n */\nexport const AVAILABLE_PERMISSIONS = new InjectionToken<{\n Create: Permission;\n Delete: Permission;\n List: Permission;\n Read: Permission;\n Update: Permission;\n}>('AVAILABLE_PERMISSIONS');\nexport const AVAILABLE_DOMAINS = new InjectionToken<Record<string, Domain>[]>('AVAILABLE_DOMAINS', {\n factory: () => [],\n});\n\n/**\n * The generated resourceMeta from the output of the [ccc package](https://github.com/cccteam/ccc) typescript generator\n * Required to work with generated routes and resource metadata\n * @defaultValue a no-op function that returns an empty object\n */\nexport const RESOURCE_META = new InjectionToken<(resource: Resource) => ResourceMeta>('RESOURCE_META', {\n factory: () => () => ({}) as ResourceMeta,\n});\n\n/**\n * The generated methodMeta from the output of the [ccc package](https://github.com/cccteam/ccc) typescript generator\n * Required to work with generated method data\n * @defaultValue a no-op function that returns an empty object\n */\nexport const METHOD_META = new InjectionToken<(method: string) => MethodMeta>('METHOD_META', {\n factory: () => () => ({}) as MethodMeta,\n});\n\n/**\n * The duration in seconds for the session to be considered idle.\n * @defaultValue 300 seconds\n */\nexport const IDLE_SESSION_DURATION = new InjectionToken<number>('IDLE_SESSION_DURATION', { factory: () => 300 });\n\n/**\n * The duration in seconds for the warning to be shown to the user before the session times out due to inactivity.\n * @defaultValue 60 seconds\n */\nexport const IDLE_WARNING_DURATION = new InjectionToken<number>('IDLE_WARNING_DURATION', { factory: () => 60 });\n\n/**\n * The duration in seconds for the keepalive ping to be sent to the server to keep the session alive.\n * @defaultValue 30 seconds\n */\nexport const IDLE_KEEPALIVE_DURATION = new InjectionToken<number>('IDLE_KEEPALIVE_DURATION', { factory: () => 30 });\n\n/**\n * A function to be called when the user logs out.\n * @defaultValue a no-op function that returns 0\n */\nexport const LOGOUT_ACTION = new InjectionToken<() => void>('LOGOUT_ACTION', { factory: () => () => 0 });\n\n/**\n * A function to be called when the user is logged out due to inactivity.\n * @defaultValue a no-op function that returns 0\n */\nexport const IDLE_LOGOUT_ACTION = new InjectionToken<() => void>('IDLE_LOGOUT_ACTION', {\n factory: () => () => 0,\n});\n","import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nexport const validatorsPresent = (\n control: AbstractControl<unknown, unknown>,\n validators: ValidatorFn[],\n previousValidatorCount: number,\n): boolean => {\n if (validators.length === previousValidatorCount) {\n return true;\n }\n\n let hasAllValidators = true;\n for (const validator of validators) {\n if (!control.hasValidator(validator)) {\n hasAllValidators = false;\n break;\n }\n }\n return hasAllValidators;\n};\n\nexport const requiredIf = (predicate: () => boolean, validator: ValidatorFn) => {\n return (formControl: AbstractControl): ValidationErrors | null => {\n if (!formControl.parent) {\n return null;\n }\n if (predicate()) {\n return validator(formControl);\n }\n return null;\n };\n};\n\ndeclare const __singletonValidatorBrand: unique symbol;\nexport type ResourceValidatorFn = ValidatorFn & {\n readonly [__singletonValidatorBrand]: true;\n};\nexport function createResourceValidator(validator: ValidatorFn): ResourceValidatorFn {\n return validator as ResourceValidatorFn;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -27,10 +27,10 @@ class AlertComponent {
|
|
|
27
27
|
this.errors.dismissGlobalNotification(this.error);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
31
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: AlertComponent, isStandalone: true, selector: "ccc-alert", inputs: { error: "error" }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: "<div class=\"alert\" [ngClass]=\"error.level\">\n <div class=\"message\">\n <span>{{ error.message }}</span>\n </div>\n <div class=\"alert-end\">\n @if (error.link) {\n <span [routerLink]=\"error.link\" class=\"link\">View</span>\n }\n <button (click)=\"dismissAlert()\" mat-icon-button aria-label=\"Close Alert\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".alert{margin:auto;border:1px solid;max-width:450px;border-radius:5px;background-color:#d3d3d3;display:flex;flex-direction:row;align-items:center;justify-content:space-between}.message{padding-left:15px;max-width:400px;display:flex;justify-content:space-between}.alert-end{display:flex;flex-direction:row;align-items:center;gap:5px}.link{cursor:pointer}.link:hover{text-decoration:underline}.warn{border-color:red;background-color:#fff5f4}.accent{border-color:#dfb51d;background-color:#fff8e0}.success{border-color:#4caf50;background-color:#f0fff0}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
32
32
|
}
|
|
33
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AlertComponent, decorators: [{
|
|
34
34
|
type: Component,
|
|
35
35
|
args: [{ selector: 'ccc-alert', imports: [MatIconModule, MatButtonModule, CommonModule, RouterModule], template: "<div class=\"alert\" [ngClass]=\"error.level\">\n <div class=\"message\">\n <span>{{ error.message }}</span>\n </div>\n <div class=\"alert-end\">\n @if (error.link) {\n <span [routerLink]=\"error.link\" class=\"link\">View</span>\n }\n <button (click)=\"dismissAlert()\" mat-icon-button aria-label=\"Close Alert\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".alert{margin:auto;border:1px solid;max-width:450px;border-radius:5px;background-color:#d3d3d3;display:flex;flex-direction:row;align-items:center;justify-content:space-between}.message{padding-left:15px;max-width:400px;display:flex;justify-content:space-between}.alert-end{display:flex;flex-direction:row;align-items:center;gap:5px}.link{cursor:pointer}.link:hover{text-decoration:underline}.warn{border-color:red;background-color:#fff5f4}.accent{border-color:#dfb51d;background-color:#fff8e0}.success{border-color:#4caf50;background-color:#f0fff0}\n"] }]
|
|
36
36
|
}], propDecorators: { error: [{
|
|
@@ -4,11 +4,11 @@ import { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';
|
|
|
4
4
|
|
|
5
5
|
class UiCoreService {
|
|
6
6
|
notifications = inject(NotificationService);
|
|
7
|
-
loadingSignal = signal([],
|
|
8
|
-
sidenavOpened = signal(true,
|
|
9
|
-
currentSidenavIdentifier = signal('',
|
|
7
|
+
loadingSignal = signal([], ...(ngDevMode ? [{ debugName: "loadingSignal" }] : []));
|
|
8
|
+
sidenavOpened = signal(true, ...(ngDevMode ? [{ debugName: "sidenavOpened" }] : []));
|
|
9
|
+
currentSidenavIdentifier = signal('', ...(ngDevMode ? [{ debugName: "currentSidenavIdentifier" }] : []));
|
|
10
10
|
loading = this.loadingSignal.asReadonly();
|
|
11
|
-
isLoading = computed(() => this.loading().length > 0,
|
|
11
|
+
isLoading = computed(() => this.loading().length > 0, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
12
12
|
publishError(message) {
|
|
13
13
|
this.notifications.addGlobalNotification(message);
|
|
14
14
|
}
|
|
@@ -23,10 +23,10 @@ class UiCoreService {
|
|
|
23
23
|
toggleSidenav() {
|
|
24
24
|
this.sidenavOpened.update((opened) => !opened);
|
|
25
25
|
}
|
|
26
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
27
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
26
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UiCoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
27
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UiCoreService, providedIn: 'root' });
|
|
28
28
|
}
|
|
29
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UiCoreService, decorators: [{
|
|
30
30
|
type: Injectable,
|
|
31
31
|
args: [{
|
|
32
32
|
providedIn: 'root',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cccteam-ccc-lib-ui-core-service.mjs","sources":["../../../projects/ccc-lib/ui-core-service/ui-core.service.ts","../../../projects/ccc-lib/ui-core-service/cccteam-ccc-lib-ui-core-service.ts"],"sourcesContent":["import { computed, inject, Injectable, signal } from '@angular/core';\nimport { CreateNotificationMessage } from '@cccteam/ccc-lib/types';\nimport { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class UiCoreService {\n notifications = inject(NotificationService);\n loadingSignal = signal([] as string[]);\n sidenavOpened = signal(true);\n currentSidenavIdentifier = signal('');\n\n private loading = this.loadingSignal.asReadonly();\n isLoading = computed(() => this.loading().length > 0);\n\n publishError(message: CreateNotificationMessage): void {\n this.notifications.addGlobalNotification(message);\n }\n\n beginActivity(process: string): void {\n if (!this.loading().includes(process)) {\n this.loadingSignal.update((current) => [...current, process]);\n }\n }\n\n endActivity(process: string): void {\n this.loadingSignal.update((current) => current.filter((p) => p !== process));\n }\n\n toggleSidenav(): void {\n this.sidenavOpened.update((opened) => !opened);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAOa,aAAa,CAAA;AACxB,IAAA,aAAa,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC3C,IAAA,aAAa,GAAG,MAAM,CAAC,EAAc,
|
|
1
|
+
{"version":3,"file":"cccteam-ccc-lib-ui-core-service.mjs","sources":["../../../projects/ccc-lib/ui-core-service/ui-core.service.ts","../../../projects/ccc-lib/ui-core-service/cccteam-ccc-lib-ui-core-service.ts"],"sourcesContent":["import { computed, inject, Injectable, signal } from '@angular/core';\nimport { CreateNotificationMessage } from '@cccteam/ccc-lib/types';\nimport { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class UiCoreService {\n notifications = inject(NotificationService);\n loadingSignal = signal([] as string[]);\n sidenavOpened = signal(true);\n currentSidenavIdentifier = signal('');\n\n private loading = this.loadingSignal.asReadonly();\n isLoading = computed(() => this.loading().length > 0);\n\n publishError(message: CreateNotificationMessage): void {\n this.notifications.addGlobalNotification(message);\n }\n\n beginActivity(process: string): void {\n if (!this.loading().includes(process)) {\n this.loadingSignal.update((current) => [...current, process]);\n }\n }\n\n endActivity(process: string): void {\n this.loadingSignal.update((current) => current.filter((p) => p !== process));\n }\n\n toggleSidenav(): void {\n this.sidenavOpened.update((opened) => !opened);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAOa,aAAa,CAAA;AACxB,IAAA,aAAa,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC3C,IAAA,aAAa,GAAG,MAAM,CAAC,EAAc,yDAAC;AACtC,IAAA,aAAa,GAAG,MAAM,CAAC,IAAI,yDAAC;AAC5B,IAAA,wBAAwB,GAAG,MAAM,CAAC,EAAE,oEAAC;AAE7B,IAAA,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;AACjD,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,qDAAC;AAErD,IAAA,YAAY,CAAC,OAAkC,EAAA;AAC7C,QAAA,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC;IACnD;AAEA,IAAA,aAAa,CAAC,OAAe,EAAA;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AACrC,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/D;IACF;AAEA,IAAA,WAAW,CAAC,OAAe,EAAA;QACzB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,CAAC;IAC9E;IAEA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC;IAChD;uGAzBW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cAFZ,MAAM,EAAA,CAAA;;2FAEP,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACND;;AAEG;;;;"}
|
|
@@ -3,7 +3,7 @@ import { inject, signal, computed, Injectable } from '@angular/core';
|
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { Router } from '@angular/router';
|
|
5
5
|
import { AuthService } from '@cccteam/ccc-lib/auth-service';
|
|
6
|
-
import { FRONTEND_LOGIN_PATH, IDLE_SESSION_DURATION, IDLE_WARNING_DURATION, IDLE_KEEPALIVE_DURATION, AlertLevel } from '@cccteam/ccc-lib/types';
|
|
6
|
+
import { FRONTEND_LOGIN_PATH, IDLE_SESSION_DURATION, IDLE_LOGOUT_ACTION, IDLE_WARNING_DURATION, IDLE_KEEPALIVE_DURATION, AlertLevel } from '@cccteam/ccc-lib/types';
|
|
7
7
|
import { UiCoreService } from '@cccteam/ccc-lib/ui-core-service';
|
|
8
8
|
import { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';
|
|
9
9
|
import { interval } from 'rxjs';
|
|
@@ -15,28 +15,29 @@ class IdleService {
|
|
|
15
15
|
notifications = inject(NotificationService);
|
|
16
16
|
loginPath = inject(FRONTEND_LOGIN_PATH);
|
|
17
17
|
sessionDuration = inject(IDLE_SESSION_DURATION);
|
|
18
|
+
logoutAction = inject(IDLE_LOGOUT_ACTION);
|
|
18
19
|
warningDuration = inject(IDLE_WARNING_DURATION);
|
|
19
20
|
keepAliveDuration = inject(IDLE_KEEPALIVE_DURATION);
|
|
20
21
|
idleCheckFrequency = 1000;
|
|
21
22
|
warningThreshold = this.sessionDuration - this.warningDuration;
|
|
22
|
-
isActive = signal(false,
|
|
23
|
-
lastActivityTimestamp = signal(0,
|
|
24
|
-
tick = signal(Date.now(),
|
|
23
|
+
isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
24
|
+
lastActivityTimestamp = signal(0, ...(ngDevMode ? [{ debugName: "lastActivityTimestamp" }] : []));
|
|
25
|
+
tick = signal(Date.now(), ...(ngDevMode ? [{ debugName: "tick" }] : []));
|
|
25
26
|
secondsIdle = computed(() => {
|
|
26
27
|
if (!this.isActive() || this.lastActivityTimestamp() === 0) {
|
|
27
28
|
return 0;
|
|
28
29
|
}
|
|
29
30
|
// Depends on tick() to force re-evaluation as time passes
|
|
30
31
|
return Math.floor((this.tick() - this.lastActivityTimestamp()) / 1000);
|
|
31
|
-
},
|
|
32
|
-
isWarning = computed(() => this.secondsIdle() >= this.warningThreshold,
|
|
32
|
+
}, ...(ngDevMode ? [{ debugName: "secondsIdle" }] : []));
|
|
33
|
+
isWarning = computed(() => this.secondsIdle() >= this.warningThreshold, ...(ngDevMode ? [{ debugName: "isWarning" }] : []));
|
|
33
34
|
countdown = computed(() => {
|
|
34
35
|
if (!this.isWarning()) {
|
|
35
36
|
return 0;
|
|
36
37
|
}
|
|
37
38
|
const remaining = this.sessionDuration - this.secondsIdle();
|
|
38
39
|
return Math.max(0, remaining);
|
|
39
|
-
},
|
|
40
|
+
}, ...(ngDevMode ? [{ debugName: "countdown" }] : []));
|
|
40
41
|
alertId;
|
|
41
42
|
mainTickerSubscription;
|
|
42
43
|
activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];
|
|
@@ -70,9 +71,15 @@ class IdleService {
|
|
|
70
71
|
this.dismissWarningAlert();
|
|
71
72
|
}
|
|
72
73
|
/**
|
|
73
|
-
* Logs out the user due to inactivity and stops the service.
|
|
74
|
+
* Logs out the user due to inactivity, calls the configured logout action, and stops the service.
|
|
74
75
|
*/
|
|
75
76
|
logoutAndStop() {
|
|
77
|
+
try {
|
|
78
|
+
this.logoutAction();
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error('Error during idle logout action (IDLE_LOGOUT_ACTION token):', error);
|
|
82
|
+
}
|
|
76
83
|
this.stop();
|
|
77
84
|
this.router.navigate([this.loginPath]);
|
|
78
85
|
this.core.publishError({
|
|
@@ -140,10 +147,10 @@ class IdleService {
|
|
|
140
147
|
this.alertId = undefined;
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
144
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
150
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: IdleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
151
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: IdleService, providedIn: 'root' });
|
|
145
152
|
}
|
|
146
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
153
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: IdleService, decorators: [{
|
|
147
154
|
type: Injectable,
|
|
148
155
|
args: [{
|
|
149
156
|
providedIn: 'root',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cccteam-ccc-lib-ui-idle-service.mjs","sources":["../../../projects/ccc-lib/ui-idle-service/idle.service.ts","../../../projects/ccc-lib/ui-idle-service/cccteam-ccc-lib-ui-idle-service.ts"],"sourcesContent":["import { computed, inject, Injectable, OnDestroy, signal, WritableSignal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Router } from '@angular/router';\nimport { AuthService } from '@cccteam/ccc-lib/auth-service';\nimport {\n AlertLevel,\n FRONTEND_LOGIN_PATH,\n IDLE_KEEPALIVE_DURATION,\n IDLE_SESSION_DURATION,\n IDLE_WARNING_DURATION,\n} from '@cccteam/ccc-lib/types';\nimport { UiCoreService } from '@cccteam/ccc-lib/ui-core-service';\nimport { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';\nimport { interval, Subscription } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class IdleService implements OnDestroy {\n private auth = inject(AuthService);\n private core = inject(UiCoreService);\n private router = inject(Router);\n private notifications = inject(NotificationService);\n private readonly loginPath = inject(FRONTEND_LOGIN_PATH);\n\n private readonly sessionDuration = inject(IDLE_SESSION_DURATION);\n private readonly warningDuration = inject(IDLE_WARNING_DURATION);\n private readonly keepAliveDuration = inject(IDLE_KEEPALIVE_DURATION);\n private readonly idleCheckFrequency = 1000;\n private readonly warningThreshold = this.sessionDuration - this.warningDuration;\n\n public readonly isActive = signal(false);\n private lastActivityTimestamp: WritableSignal<number> = signal(0);\n private tick = signal(Date.now());\n\n public readonly secondsIdle = computed(() => {\n if (!this.isActive() || this.lastActivityTimestamp() === 0) {\n return 0;\n }\n // Depends on tick() to force re-evaluation as time passes\n return Math.floor((this.tick() - this.lastActivityTimestamp()) / 1000);\n });\n\n public readonly isWarning = computed(() => this.secondsIdle() >= this.warningThreshold);\n public readonly countdown = computed(() => {\n if (!this.isWarning()) {\n return 0;\n }\n const remaining = this.sessionDuration - this.secondsIdle();\n return Math.max(0, remaining);\n });\n\n private alertId: number | undefined;\n private mainTickerSubscription: Subscription | undefined;\n\n private readonly activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n\n constructor() {\n interval(this.keepAliveDuration * 1000)\n .pipe(takeUntilDestroyed())\n .subscribe(() => this.checkSession());\n }\n\n ngOnDestroy(): void {\n this.stop();\n }\n\n /**\n * Starts the idle monitoring service.\n */\n start(): void {\n if (this.isActive()) {\n return;\n }\n this.isActive.set(true);\n this.lastActivityTimestamp.set(Date.now());\n this.addActivityListeners();\n this.startMainTicker();\n }\n\n /**\n * Stops the idle monitoring service and cleans up timers and alerts.\n */\n stop(): void {\n this.isActive.set(false);\n this.mainTickerSubscription?.unsubscribe();\n this.removeActivityListeners();\n this.dismissWarningAlert();\n }\n\n /**\n * Logs out the user due to inactivity and stops the service.\n */\n logoutAndStop(): void {\n this.stop();\n\n this.router.navigate([this.loginPath]);\n this.core.publishError({\n message: 'You have been logged out due to inactivity.',\n level: AlertLevel.INFO,\n link: '',\n });\n }\n\n private startMainTicker(): void {\n this.mainTickerSubscription = interval(this.idleCheckFrequency).subscribe(() => {\n this.tick.set(Date.now());\n\n if (this.secondsIdle() >= this.sessionDuration) {\n this.logoutAndStop();\n return;\n }\n\n if (this.isWarning()) {\n this.showOrUpdateWarningAlert(this.countdown());\n } else {\n this.dismissWarningAlert();\n }\n });\n }\n\n private checkSession(): void {\n if (this.auth.authenticated()) {\n this.auth.checkUserSession().subscribe({\n next: () => {\n if (!this.auth.authenticated()) {\n this.logoutAndStop();\n }\n },\n });\n }\n }\n\n setLastActivity(): void {\n this.lastActivityTimestamp.set(Date.now());\n }\n boundActivity = this.setLastActivity.bind(this);\n\n private addActivityListeners(): void {\n this.activityEvents.forEach((event) => {\n document.addEventListener(event, this.boundActivity, true);\n });\n }\n\n private removeActivityListeners(): void {\n this.activityEvents.forEach((event) => {\n document.removeEventListener(event, this.boundActivity, true);\n });\n }\n\n private showOrUpdateWarningAlert(countdown: number): void {\n const message = `You will be logged out in ${countdown} seconds due to inactivity.`;\n if (this.alertId !== undefined) {\n this.notifications.updateNotification({ id: this.alertId, level: AlertLevel.INFO, link: '', message });\n } else {\n this.alertId = this.notifications.addGlobalNotification({\n message,\n level: AlertLevel.INFO,\n link: '',\n });\n }\n }\n\n private dismissWarningAlert(): void {\n if (this.alertId !== undefined) {\n this.notifications.dismissGlobalNotificationById(this.alertId);\n this.alertId = undefined;\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cccteam-ccc-lib-ui-idle-service.mjs","sources":["../../../projects/ccc-lib/ui-idle-service/idle.service.ts","../../../projects/ccc-lib/ui-idle-service/cccteam-ccc-lib-ui-idle-service.ts"],"sourcesContent":["import { computed, inject, Injectable, OnDestroy, signal, WritableSignal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Router } from '@angular/router';\nimport { AuthService } from '@cccteam/ccc-lib/auth-service';\nimport {\n AlertLevel,\n FRONTEND_LOGIN_PATH,\n IDLE_KEEPALIVE_DURATION,\n IDLE_LOGOUT_ACTION,\n IDLE_SESSION_DURATION,\n IDLE_WARNING_DURATION,\n} from '@cccteam/ccc-lib/types';\nimport { UiCoreService } from '@cccteam/ccc-lib/ui-core-service';\nimport { NotificationService } from '@cccteam/ccc-lib/ui-notification-service';\nimport { interval, Subscription } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class IdleService implements OnDestroy {\n private auth = inject(AuthService);\n private core = inject(UiCoreService);\n private router = inject(Router);\n private notifications = inject(NotificationService);\n private readonly loginPath = inject(FRONTEND_LOGIN_PATH);\n\n private readonly sessionDuration = inject(IDLE_SESSION_DURATION);\n private readonly logoutAction = inject(IDLE_LOGOUT_ACTION);\n private readonly warningDuration = inject(IDLE_WARNING_DURATION);\n private readonly keepAliveDuration = inject(IDLE_KEEPALIVE_DURATION);\n private readonly idleCheckFrequency = 1000;\n private readonly warningThreshold = this.sessionDuration - this.warningDuration;\n\n public readonly isActive = signal(false);\n private lastActivityTimestamp: WritableSignal<number> = signal(0);\n private tick = signal(Date.now());\n\n public readonly secondsIdle = computed(() => {\n if (!this.isActive() || this.lastActivityTimestamp() === 0) {\n return 0;\n }\n // Depends on tick() to force re-evaluation as time passes\n return Math.floor((this.tick() - this.lastActivityTimestamp()) / 1000);\n });\n\n public readonly isWarning = computed(() => this.secondsIdle() >= this.warningThreshold);\n public readonly countdown = computed(() => {\n if (!this.isWarning()) {\n return 0;\n }\n const remaining = this.sessionDuration - this.secondsIdle();\n return Math.max(0, remaining);\n });\n\n private alertId: number | undefined;\n private mainTickerSubscription: Subscription | undefined;\n\n private readonly activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n\n constructor() {\n interval(this.keepAliveDuration * 1000)\n .pipe(takeUntilDestroyed())\n .subscribe(() => this.checkSession());\n }\n\n ngOnDestroy(): void {\n this.stop();\n }\n\n /**\n * Starts the idle monitoring service.\n */\n start(): void {\n if (this.isActive()) {\n return;\n }\n this.isActive.set(true);\n this.lastActivityTimestamp.set(Date.now());\n this.addActivityListeners();\n this.startMainTicker();\n }\n\n /**\n * Stops the idle monitoring service and cleans up timers and alerts.\n */\n stop(): void {\n this.isActive.set(false);\n this.mainTickerSubscription?.unsubscribe();\n this.removeActivityListeners();\n this.dismissWarningAlert();\n }\n\n /**\n * Logs out the user due to inactivity, calls the configured logout action, and stops the service.\n */\n logoutAndStop(): void {\n try {\n this.logoutAction();\n } catch (error) {\n console.error('Error during idle logout action (IDLE_LOGOUT_ACTION token):', error);\n }\n this.stop();\n\n this.router.navigate([this.loginPath]);\n this.core.publishError({\n message: 'You have been logged out due to inactivity.',\n level: AlertLevel.INFO,\n link: '',\n });\n }\n\n private startMainTicker(): void {\n this.mainTickerSubscription = interval(this.idleCheckFrequency).subscribe(() => {\n this.tick.set(Date.now());\n\n if (this.secondsIdle() >= this.sessionDuration) {\n this.logoutAndStop();\n return;\n }\n\n if (this.isWarning()) {\n this.showOrUpdateWarningAlert(this.countdown());\n } else {\n this.dismissWarningAlert();\n }\n });\n }\n\n private checkSession(): void {\n if (this.auth.authenticated()) {\n this.auth.checkUserSession().subscribe({\n next: () => {\n if (!this.auth.authenticated()) {\n this.logoutAndStop();\n }\n },\n });\n }\n }\n\n setLastActivity(): void {\n this.lastActivityTimestamp.set(Date.now());\n }\n boundActivity = this.setLastActivity.bind(this);\n\n private addActivityListeners(): void {\n this.activityEvents.forEach((event) => {\n document.addEventListener(event, this.boundActivity, true);\n });\n }\n\n private removeActivityListeners(): void {\n this.activityEvents.forEach((event) => {\n document.removeEventListener(event, this.boundActivity, true);\n });\n }\n\n private showOrUpdateWarningAlert(countdown: number): void {\n const message = `You will be logged out in ${countdown} seconds due to inactivity.`;\n if (this.alertId !== undefined) {\n this.notifications.updateNotification({ id: this.alertId, level: AlertLevel.INFO, link: '', message });\n } else {\n this.alertId = this.notifications.addGlobalNotification({\n message,\n level: AlertLevel.INFO,\n link: '',\n });\n }\n }\n\n private dismissWarningAlert(): void {\n if (this.alertId !== undefined) {\n this.notifications.dismissGlobalNotificationById(this.alertId);\n this.alertId = undefined;\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -36,10 +36,10 @@ class ApiInterceptor {
|
|
|
36
36
|
this.ui.endActivity(request.method + ' ' + request.url);
|
|
37
37
|
}));
|
|
38
38
|
}
|
|
39
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
40
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
39
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ApiInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
40
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ApiInterceptor });
|
|
41
41
|
}
|
|
42
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
42
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ApiInterceptor, decorators: [{
|
|
43
43
|
type: Injectable
|
|
44
44
|
}] });
|
|
45
45
|
|
|
@@ -2,8 +2,8 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { signal, Injectable } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
class NotificationService {
|
|
5
|
-
notificationId = signal(0,
|
|
6
|
-
_notifications = signal([],
|
|
5
|
+
notificationId = signal(0, ...(ngDevMode ? [{ debugName: "notificationId" }] : []));
|
|
6
|
+
_notifications = signal([], ...(ngDevMode ? [{ debugName: "_notifications" }] : []));
|
|
7
7
|
notifications = this._notifications.asReadonly();
|
|
8
8
|
/**
|
|
9
9
|
* Adds a new global notification.
|
|
@@ -45,10 +45,10 @@ class NotificationService {
|
|
|
45
45
|
updateNotification(updatedNotification) {
|
|
46
46
|
this._notifications.update((current) => current.map((notification) => notification.id === updatedNotification.id ? { ...notification, ...updatedNotification } : notification));
|
|
47
47
|
}
|
|
48
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
49
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
48
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
49
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
50
50
|
}
|
|
51
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NotificationService, decorators: [{
|
|
52
52
|
type: Injectable,
|
|
53
53
|
args: [{
|
|
54
54
|
providedIn: 'root',
|