@acorex-platform/framework-client 0.0.59 → 0.0.60
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/acorex-platform-framework-client-auth.mjs +397 -93
- package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-common.mjs +33 -31
- package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs +12 -4
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BBuYugjl.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-D0jDsA6M.mjs} +80 -13
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-D0jDsA6M.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DZDf_nVq.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-Bdvd1iYt.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DZDf_nVq.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-Bdvd1iYt.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-CFFv3jDs.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-CsTP8YHv.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-CFFv3jDs.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-CsTP8YHv.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-BDNPJg_6.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-UvMk0GbU.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-BDNPJg_6.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-UvMk0GbU.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +165 -28
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-Rv0K9r_e.mjs → acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-KrDsAa3H.mjs} +555 -121
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-KrDsAa3H.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-Dzqn3rGa.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BDlo6nTx.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-Dzqn3rGa.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BDlo6nTx.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-C97rrrmu.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-By3wntCB.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-C97rrrmu.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-By3wntCB.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -1
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs +4 -4
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
- package/layout/builder/README.md +10 -0
- package/layout/widget-core/README.md +47 -3
- package/layout/widgets/README.md +8 -2
- package/package.json +2 -2
- package/types/acorex-platform-framework-client-auth.d.ts +60 -1
- package/types/acorex-platform-framework-client-common.d.ts +3 -2
- package/types/acorex-platform-framework-client-layout-components.d.ts +3 -1
- package/types/acorex-platform-framework-client-layout-entity.d.ts +8 -1
- package/types/acorex-platform-framework-client-layout-widget-core.d.ts +39 -0
- package/types/acorex-platform-framework-client-layout-widgets.d.ts +25 -5
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BBuYugjl.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-Rv0K9r_e.mjs.map +0 -1
package/layout/builder/README.md
CHANGED
|
@@ -1220,6 +1220,16 @@ export class SignatureComponent {
|
|
|
1220
1220
|
|
|
1221
1221
|
---
|
|
1222
1222
|
|
|
1223
|
+
## Repeater widgets (row isolation)
|
|
1224
|
+
|
|
1225
|
+
Sibling rows share leaf names (`applicationId`, `roleIds`). Do not bind triggers to `events.context('*applicationId')` or a bare `applicationId` — that clears **every** row.
|
|
1226
|
+
|
|
1227
|
+
- This row only: `events.context('>field')`.
|
|
1228
|
+
- Duplicate keys: merge on submit (union), not unique dropdowns with `filter` `not-in`.
|
|
1229
|
+
- Details: `libs/framework/client/layout/widget-core/README.md`.
|
|
1230
|
+
|
|
1231
|
+
---
|
|
1232
|
+
|
|
1223
1233
|
## Best Practices
|
|
1224
1234
|
|
|
1225
1235
|
### 1. Use Descriptive Names
|
|
@@ -1,4 +1,48 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Widget renderer — repeater context isolation
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Package: `@acorex-platform/framework-client/layout/widget-core`.
|
|
4
|
+
|
|
5
|
+
Renderer: `src/lib/widget-renderer.directive.ts`.
|
|
6
|
+
|
|
7
|
+
Do not “simplify” path matching so that two repeater rows share the same leaf field name. That regression already shipped twice on TM Tenant Users Invite (`applicationRoleRows`).
|
|
8
|
+
|
|
9
|
+
## What went wrong
|
|
10
|
+
|
|
11
|
+
Indexed store paths look like:
|
|
12
|
+
|
|
13
|
+
- `applicationRoleRows[0].applicationId`
|
|
14
|
+
- `applicationRoleRows[1].applicationId`
|
|
15
|
+
|
|
16
|
+
Last-segment matching (`applicationId`) treats those as the same change. Effects:
|
|
17
|
+
|
|
18
|
+
- `events.context('>applicationId')` + `widget.setValue([])` on Roles runs on **every** row.
|
|
19
|
+
- `events.context('*applicationId')` does the same by design — never use `*` for row-local reset.
|
|
20
|
+
|
|
21
|
+
Unresolved `>` (empty `parentPath`) becomes the bare field `applicationId`. That must **not** suffix-match every `*.applicationId`.
|
|
22
|
+
|
|
23
|
+
## Required matching rules
|
|
24
|
+
|
|
25
|
+
| Listener | Match |
|
|
26
|
+
|----------|--------|
|
|
27
|
+
| `events.context('>field')` | Exact resolved path for **this** widget row only |
|
|
28
|
+
| `events.context('rows')` | The array and every `rows[n]…` child (list-wide refresh) |
|
|
29
|
+
| Different `rows[i]` vs `rows[j]` | **Never** match via shared suffix |
|
|
30
|
+
|
|
31
|
+
`repeaterRowIndexConflicts` must stay in front of suffix matching in `contextStorePathDependsOnChangedPath`. `getEventScope` / `hasTriggerDependency` must keep the exact-match branch for `>` — do not OR `>` with suffix matching.
|
|
32
|
+
|
|
33
|
+
## Duplicate keys in a repeater
|
|
34
|
+
|
|
35
|
+
Prefer **merge on submit** (union of child values for the same key). TM Tenant Users Invite does this via `normalizeInviteApplicationRoleAssignments` — the same application may appear on two rows; persist one grant with all picked roles.
|
|
36
|
+
|
|
37
|
+
Do **not** unique the dropdown with widget `filter` `not-in` / `nin`. Empty `not-in` is treated as a pending cascade and disables the select (empty list + not-allowed cursor). If a different screen truly needs unique options, use `excludeIds` (keep the current widget value in `excludeOptionRows`), never `not-in`.
|
|
38
|
+
|
|
39
|
+
## Layout recipe — row-local Roles reset
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
triggers: [{
|
|
43
|
+
event: "{{ events.context('>applicationId') }}",
|
|
44
|
+
action: '{{ widget.setValue([]); widget.refresh(); }}',
|
|
45
|
+
}]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Reference: `libs/modules/security-management/client/src/lib/commands/invite-user.command.ts` (`buildApplicationRoleRepeaterChildren`).
|
package/layout/widgets/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Layout widgets
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Package: `@acorex-platform/framework-client/layout/widgets`.
|
|
4
|
+
|
|
5
|
+
Select / combo (`select-box-widget-edit.component.ts`):
|
|
6
|
+
|
|
7
|
+
- Cascade parent empty → `hasPendingCascadeFilter` disables the control. Operators `not-in` / `nin` are **not** cascade.
|
|
8
|
+
- Repeater duplicate keys: merge on submit (see TM invite `normalizeInviteApplicationRoleAssignments`). Do not unique options with `filter` `not-in`.
|
|
9
|
+
- Repeater path matching: `libs/framework/client/layout/widget-core/README.md`.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acorex-platform/framework-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.60",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@acorex-platform/framework-shared": "0.0.
|
|
5
|
+
"@acorex-platform/framework-shared": "0.0.60",
|
|
6
6
|
"@acorex/cdk": "^21.0.0 || ^22.0.0 || ^22.0.0-next.0 || ^22.1.0-next.0 || ^22.2.0-next.0 || ^22.2.0-next.0",
|
|
7
7
|
"@acorex/charts": "^21.0.0 || ^22.0.0 || ^22.0.0-next.0 || ^22.1.0-next.0 || ^22.2.0-next.0 || ^22.2.0-next.0",
|
|
8
8
|
"@acorex/components": "^21.0.0 || ^22.0.0 || ^22.0.0-next.0 || ^22.1.0-next.0 || ^22.2.0-next.0 || ^22.2.0-next.0",
|
|
@@ -351,7 +351,13 @@ declare class AXPSessionService {
|
|
|
351
351
|
/** In-memory catalog caches — shared by guards and chooser UI (one List* per bind). */
|
|
352
352
|
private tenantsListCache;
|
|
353
353
|
private applicationsListCache;
|
|
354
|
+
/** Bumps when catalogs must re-fetch (e.g. after tenant-request approve). */
|
|
355
|
+
private readonly catalogEpoch$;
|
|
354
356
|
private signoutInFlight;
|
|
357
|
+
/** Coalesces soft-restore → Authorized promotion after connectivity recovers. */
|
|
358
|
+
private accessPolicyRetryInFlight;
|
|
359
|
+
private softRestoreOnlineRecoveryAttached;
|
|
360
|
+
private softRestoreOnlineRecoveryHandler;
|
|
355
361
|
private status;
|
|
356
362
|
readonly status$: Observable<AXPSessionStatus>;
|
|
357
363
|
private isLoading;
|
|
@@ -391,6 +397,28 @@ declare class AXPSessionService {
|
|
|
391
397
|
/** Waits for session restore to finish, then emits whether the session is fully authorized. */
|
|
392
398
|
readonly isAuthorizedWithLoading$: Observable<boolean>;
|
|
393
399
|
restoreSession(): Promise<void>;
|
|
400
|
+
/**
|
|
401
|
+
* Trust persisted AXP_SESSION after a non-definitive restore refresh failure.
|
|
402
|
+
* Keeps identity; promotes to Authorized only when access policy load succeeds.
|
|
403
|
+
*/
|
|
404
|
+
private softRestoreFromStoredSession;
|
|
405
|
+
/**
|
|
406
|
+
* Soft-restore policy load: success = both loaders completed without throw
|
|
407
|
+
* (empty permission/feature lists still count as a successful load).
|
|
408
|
+
*/
|
|
409
|
+
private tryLoadAccessPolicyForSoftRestore;
|
|
410
|
+
/**
|
|
411
|
+
* Retries access-policy load after a soft restore that stayed Authenticated.
|
|
412
|
+
* On success with complete workspace, promotes to Authorized (no logout on failure).
|
|
413
|
+
* Coalesces concurrent callers (refresh / online / successful API).
|
|
414
|
+
*/
|
|
415
|
+
retryAccessPolicyAuthorization(): Promise<boolean>;
|
|
416
|
+
/**
|
|
417
|
+
* Bounded recovery after soft-restore Authenticated: browser `online` once per arm.
|
|
418
|
+
* Successful token refresh also retries (see {@link refreshToken}).
|
|
419
|
+
*/
|
|
420
|
+
private armSoftRestorePolicyRecovery;
|
|
421
|
+
private disarmSoftRestorePolicyRecovery;
|
|
394
422
|
signin(credentials: AXPBaseCredentials): Promise<void>;
|
|
395
423
|
register(credentials: AXPBaseCredentials): Promise<void>;
|
|
396
424
|
private applySignInResult;
|
|
@@ -428,6 +456,11 @@ declare class AXPSessionService {
|
|
|
428
456
|
/** Shared ListApplications — used by guards and {@link applications$}. */
|
|
429
457
|
getApplicationsList(): Promise<AXPApplication[]>;
|
|
430
458
|
private clearCatalogCaches;
|
|
459
|
+
/**
|
|
460
|
+
* Drops ListTenants / ListApplications caches and re-emits {@link tenants$}.
|
|
461
|
+
* Call after membership/tenant availability changes (e.g. approve tenant request).
|
|
462
|
+
*/
|
|
463
|
+
invalidateCatalogCaches(): void;
|
|
431
464
|
signInComplete(): Promise<void>;
|
|
432
465
|
/** Tenant + application must be bound before menu, permissions, and features are fully valid. */
|
|
433
466
|
private hasCompleteSessionContext;
|
|
@@ -715,6 +748,32 @@ declare function storeSessionLimitPendingTenant(tenant: AXPSessionLimitPendingTe
|
|
|
715
748
|
declare function readSessionLimitPendingTenant(): AXPSessionLimitPendingTenant | null;
|
|
716
749
|
declare function clearSessionLimitPendingTenant(): void;
|
|
717
750
|
|
|
751
|
+
/**
|
|
752
|
+
* Stable server codes for definitive refresh/session death (prefer over message text).
|
|
753
|
+
* Keep in sync with `AUTH_REFRESH_ERROR_CODES` / `SESSION_MEMBERSHIP_DENIED` on the server.
|
|
754
|
+
*/
|
|
755
|
+
declare const DEFINITIVE_AUTH_REFRESH_CODES: readonly ["REFRESH_MISSING", "REFRESH_EXPIRED", "REFRESH_REVOKED", "REFRESH_REUSE", "SESSION_REVOKED", "USER_NOT_FOUND", "SESSION_MEMBERSHIP_DENIED"];
|
|
756
|
+
/**
|
|
757
|
+
* True only when refresh failed because the refresh cookie / session family is dead.
|
|
758
|
+
* Network / 5xx / Redis unavailable / empty transient results → false.
|
|
759
|
+
*/
|
|
760
|
+
declare function isDefinitiveAuthRefreshFailure(error: unknown): boolean;
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* After soft restore: keep identity without promoting to Authorized when
|
|
764
|
+
* access policy could not be loaded (transient API/refresh failure).
|
|
765
|
+
*/
|
|
766
|
+
declare function resolveStatusAfterSoftRestore(options: {
|
|
767
|
+
hasUser: boolean;
|
|
768
|
+
hasCompleteWorkspace: boolean;
|
|
769
|
+
policyLoadSucceeded: boolean;
|
|
770
|
+
}): AXPSessionStatus;
|
|
771
|
+
/**
|
|
772
|
+
* Soft-restore left the session Authenticated (policy unavailable).
|
|
773
|
+
* Retry access-policy load after connectivity / successful token refresh recovers.
|
|
774
|
+
*/
|
|
775
|
+
declare function shouldRetryAccessPolicyAuthorization(status: AXPSessionStatus): boolean;
|
|
776
|
+
|
|
718
777
|
/**
|
|
719
778
|
* Best-effort plain string for thrown {@link Error} messages from command results (no i18n lookup).
|
|
720
779
|
*/
|
|
@@ -1059,5 +1118,5 @@ declare class AXPSignInMethodRegistry {
|
|
|
1059
1118
|
static ɵprov: i0.ɵɵInjectableDeclaration<AXPSignInMethodRegistry>;
|
|
1060
1119
|
}
|
|
1061
1120
|
|
|
1062
|
-
export { AUTH_SESSION_TRACE_NS, AUTH_SESSION_TRACE_TITLE, AXPAuthGuard, AXPAuthModule, AXPAuthStrategy, AXPAuthStrategyRegistryService, AXPFeatureDirective, AXPFeatureEvaluatorScopeProvider, AXPFeatureGuard, AXPLoginChallengeComponentBase, AXPLoginChallengeProvider, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPPlatformAuthRuntimeService, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPSignInMethod, AXPSignInMethodRegistry, AXPUnauthenticatedError, AXPUnauthorizedError, AXPUserProfileIdentityService, AXP_ACCESS_POLICY_CACHE_PORT, AXP_APPLICATION_LOADER, AXP_DEFAULT_PLATFORM_OAUTH_CLIENT_ID, AXP_DEFAULT_PLATFORM_OAUTH_SCOPE, AXP_FEATURE_CHECKER, AXP_FEATURE_LOADER, AXP_LOGIN_CHALLENGE_PROVIDER, AXP_OAUTH_PKCE_VERIFIER_KEY, AXP_PERMISSION_CHECKER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_PERMISSION_MODULES_RESOLVER, AXP_PLATFORM_OAUTH_CSRF_COOKIE, AXP_TENANT_LOADER, AXP_USER_AVATAR_CACHE_PORT, JwtUtil, MAX_ACTIVE_DEVICE_SESSIONS_CODE, PkceUtil, TimeUtil, asAuthListProvidersResponse, clearOAuthPendingStrategy, clearSessionLimitPendingTenant, commandMessageTextForError, exchangePlatformOAuthAuthorizationCode, fetchPlatformOAuthDiscoveryDocument, findIdentityProvider, getOAuthPendingStrategy, hasLegacyOAuthPkceVerifier, hasOAuthPendingFlow, initPlatformOAuthAuthorization, isMaxActiveDeviceSessionsError, isOAuthRedirectInFlight, platformOAuthSessionUpdateParams, readPlatformOAuthCsrfToken, readSessionLimitPendingTenant, resolvePlatformOAuthAuthorizeEndpoint, resolvePlatformOAuthClientConfig, resolvePlatformOAuthIssuer, resolvePlatformOAuthRedirectUri, resolvePlatformOAuthTokenEndpoint, setOAuthPendingStrategy, shouldPlatformOAuthBindSession, storeSessionLimitPendingTenant, toPlatformOAuthSignInResult, traceAuthAccessPolicy, traceAuthCatalog, traceAuthGuard, traceAuthLifecycle, traceAuthLifecycleError, traceAuthRestore, traceAuthWorkspace, warnAuthAccessPolicy, warnAuthLifecycle, warnAuthWorkspace };
|
|
1121
|
+
export { AUTH_SESSION_TRACE_NS, AUTH_SESSION_TRACE_TITLE, AXPAuthGuard, AXPAuthModule, AXPAuthStrategy, AXPAuthStrategyRegistryService, AXPFeatureDirective, AXPFeatureEvaluatorScopeProvider, AXPFeatureGuard, AXPLoginChallengeComponentBase, AXPLoginChallengeProvider, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPPlatformAuthRuntimeService, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPSignInMethod, AXPSignInMethodRegistry, AXPUnauthenticatedError, AXPUnauthorizedError, AXPUserProfileIdentityService, AXP_ACCESS_POLICY_CACHE_PORT, AXP_APPLICATION_LOADER, AXP_DEFAULT_PLATFORM_OAUTH_CLIENT_ID, AXP_DEFAULT_PLATFORM_OAUTH_SCOPE, AXP_FEATURE_CHECKER, AXP_FEATURE_LOADER, AXP_LOGIN_CHALLENGE_PROVIDER, AXP_OAUTH_PKCE_VERIFIER_KEY, AXP_PERMISSION_CHECKER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_PERMISSION_MODULES_RESOLVER, AXP_PLATFORM_OAUTH_CSRF_COOKIE, AXP_TENANT_LOADER, AXP_USER_AVATAR_CACHE_PORT, DEFINITIVE_AUTH_REFRESH_CODES, JwtUtil, MAX_ACTIVE_DEVICE_SESSIONS_CODE, PkceUtil, TimeUtil, asAuthListProvidersResponse, clearOAuthPendingStrategy, clearSessionLimitPendingTenant, commandMessageTextForError, exchangePlatformOAuthAuthorizationCode, fetchPlatformOAuthDiscoveryDocument, findIdentityProvider, getOAuthPendingStrategy, hasLegacyOAuthPkceVerifier, hasOAuthPendingFlow, initPlatformOAuthAuthorization, isDefinitiveAuthRefreshFailure, isMaxActiveDeviceSessionsError, isOAuthRedirectInFlight, platformOAuthSessionUpdateParams, readPlatformOAuthCsrfToken, readSessionLimitPendingTenant, resolvePlatformOAuthAuthorizeEndpoint, resolvePlatformOAuthClientConfig, resolvePlatformOAuthIssuer, resolvePlatformOAuthRedirectUri, resolvePlatformOAuthTokenEndpoint, resolveStatusAfterSoftRestore, setOAuthPendingStrategy, shouldPlatformOAuthBindSession, shouldRetryAccessPolicyAuthorization, storeSessionLimitPendingTenant, toPlatformOAuthSignInResult, traceAuthAccessPolicy, traceAuthCatalog, traceAuthGuard, traceAuthLifecycle, traceAuthLifecycleError, traceAuthRestore, traceAuthWorkspace, warnAuthAccessPolicy, warnAuthLifecycle, warnAuthWorkspace };
|
|
1063
1122
|
export type { AXPAccessPolicyCachePort, AXPApplication, AXPApplicationLoader, AXPAuthIdentityProvider, AXPAuthListProvidersResponse, AXPAuthLocalSignInMethod, AXPAuthModuleConfigs, AXPBaseCredentials, AXPChallengeCheckResult, AXPChallengeContentType, AXPEdition, AXPFeature, AXPFeatureChecker, AXPFeatureLoader, AXPLoginChallengeData, AXPPermission, AXPPermissionAddOptions, AXPPermissionChecker, AXPPermissionDefinition, AXPPermissionDefinitionProvider, AXPPermissionGroupAddOptions, AXPPermissionGroupDefinition, AXPPermissionLoader, AXPPermissionModulesResolver, AXPPlatformOAuthClientConfig, AXPPlatformOAuthDiscoveryDocument, AXPSessionData, AXPSessionLimitPendingTenant, AXPSignInMethodDescriptor, AXPSignInMethodProtocol, AXPSignInMethodStartResult, AXPSignInMethodStep, AXPSignInMethodStepKind, AXPSignInResult, AXPTenant, AXPTenantLoader, AXPTokenResult, AXPUser, AXPUserAvatarCachePort, PlatformAuthOwnDeviceSessionDto, PlatformAuthTokenResponseDto, PlatformAuthUpdateSessionInput };
|
|
@@ -820,15 +820,17 @@ declare class AXPKeyboardShortcutsHelpComponent {
|
|
|
820
820
|
|
|
821
821
|
declare class AXPKeyboardShortcutsHelpService {
|
|
822
822
|
private readonly popupService;
|
|
823
|
-
private readonly dialogOpener;
|
|
824
823
|
private readonly translationService;
|
|
825
824
|
private readonly shortcutRegistry;
|
|
826
825
|
private readonly document;
|
|
826
|
+
/** In-flight help popup session (open until the popup closes). */
|
|
827
|
+
private activeShow;
|
|
827
828
|
constructor();
|
|
828
829
|
/**
|
|
829
830
|
* Opens the keyboard shortcuts help popup, or no-ops when it is already open.
|
|
830
831
|
*/
|
|
831
832
|
show(): Promise<void>;
|
|
833
|
+
private openHelpPopup;
|
|
832
834
|
static ɵfac: i0.ɵɵFactoryDeclaration<AXPKeyboardShortcutsHelpService, never>;
|
|
833
835
|
static ɵprov: i0.ɵɵInjectableDeclaration<AXPKeyboardShortcutsHelpService>;
|
|
834
836
|
}
|
|
@@ -4152,7 +4154,6 @@ declare function downloadGraphicFromElement(container: HTMLElement, options: AXP
|
|
|
4152
4154
|
|
|
4153
4155
|
declare class AXPExportService {
|
|
4154
4156
|
popupService: AXPopupService;
|
|
4155
|
-
private readonly dialogOpener;
|
|
4156
4157
|
generateBlobFromElement(element: HTMLElement, blobOptions?: AXPDomToImageOptions): Promise<Blob>;
|
|
4157
4158
|
download(blob: Blob, filename: string): void;
|
|
4158
4159
|
static ɵfac: i0.ɵɵFactoryDeclaration<AXPExportService, never>;
|
|
@@ -2990,6 +2990,8 @@ declare class AXPRepeaterRowsLayoutComponent {
|
|
|
2990
2990
|
disabled: _angular_core.InputSignal<boolean>;
|
|
2991
2991
|
hasControls: _angular_core.InputSignal<boolean>;
|
|
2992
2992
|
allowReorder: _angular_core.InputSignal<boolean>;
|
|
2993
|
+
/** Opt-in: put Add next to last-row Remove. Default keeps footer Add Item for other repeaters. */
|
|
2994
|
+
inlineAddControl: _angular_core.InputSignal<boolean>;
|
|
2993
2995
|
rowTemplate: _angular_core.InputSignal<TemplateRef<{
|
|
2994
2996
|
index: number;
|
|
2995
2997
|
}>>;
|
|
@@ -3007,7 +3009,7 @@ declare class AXPRepeaterRowsLayoutComponent {
|
|
|
3007
3009
|
protected onAddClick(): void;
|
|
3008
3010
|
protected onRemoveClick(index: number): void;
|
|
3009
3011
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXPRepeaterRowsLayoutComponent, never>;
|
|
3010
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXPRepeaterRowsLayoutComponent, "axp-repeater-rows-layout", never, { "count": { "alias": "count"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hasControls": { "alias": "hasControls"; "required": false; "isSignal": true; }; "allowReorder": { "alias": "allowReorder"; "required": false; "isSignal": true; }; "rowTemplate": { "alias": "rowTemplate"; "required": true; "isSignal": true; }; "addItemLabelKey": { "alias": "addItemLabelKey"; "required": false; "isSignal": true; }; "emptyTitleKey": { "alias": "emptyTitleKey"; "required": false; "isSignal": true; }; "emptyDescriptionKey": { "alias": "emptyDescriptionKey"; "required": false; "isSignal": true; }; "addFirstItemLabelKey": { "alias": "addFirstItemLabelKey"; "required": false; "isSignal": true; }; }, { "addClick": "addClick"; "removeClick": "removeClick"; "drop": "drop"; }, never, never, true, never>;
|
|
3012
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXPRepeaterRowsLayoutComponent, "axp-repeater-rows-layout", never, { "count": { "alias": "count"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hasControls": { "alias": "hasControls"; "required": false; "isSignal": true; }; "allowReorder": { "alias": "allowReorder"; "required": false; "isSignal": true; }; "inlineAddControl": { "alias": "inlineAddControl"; "required": false; "isSignal": true; }; "rowTemplate": { "alias": "rowTemplate"; "required": true; "isSignal": true; }; "addItemLabelKey": { "alias": "addItemLabelKey"; "required": false; "isSignal": true; }; "emptyTitleKey": { "alias": "emptyTitleKey"; "required": false; "isSignal": true; }; "emptyDescriptionKey": { "alias": "emptyDescriptionKey"; "required": false; "isSignal": true; }; "addFirstItemLabelKey": { "alias": "addFirstItemLabelKey"; "required": false; "isSignal": true; }; }, { "addClick": "addClick"; "removeClick": "removeClick"; "drop": "drop"; }, never, never, true, never>;
|
|
3011
3013
|
}
|
|
3012
3014
|
|
|
3013
3015
|
/** Scheduler appointment with optional provider tag for context menu routing. */
|
|
@@ -1633,6 +1633,11 @@ declare class AXPEntityMasterListViewModel {
|
|
|
1633
1633
|
title: string;
|
|
1634
1634
|
} | null>;
|
|
1635
1635
|
parentKey: _angular_core.Signal<string | undefined>;
|
|
1636
|
+
/**
|
|
1637
|
+
* Tree column only while the list is unfiltered roots.
|
|
1638
|
+
* An active filter returns a flat page; keeping parentField would drop child rows and page by the flat total.
|
|
1639
|
+
*/
|
|
1640
|
+
gridParentField: _angular_core.Signal<string | undefined>;
|
|
1636
1641
|
hasSelectedItems: _angular_core.Signal<boolean>;
|
|
1637
1642
|
clearSelection(): void;
|
|
1638
1643
|
/**
|
|
@@ -1649,6 +1654,7 @@ declare class AXPEntityMasterListViewModel {
|
|
|
1649
1654
|
*/
|
|
1650
1655
|
categoryListFilters: _angular_core.WritableSignal<AXPFilterQuery[]>;
|
|
1651
1656
|
setCategoryListFilters(filters: AXPFilterQuery[]): void;
|
|
1657
|
+
private hasActiveListFilter;
|
|
1652
1658
|
title: _angular_core.Signal<string>;
|
|
1653
1659
|
description: _angular_core.Signal<string | null>;
|
|
1654
1660
|
filterDefinitions: _angular_core.WritableSignal<AXPEntityListFilterDefinition[]>;
|
|
@@ -2553,7 +2559,8 @@ interface AXPEntityDeletePerformInput {
|
|
|
2553
2559
|
meta?: unknown;
|
|
2554
2560
|
}
|
|
2555
2561
|
/**
|
|
2556
|
-
* Deletes one or more entity records
|
|
2562
|
+
* Deletes one or more entity records.
|
|
2563
|
+
* A custom `commands.delete.execute` runs once per id. The crud default stays on the bulk API.
|
|
2557
2564
|
*/
|
|
2558
2565
|
declare class AXPEntityDeletePerformService {
|
|
2559
2566
|
private readonly entityRegistry;
|
|
@@ -229,6 +229,12 @@ declare abstract class AXPValueWidgetComponent<T = any | null, TOptions extends
|
|
|
229
229
|
/** Applies schema default without marking the form as user-edited. */
|
|
230
230
|
protected applyDefaultValue(value: T | null | undefined): void;
|
|
231
231
|
setValue(value: T | null | undefined): void;
|
|
232
|
+
/**
|
|
233
|
+
* Repeater clones pass the row index onto every descendant. Attach that index
|
|
234
|
+
* to the ancestor array path (`rows[0].field`), not after the leaf (`rows.field.[0]`).
|
|
235
|
+
* Lodash paths need `rows[0].field` — a dotted `.[0].` segment is a literal key.
|
|
236
|
+
*/
|
|
237
|
+
private joinIndexedWidgetPath;
|
|
232
238
|
protected detectFullPath(): void;
|
|
233
239
|
protected handleValueChanged(e: AXValueChangedEvent<T>): void;
|
|
234
240
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXPValueWidgetComponent<any, any>, never>;
|
|
@@ -243,6 +249,8 @@ declare abstract class AXPDataListWidgetComponent extends AXPValueWidgetComponen
|
|
|
243
249
|
protected valueField: _angular_core.Signal<string>;
|
|
244
250
|
protected textTemplate: _angular_core.Signal<string | undefined>;
|
|
245
251
|
protected dataSource: _angular_core.WritableSignal<AXDataSource<any>>;
|
|
252
|
+
/** AXDataSource instance from options that the isolated widget copy was built from. */
|
|
253
|
+
private boundRemoteDataSource;
|
|
246
254
|
/** Query key from options, when options.dataSource is a string or `{ id }` object. */
|
|
247
255
|
protected queryDataSourceName: _angular_core.Signal<string | null>;
|
|
248
256
|
selectedItems: _angular_core.WritableSignal<any[]>;
|
|
@@ -911,15 +919,35 @@ declare class AXPWidgetRendererDirective {
|
|
|
911
919
|
/**
|
|
912
920
|
* True when a context store path used in an expression (`context.eval`, `context.options`) is
|
|
913
921
|
* affected by `changedPath`.
|
|
922
|
+
*
|
|
923
|
+
* Do not drop `repeaterRowIndexConflicts` or re-enable last-segment matching across rows.
|
|
924
|
+
* `applicationRoleRows[0].applicationId` and `applicationRoleRows[1].applicationId` share the
|
|
925
|
+
* suffix `applicationId`; treating that as a match clears sibling repeater fields (roles).
|
|
926
|
+
* Canonical: `libs/framework/client/layout/widget-core/README.md` (repeater context isolation).
|
|
914
927
|
*/
|
|
915
928
|
private contextStorePathDependsOnChangedPath;
|
|
929
|
+
/**
|
|
930
|
+
* Different indexed rows of the same array must not share context events.
|
|
931
|
+
* `rows[0].applicationId` must not match `rows[1].applicationId` via suffix (`applicationId`).
|
|
932
|
+
* Bare `rows` (no `[n]`) still matches every indexed child so list-wide expressions can refresh.
|
|
933
|
+
* Do not remove this gate or “simplify” it back to suffix-only matching.
|
|
934
|
+
*/
|
|
935
|
+
private repeaterRowIndexConflicts;
|
|
916
936
|
/**
|
|
917
937
|
* Whether an expression template string reads context store paths affected by `changedPath`.
|
|
938
|
+
*
|
|
939
|
+
* Unresolved `>field` (parentPath empty) is `field` only — never suffix-match every `*.field`.
|
|
940
|
+
* Do not fold `>` back into generic suffix matching.
|
|
918
941
|
*/
|
|
919
942
|
private expressionTextDependsOnContextPath;
|
|
920
943
|
private hasExpressionDependency;
|
|
921
944
|
private isPathAlias;
|
|
922
945
|
private getExpressionValueFromNode;
|
|
946
|
+
/**
|
|
947
|
+
* `events.context('>field')` is this row only (exact resolved path).
|
|
948
|
+
* Do not use `*field` / suffix matching for row-local reset triggers — that fires on every
|
|
949
|
+
* repeater row that has a field of the same name.
|
|
950
|
+
*/
|
|
923
951
|
private hasTriggerDependency;
|
|
924
952
|
private hasVisibilityDependency;
|
|
925
953
|
ngOnChanges(changes: SimpleChanges): void;
|
|
@@ -934,8 +962,19 @@ declare class AXPWidgetRendererDirective {
|
|
|
934
962
|
private show;
|
|
935
963
|
private hide;
|
|
936
964
|
private evaluateExpression;
|
|
965
|
+
/**
|
|
966
|
+
* Repeater-relative paths (`>applicationId`) resolve against this widget's parent
|
|
967
|
+
* row (`applicationRoleRows[0].applicationId`), not every field with the same name.
|
|
968
|
+
* When `parentPath` is empty the result is the bare field — callers must not treat that
|
|
969
|
+
* as “any `*.applicationId`”.
|
|
970
|
+
*/
|
|
971
|
+
private resolveRowRelativeContextPath;
|
|
937
972
|
private buildExpressionScope;
|
|
938
973
|
private getContextScope;
|
|
974
|
+
/**
|
|
975
|
+
* `events.context('>…')` is exact row path only. Do not OR it with
|
|
976
|
+
* `contextStorePathDependsOnChangedPath` — that suffix-matches sibling rows.
|
|
977
|
+
*/
|
|
939
978
|
private getEventScope;
|
|
940
979
|
private getWidgetScope;
|
|
941
980
|
private getFunctionScope;
|
|
@@ -1616,16 +1616,25 @@ interface AXPRichTextWidgetOptions {
|
|
|
1616
1616
|
column: AXPRichTextWidgetColumnOptions;
|
|
1617
1617
|
}
|
|
1618
1618
|
|
|
1619
|
-
declare class AXPSelectBoxWidgetColumnComponent extends AXPColumnWidgetComponent<
|
|
1619
|
+
declare class AXPSelectBoxWidgetColumnComponent extends AXPColumnWidgetComponent<unknown> implements OnInit {
|
|
1620
|
+
private readonly queryService;
|
|
1621
|
+
private readonly localStore;
|
|
1622
|
+
private readonly destroyRef;
|
|
1623
|
+
private readonly activeTextField;
|
|
1624
|
+
private readonly activeValueField;
|
|
1620
1625
|
protected textField: _angular_core.Signal<string>;
|
|
1621
1626
|
protected valueField: _angular_core.Signal<string>;
|
|
1622
1627
|
protected cssClassField: _angular_core.Signal<string | undefined>;
|
|
1623
1628
|
protected badgeClass: _angular_core.Signal<string | undefined>;
|
|
1624
|
-
|
|
1629
|
+
private readonly displayRows;
|
|
1630
|
+
private destroyed;
|
|
1625
1631
|
protected internalValue: _angular_core.Signal<Record<string, unknown>[]>;
|
|
1632
|
+
ngOnInit(): void;
|
|
1626
1633
|
protected resolveBadgeClasses(item: unknown): string;
|
|
1627
1634
|
protected getItemLabel(item: unknown): string | Record<string, string>;
|
|
1628
|
-
private
|
|
1635
|
+
private loadRows;
|
|
1636
|
+
private resolveSlots;
|
|
1637
|
+
private readLocalItems;
|
|
1629
1638
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXPSelectBoxWidgetColumnComponent, never>;
|
|
1630
1639
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXPSelectBoxWidgetColumnComponent, "axp-select-box-widget-column", never, { "rawValue": { "alias": "rawValue"; "required": false; }; "rowData": { "alias": "rowData"; "required": false; }; }, {}, never, never, true, never>;
|
|
1631
1640
|
}
|
|
@@ -1674,6 +1683,8 @@ declare class AXPSelectBoxWidgetEditComponent extends AXPDataListWidgetComponent
|
|
|
1674
1683
|
/**
|
|
1675
1684
|
* True when a cascade/parent filter is configured but required values are still empty
|
|
1676
1685
|
* (e.g. state select before country is chosen).
|
|
1686
|
+
* `not-in` / `nin` are not cascade — treating them as pending disables the control
|
|
1687
|
+
* (not-allowed cursor, empty list). Hide already-picked options with `excludeIds`, not `filter`.
|
|
1677
1688
|
*/
|
|
1678
1689
|
protected hasPendingCascadeFilter: _angular_core.Signal<boolean>;
|
|
1679
1690
|
/** Only swap datasource when cascade parent is missing. */
|
|
@@ -1721,6 +1732,12 @@ declare class AXPSelectBoxWidgetEditComponent extends AXPDataListWidgetComponent
|
|
|
1721
1732
|
*/
|
|
1722
1733
|
private syncExposePathsToSavedBaseline;
|
|
1723
1734
|
private remapComboItems;
|
|
1735
|
+
/**
|
|
1736
|
+
* Drop ids in `excludeIds` except this widget's current value so the selected item stays visible.
|
|
1737
|
+
* Do not filter out the current row's own id — the dropdown would go empty after pick.
|
|
1738
|
+
*/
|
|
1739
|
+
private excludeOptionRows;
|
|
1740
|
+
private applyArrayWidgetFilter;
|
|
1724
1741
|
/**
|
|
1725
1742
|
* Patches lookup `load` so widget/cascade filters are AND-ed with lookup search,
|
|
1726
1743
|
* and so a pending cascade parent returns an empty page.
|
|
@@ -4314,6 +4331,7 @@ declare class AXPRepeaterWidgetEditComponent extends AXPValueWidgetComponent<any
|
|
|
4314
4331
|
protected disabled: _angular_core.Signal<boolean>;
|
|
4315
4332
|
protected hasControls: _angular_core.Signal<boolean>;
|
|
4316
4333
|
protected allowReorder: _angular_core.Signal<boolean>;
|
|
4334
|
+
protected inlineAddControl: _angular_core.Signal<boolean>;
|
|
4317
4335
|
protected rows: _angular_core.Signal<any[]>;
|
|
4318
4336
|
onDrop(e: AXDropListDroppedEvent): void;
|
|
4319
4337
|
protected handleAddItemClick(): void;
|
|
@@ -4350,6 +4368,8 @@ interface AXPRepeaterWidgetEditOptions {
|
|
|
4350
4368
|
disabled?: boolean;
|
|
4351
4369
|
hasControls?: boolean;
|
|
4352
4370
|
allowReorder?: boolean;
|
|
4371
|
+
/** When true, Add sits on the last row (opt-in). Default keeps footer Add Item. */
|
|
4372
|
+
inlineAddControl?: boolean;
|
|
4353
4373
|
/** Cloned into each new row. Missing `id` values are generated. */
|
|
4354
4374
|
defaultItem?: Record<string, unknown>;
|
|
4355
4375
|
}
|
|
@@ -5274,9 +5294,9 @@ declare class AXPFlexOptionsWidgetEditComponent extends AXPValueWidgetComponent<
|
|
|
5274
5294
|
protected flexDirectionIsColumn: _angular_core.Signal<boolean | undefined>;
|
|
5275
5295
|
protected flexDirectionIsReverse: _angular_core.Signal<boolean | undefined>;
|
|
5276
5296
|
protected flexDirectionWithoutReverse: _angular_core.Signal<string | undefined>;
|
|
5277
|
-
protected gapMode: _angular_core.WritableSignal<"
|
|
5297
|
+
protected gapMode: _angular_core.WritableSignal<"both" | "single">;
|
|
5278
5298
|
protected gapUnit: _angular_core.WritableSignal<string>;
|
|
5279
|
-
protected gap: _angular_core.WritableSignal<Record<"
|
|
5299
|
+
protected gap: _angular_core.WritableSignal<Record<"both" | "x" | "y", number>>;
|
|
5280
5300
|
protected lastGap: _angular_core.WritableSignal<number>;
|
|
5281
5301
|
protected selectedJustify: _angular_core.WritableSignal<AXPFlexBoxOption>;
|
|
5282
5302
|
protected selectedAlign: _angular_core.WritableSignal<AXPFlexBoxOption>;
|