@quadrel-enterprise-ui/framework 20.11.2-beta.150.1 → 20.11.2-beta.152.1

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.
@@ -3,13 +3,13 @@ import { inject, ElementRef, Directive, InjectionToken, HostBinding, Input, View
3
3
  import { Dialog, DialogRef, DialogModule } from '@angular/cdk/dialog';
4
4
  import * as i1 from '@angular/common';
5
5
  import { CommonModule, NgFor, NgIf, NgClass, NgTemplateOutlet, AsyncPipe } from '@angular/common';
6
- import { BehaviorSubject, pairwise, from, switchMap, map as map$1, Subject, throwError, of, ReplaySubject, merge, fromEvent, isObservable, NEVER, Observable, EMPTY, shareReplay, Subscription, distinctUntilChanged as distinctUntilChanged$1, debounce, timer, startWith as startWith$1, debounceTime as debounceTime$1, takeUntil as takeUntil$1, firstValueFrom, combineLatest, concat, take as take$1, delay, tap as tap$1, first, scan, queueScheduler, filter as filter$1, concatMap as concatMap$1, exhaustMap, finalize, combineLatestWith, forkJoin, delayWhen, withLatestFrom, async } from 'rxjs';
6
+ import { BehaviorSubject, pairwise, from, switchMap, map as map$1, Subject, throwError, of, ReplaySubject, merge, fromEvent, isObservable, NEVER, Observable, EMPTY, shareReplay, Subscription, distinctUntilChanged as distinctUntilChanged$1, debounce, timer, startWith as startWith$1, debounceTime as debounceTime$1, takeUntil as takeUntil$1, firstValueFrom, combineLatest, concat, take as take$1, delay, tap as tap$1, first, scan, queueScheduler, filter as filter$1, concatMap as concatMap$1, exhaustMap, finalize, forkJoin, delayWhen, combineLatestWith, withLatestFrom, async } from 'rxjs';
7
7
  import { map, takeUntil, take, filter, catchError, debounceTime, startWith, distinctUntilChanged, concatMap, tap, skip, auditTime, observeOn, switchMap as switchMap$1, pairwise as pairwise$1, mergeMap, delay as delay$1 } from 'rxjs/operators';
8
8
  import { v4 } from 'uuid';
9
9
  import * as i3 from '@ngx-translate/core';
10
10
  import { TranslateService, TranslateModule } from '@ngx-translate/core';
11
11
  import * as i2$1 from '@angular/router';
12
- import { Router, ActivationEnd, RouterModule, ActivatedRoute, NavigationError, NavigationCancel, NavigationEnd, NavigationStart } from '@angular/router';
12
+ import { Router, ActivationEnd, RouterModule, ActivatedRoute, NavigationEnd, NavigationCancel, NavigationError, NavigationStart } from '@angular/router';
13
13
  import { HttpStatusCode, HttpEventType, HttpClient, HttpParams, HTTP_INTERCEPTORS } from '@angular/common/http';
14
14
  import * as _ from 'lodash';
15
15
  import { upperCase, lowerFirst, isEqual, range, get as get$1, cloneDeep, union, isNumber as isNumber$1 } from 'lodash';
@@ -7104,6 +7104,277 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7104
7104
  }]
7105
7105
  }] });
7106
7106
 
7107
+ /**
7108
+ * Framework-wide funnel for syncing application state with the URL `?key=value` query string.
7109
+ *
7110
+ * Several Quadrel features mirror their state to the URL — the table's sort and pagination today,
7111
+ * filter, search, and `qd-page-tabs` over time. Without coordination they each call
7112
+ * `router.navigate(...)` directly, which produces two failure modes:
7113
+ *
7114
+ * 1. **Race**: two navigates issued in the same JS turn cancel each other. Only the last writer
7115
+ * wins; the URL silently loses the cancelled feature's params.
7116
+ * 2. **History pollution**: a single user action that changes two features (e.g. clicking a sort
7117
+ * header resets the page index) ends up as two history entries. Browser-back only undoes one.
7118
+ *
7119
+ * `QdRouterQueryParamHubService` is the single funnel through which features run their query-param
7120
+ * reads and writes. It does three jobs:
7121
+ *
7122
+ * - **Ownership** — `claim()` / `release()` enforce one writer per param key, app-wide.
7123
+ * - **Shared reads** — `queryParams()` and `snapshotQueryParam()` expose the route state without
7124
+ * each feature needing its own `ActivatedRoute` subscription.
7125
+ * - **Coordinated writes** — `write()` buffers param updates within a microtask and serializes
7126
+ * navigations via a Promise chain, so two writes in the same JS turn become one history entry
7127
+ * and concurrent writes never race.
7128
+ *
7129
+ * The hub is feature-agnostic. Per-feature adapters (e.g. `QdTableSortRouterConnectorService`)
7130
+ * own their parsing/serialization and delegate the URL plumbing to the hub.
7131
+ *
7132
+ * ### Usage
7133
+ *
7134
+ * ```ts
7135
+ * @Injectable()
7136
+ * export class FilterRouterAdapterService {
7137
+ * private readonly _hub = inject(QdRouterQueryParamHubService);
7138
+ * private readonly _destroyRef = inject(DestroyRef);
7139
+ *
7140
+ * connect(state$: Observable<FilterState>, dispatch: (state: FilterState) => void): void {
7141
+ * if (!this._hub.isAvailable()) return;
7142
+ * if (!this._hub.claim(['filter'], this, this._destroyRef)) return;
7143
+ *
7144
+ * this._hub
7145
+ * .queryParams()
7146
+ * .pipe(takeUntilDestroyed(this._destroyRef))
7147
+ * .subscribe(params => dispatch(parseFilter(params['filter'])));
7148
+ *
7149
+ * state$
7150
+ * .pipe(takeUntilDestroyed(this._destroyRef))
7151
+ * .subscribe(state => this._hub.write({ filter: serializeFilter(state) }, false));
7152
+ * }
7153
+ * }
7154
+ * ```
7155
+ */
7156
+ class QdRouterQueryParamHubService {
7157
+ /**
7158
+ * Replays whenever the router has finished a navigation (`NavigationEnd`, `NavigationCancel`
7159
+ * or `NavigationError` — every event that ends a navigation, regardless of outcome).
7160
+ * Adapters that want to delay a write until any in-flight navigation has settled can take(1)
7161
+ * on this stream before calling `write()`.
7162
+ *
7163
+ * Late subscribers receive the most recent settling event immediately, so an adapter that
7164
+ * mounts after the initial route navigation can observe the route as already-settled. The
7165
+ * first replayed tick may represent that initial route navigation rather than a user-driven
7166
+ * settling event — adapters that need to distinguish "the route just changed" should compare
7167
+ * `ActivatedRoute.snapshot` themselves.
7168
+ *
7169
+ * **When the hub is unavailable** (no `Router` / `ActivatedRoute` in the injector — see
7170
+ * `isAvailable()`) this observable never emits. Adapters that compose `navigationSettled$`
7171
+ * via operators like `switchMap` or `concat` must guard with `isAvailable()` first, otherwise
7172
+ * their pipelines hang silently.
7173
+ */
7174
+ navigationSettled$;
7175
+ _router = inject(Router, { optional: true });
7176
+ _activatedRoute = inject(ActivatedRoute, { optional: true });
7177
+ _destroyRef = inject(DestroyRef);
7178
+ _ownership = new Map();
7179
+ _destroyClaims = new WeakMap();
7180
+ _navigationSettledSubject = new ReplaySubject(1);
7181
+ _pendingParams = {};
7182
+ _pendingReplaceUrl = false;
7183
+ _flushScheduled = false;
7184
+ _navigationChain = Promise.resolve();
7185
+ constructor() {
7186
+ this.navigationSettled$ = this._navigationSettledSubject.asObservable();
7187
+ if (!this._router || !this._activatedRoute)
7188
+ return;
7189
+ this.replayCurrentRouterStateForLateSubscribers(this._router);
7190
+ this.forwardSettlingRouterEventsToNavigationSettled(this._router);
7191
+ }
7192
+ /**
7193
+ * Returns whether the hub can sync at all. False when the consuming injector has neither a
7194
+ * `Router` nor an `ActivatedRoute` available — for example in unit tests that omit
7195
+ * `RouterTestingModule`. Adapters should bail out early when this returns false.
7196
+ */
7197
+ isAvailable() {
7198
+ return !!this._router && !!this._activatedRoute;
7199
+ }
7200
+ /**
7201
+ * Reserves exclusive write access to the given query-param keys for `owner`.
7202
+ *
7203
+ * The same `owner` may claim the same keys repeatedly without conflict — claims are idempotent
7204
+ * per owner. A different owner attempting to claim an already-claimed key fails: the hub logs
7205
+ * a `console.error` listing every contested key and returns `false`. The original owner keeps
7206
+ * the keys until it calls `release()` (or until its `DestroyRef` fires, if a `destroyRef` is
7207
+ * passed here).
7208
+ *
7209
+ * Atomicity: when the call fails, no keys are claimed, even partially. The hub checks every
7210
+ * requested key against the registry before mutating anything.
7211
+ *
7212
+ * **Pass `destroyRef` to opt into auto-release.** Without it, the hub keeps a strong reference
7213
+ * to `owner` until `release()` is called manually — a destroyed adapter that forgets to release
7214
+ * pins itself in the registry. Passing the adapter's `DestroyRef` registers an `onDestroy`
7215
+ * callback that releases exactly the keys claimed via this call (and any later claims that
7216
+ * reuse the same `destroyRef`), which is the recommended path.
7217
+ *
7218
+ * Each `destroyRef` releases only the keys it owns. If the same owner uses two different
7219
+ * `DestroyRef`s in two `claim()` calls, each fires independently and only releases its own
7220
+ * keys — keys claimed via the still-alive `destroyRef` stay reserved.
7221
+ *
7222
+ * Re-claiming with the same `destroyRef` appends to the same destroy listener — no duplicate
7223
+ * listeners are registered, even when the second claim names a different owner. Each appended
7224
+ * entry carries its own owner, so when the `destroyRef` fires the hub releases each entry's
7225
+ * keys against that entry's owner. An empty `keys` array is a no-op even when `destroyRef`
7226
+ * is provided: no listener is attached, so the hub does not pin a destroy hook that would
7227
+ * release nothing.
7228
+ *
7229
+ * @param keys The query-param keys this adapter wants to own (e.g. `['sort']`, `['page', 'size']`).
7230
+ * @param owner Stable identity of the caller — usually `this`. Used as the registry key.
7231
+ * @param destroyRef Optional. If provided, the hub releases the keys automatically when the
7232
+ * `DestroyRef` fires. Pass the adapter's `inject(DestroyRef)` to make leaks impossible.
7233
+ * @returns `true` if every requested key is now owned by `owner`. `false` if at least one key
7234
+ * was already owned by a different adapter; the registry is left untouched and `destroyRef`
7235
+ * is not registered.
7236
+ */
7237
+ claim(keys, owner, destroyRef) {
7238
+ const conflicts = [];
7239
+ for (const key of keys) {
7240
+ const existing = this._ownership.get(key);
7241
+ if (existing && existing !== owner)
7242
+ conflicts.push(key);
7243
+ }
7244
+ if (conflicts.length > 0) {
7245
+ const list = conflicts.map(k => `"${k}"`).join(', ');
7246
+ console.error(`Quadrel Framework | QdRouterQueryParamHub - Query param ${list} ${conflicts.length === 1 ? 'is' : 'are'} ` +
7247
+ `already owned by another adapter. Disable the conflicting feature's URL sync or move it to a ` +
7248
+ `different param key.`);
7249
+ return false;
7250
+ }
7251
+ keys.forEach(key => this._ownership.set(key, owner));
7252
+ if (destroyRef && keys.length > 0)
7253
+ this.registerAutoRelease(owner, keys, destroyRef);
7254
+ return true;
7255
+ }
7256
+ /**
7257
+ * Drops `owner`'s claim on the given keys. Keys not owned by `owner` are left untouched —
7258
+ * a foreign release call cannot steal another adapter's ownership.
7259
+ *
7260
+ * Adapters typically release in their `DestroyRef.onDestroy` callback so a destroyed component
7261
+ * frees its keys for the next adapter that mounts.
7262
+ */
7263
+ release(keys, owner) {
7264
+ keys.forEach(key => {
7265
+ if (this._ownership.get(key) === owner)
7266
+ this._ownership.delete(key);
7267
+ });
7268
+ }
7269
+ /**
7270
+ * Reactive view of `ActivatedRoute.queryParams`. Returns the empty observable if the hub is
7271
+ * not available (no Router/ActivatedRoute). Adapters subscribe here instead of injecting
7272
+ * `ActivatedRoute` themselves so the hub stays the single read funnel.
7273
+ *
7274
+ * The observable is hot — late subscribers receive the current params immediately.
7275
+ */
7276
+ queryParams() {
7277
+ return this._activatedRoute?.queryParams ?? of({});
7278
+ }
7279
+ /**
7280
+ * Synchronous read of a single query param from the latest `ActivatedRoute` snapshot.
7281
+ * Adapters use this to detect "URL already matches the desired state" and skip a redundant
7282
+ * `write()`.
7283
+ *
7284
+ * @returns The param value, or `undefined` if the param is missing or the hub is unavailable.
7285
+ */
7286
+ snapshotQueryParam(key) {
7287
+ return this._activatedRoute?.snapshot.queryParamMap.get(key) ?? undefined;
7288
+ }
7289
+ /**
7290
+ * Schedules a query-param update.
7291
+ *
7292
+ * Two coordination guarantees:
7293
+ *
7294
+ * - **Microtask batching** — every `write()` issued in the same JavaScript turn is merged into
7295
+ * a single `router.navigate(...)` call. A user action that changes two features at once
7296
+ * (e.g. sort change resets the page) becomes one history entry, not two. Note: batching is
7297
+ * per JS turn, not per logical user action — writes that fall into the next microtask after
7298
+ * a settled navigation produce a separate history entry, even when they belong to the same
7299
+ * conceptual gesture.
7300
+ * - **Serialized navigations** — flushes are chained on a Promise so a second flush only fires
7301
+ * after the previous `router.navigate` has settled. Concurrent navigates can therefore not
7302
+ * cancel each other. A rejected `router.navigate` (cancelled by a guard, redirected, or
7303
+ * failed) does not stop the chain — the next pending flush still runs. Rejections are not
7304
+ * logged here; consumers that need routing diagnostics should subscribe to `router.events`.
7305
+ *
7306
+ * Adapters are still responsible for skipping no-op writes (compare the desired value against
7307
+ * `snapshotQueryParam()` first), since the hub does not deduplicate identical values.
7308
+ *
7309
+ * Setting a param value to `undefined` removes the param from the URL via Angular Router's
7310
+ * `merge` behavior. Other params not mentioned in the call are preserved.
7311
+ *
7312
+ * @param params Partial map of query-param keys to their new values. Missing keys are not touched.
7313
+ * An empty object short-circuits and is a no-op.
7314
+ * @param replaceUrl `true` replaces the current history entry; `false` pushes a new entry.
7315
+ * When several `write()` calls in the same microtask disagree, `true` wins (so an initial
7316
+ * replace is preserved when a follow-up write would otherwise push). The escalation is
7317
+ * per-batch — after each flush the pending flag resets to `false`, so writes that arrive
7318
+ * in the next microtask start a fresh batch with their own `replaceUrl` argument.
7319
+ */
7320
+ write(params, replaceUrl) {
7321
+ const router = this._router;
7322
+ const activatedRoute = this._activatedRoute;
7323
+ if (!router || !activatedRoute)
7324
+ return;
7325
+ if (Object.keys(params).length === 0)
7326
+ return;
7327
+ Object.assign(this._pendingParams, params);
7328
+ this._pendingReplaceUrl = this._pendingReplaceUrl || replaceUrl;
7329
+ if (this._flushScheduled)
7330
+ return;
7331
+ this._flushScheduled = true;
7332
+ Promise.resolve().then(() => this.flush(router, activatedRoute));
7333
+ }
7334
+ replayCurrentRouterStateForLateSubscribers(router) {
7335
+ if (router.navigated)
7336
+ this._navigationSettledSubject.next();
7337
+ }
7338
+ forwardSettlingRouterEventsToNavigationSettled(router) {
7339
+ router.events
7340
+ .pipe(filter(event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError), takeUntilDestroyed(this._destroyRef))
7341
+ .subscribe(() => this._navigationSettledSubject.next());
7342
+ }
7343
+ registerAutoRelease(owner, keys, destroyRef) {
7344
+ const existingClaims = this._destroyClaims.get(destroyRef);
7345
+ if (existingClaims) {
7346
+ existingClaims.push({ owner, keys });
7347
+ return;
7348
+ }
7349
+ const claims = [{ owner, keys }];
7350
+ this._destroyClaims.set(destroyRef, claims);
7351
+ destroyRef.onDestroy(() => {
7352
+ for (const claim of claims)
7353
+ this.release(claim.keys, claim.owner);
7354
+ });
7355
+ }
7356
+ flush(router, activatedRoute) {
7357
+ const params = this._pendingParams;
7358
+ const replaceUrl = this._pendingReplaceUrl;
7359
+ this._pendingParams = {};
7360
+ this._pendingReplaceUrl = false;
7361
+ this._flushScheduled = false;
7362
+ const exec = () => router.navigate([], {
7363
+ relativeTo: activatedRoute,
7364
+ queryParams: params,
7365
+ queryParamsHandling: 'merge',
7366
+ replaceUrl
7367
+ });
7368
+ this._navigationChain = this._navigationChain.catch(() => undefined).then(exec);
7369
+ }
7370
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7371
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, providedIn: 'root' });
7372
+ }
7373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, decorators: [{
7374
+ type: Injectable,
7375
+ args: [{ providedIn: 'root' }]
7376
+ }], ctorParameters: () => [] });
7377
+
7107
7378
  var breakpoints$1 = {
7108
7379
  xs: 320,
7109
7380
  sm: 600,
@@ -11246,6 +11517,7 @@ class QdInputComponent {
11246
11517
  this._isUserTyped = false;
11247
11518
  if (this.inputType === 'number') {
11248
11519
  this._value = { ...this._value, value: this.numberInputService.formatValueForDisplay(this._value.value) };
11520
+ this._displayValue = String(this._value.value ?? '');
11249
11521
  }
11250
11522
  }
11251
11523
  setDisabledState(disabled) {
@@ -11404,6 +11676,7 @@ class QdInputComponent {
11404
11676
  this._value = normalized;
11405
11677
  if (this.inputType === 'number') {
11406
11678
  this._value = { ...this._value, value: this.numberInputService.formatValueForDisplay(this._value.value) };
11679
+ this._displayValue = String(this._value.value ?? '');
11407
11680
  }
11408
11681
  }
11409
11682
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -22932,6 +23205,9 @@ class QdTableStoreSelectorService {
22932
23205
  return sort.find(entry => entry.column === column)?.direction ?? QdSortDirection.NONE;
22933
23206
  });
22934
23207
  }
23208
+ tableSort() {
23209
+ return createSelector(this.selectTables, tables => this.getTable(tables)?.sort);
23210
+ }
22935
23211
  selectIsLoading() {
22936
23212
  return createSelector(this.selectTables, tables => {
22937
23213
  const { requestState } = this.getTable(tables) || {};
@@ -23118,6 +23394,9 @@ class QdTableStoreService {
23118
23394
  columnSortDirection$(column) {
23119
23395
  return this.store.select(this.tableStoreSelectorService.columnSortDirection(column));
23120
23396
  }
23397
+ tableSort$() {
23398
+ return this.store.select(this.tableStoreSelectorService.tableSort());
23399
+ }
23121
23400
  selectIsLoading$() {
23122
23401
  return this.store.select(this.tableStoreSelectorService.selectIsLoading());
23123
23402
  }
@@ -23588,6 +23867,130 @@ var QdPaginatorDirection;
23588
23867
  QdPaginatorDirection[QdPaginatorDirection["LastPage"] = 3] = "LastPage";
23589
23868
  })(QdPaginatorDirection || (QdPaginatorDirection = {}));
23590
23869
 
23870
+ const PAGE_PARAM_NAME = 'page';
23871
+ const SIZE_PARAM_NAME = 'size';
23872
+ const OWNED_PARAMS$1 = [PAGE_PARAM_NAME, SIZE_PARAM_NAME];
23873
+ const SIZE_SANITY_MAX = 1000;
23874
+ class QdTablePaginationRouterConnectorService {
23875
+ hub = inject(QdRouterQueryParamHubService);
23876
+ destroyRef = inject(DestroyRef);
23877
+ _connection;
23878
+ _readSubscription;
23879
+ _writeSubscription;
23880
+ _activatedRouteCheckedSubject = new ReplaySubject(1);
23881
+ _activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
23882
+ _hasInitialUrlBeenSet = false;
23883
+ constructor() {
23884
+ this.destroyRef.onDestroy(() => {
23885
+ this.tearDownConnection();
23886
+ this.hub.release(OWNED_PARAMS$1, this);
23887
+ });
23888
+ }
23889
+ connectPaginationWithRouter(paginator, tableStoreService) {
23890
+ if (!paginator.shouldConnectWithRouter() || !this.hub.isAvailable())
23891
+ return of(false);
23892
+ if (!this.hub.claim(OWNED_PARAMS$1, this))
23893
+ return of(false);
23894
+ this._connection = {
23895
+ paginator: paginator,
23896
+ tableStoreService: tableStoreService
23897
+ };
23898
+ this._hasInitialUrlBeenSet = false;
23899
+ this._activatedRouteCheckedSubject = new ReplaySubject(1);
23900
+ this._activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
23901
+ this.subscribeToUrlChanges();
23902
+ this.subscribeToStoreChanges();
23903
+ return this._activatedRouteChecked$;
23904
+ }
23905
+ disconnectPaginationFromRouter(paginator) {
23906
+ if (this._connection?.paginator !== paginator)
23907
+ return;
23908
+ this.tearDownConnection();
23909
+ this.hub.release(OWNED_PARAMS$1, this);
23910
+ }
23911
+ tearDownConnection() {
23912
+ this._connection = undefined;
23913
+ this._hasInitialUrlBeenSet = false;
23914
+ this._readSubscription?.unsubscribe();
23915
+ this._writeSubscription?.unsubscribe();
23916
+ }
23917
+ subscribeToUrlChanges() {
23918
+ const { tableStoreService } = this._connection;
23919
+ let isFirstEmit = true;
23920
+ this._readSubscription = this.hub.navigationSettled$
23921
+ .pipe(switchMap(() => this.hub.queryParams()), map(queryParams => this.parseUrlParams(queryParams)), distinctUntilChanged((a, b) => a.page === b.page && a.size === b.size), switchMap(params => combineLatest([tableStoreService.pageChangeInfo$(), tableStoreService.totalCount$()]).pipe(take(1), map(([currentInfo, totalCount]) => ({ params, currentInfo, totalCount })))))
23922
+ .subscribe(({ params, currentInfo, totalCount }) => {
23923
+ const target = this.toStoreState(params);
23924
+ const isChanged = !currentInfo || currentInfo.pageIndex !== target.pageIndex || currentInfo.pageSize !== target.pageSize;
23925
+ if (isChanged) {
23926
+ tableStoreService.setPageParams(target.pageIndex, target.pageSize, totalCount);
23927
+ }
23928
+ if (isFirstEmit) {
23929
+ this._activatedRouteCheckedSubject.next(true);
23930
+ isFirstEmit = false;
23931
+ }
23932
+ });
23933
+ }
23934
+ subscribeToStoreChanges() {
23935
+ const { tableStoreService } = this._connection;
23936
+ this._writeSubscription = tableStoreService
23937
+ .pageChangeInfo$()
23938
+ .pipe(filter((info) => info !== undefined), distinctUntilChanged((a, b) => a.pageIndex === b.pageIndex && a.pageSize === b.pageSize), switchMap(info => this.hub.navigationSettled$.pipe(take(1), map(() => info))))
23939
+ .subscribe(info => this.writeUrl(info.pageIndex, info.pageSize));
23940
+ }
23941
+ writeUrl(pageIndex, pageSize) {
23942
+ const replaceUrl = !this._hasInitialUrlBeenSet;
23943
+ this._hasInitialUrlBeenSet = true;
23944
+ const targetPage = String(pageIndex + 1);
23945
+ const targetSize = String(pageSize);
23946
+ const urlAlreadyMatches = this.hub.snapshotQueryParam(PAGE_PARAM_NAME) === targetPage &&
23947
+ this.hub.snapshotQueryParam(SIZE_PARAM_NAME) === targetSize;
23948
+ if (urlAlreadyMatches)
23949
+ return;
23950
+ this.hub.write({ [PAGE_PARAM_NAME]: targetPage, [SIZE_PARAM_NAME]: targetSize }, replaceUrl);
23951
+ }
23952
+ parseUrlParams(queryParams) {
23953
+ const result = {};
23954
+ const rawPage = queryParams[PAGE_PARAM_NAME];
23955
+ if (typeof rawPage === 'string' && this.isValidPositiveIntegerString(rawPage)) {
23956
+ result.page = Number(rawPage);
23957
+ }
23958
+ const rawSize = queryParams[SIZE_PARAM_NAME];
23959
+ if (typeof rawSize === 'string' &&
23960
+ this.isValidPositiveIntegerString(rawSize) &&
23961
+ this.isValidSize(Number(rawSize))) {
23962
+ result.size = Number(rawSize);
23963
+ }
23964
+ return result;
23965
+ }
23966
+ isValidPositiveIntegerString(raw) {
23967
+ return /^[1-9]\d*$/.test(raw);
23968
+ }
23969
+ isValidSize(value) {
23970
+ const pageSizes = this.getConfiguredPageSizes();
23971
+ if (pageSizes && pageSizes.length > 0) {
23972
+ return pageSizes.includes(value);
23973
+ }
23974
+ return value <= SIZE_SANITY_MAX;
23975
+ }
23976
+ getConfiguredPageSizes() {
23977
+ const pagination = this._connection?.paginator.config?.pagination;
23978
+ return typeof pagination === 'object' ? pagination.pageSizes : undefined;
23979
+ }
23980
+ toStoreState(params) {
23981
+ const { paginator } = this._connection;
23982
+ return {
23983
+ pageIndex: params.page !== undefined ? params.page - 1 : 0,
23984
+ pageSize: params.size ?? paginator.getPageSizeDefault()
23985
+ };
23986
+ }
23987
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23988
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService });
23989
+ }
23990
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService, decorators: [{
23991
+ type: Injectable
23992
+ }], ctorParameters: () => [] });
23993
+
23591
23994
  class QdScrollingService {
23592
23995
  scrollIntoViewIfNeeded(element, borderDirection = 'top', targetBorderDistance = 0) {
23593
23996
  this.scrollIntoView(element, borderDirection, targetBorderDistance, true);
@@ -23816,6 +24219,7 @@ const PAGE_SIZE_DEFAULT = 25;
23816
24219
  class QdTablePaginatorComponent {
23817
24220
  tableDataResolver = inject(QD_TABLE_DATA_RESOLVER_TOKEN, { optional: true });
23818
24221
  tableStoreService = inject(QdTableStoreService);
24222
+ routerConnector = inject(QdTablePaginationRouterConnectorService);
23819
24223
  /**
23820
24224
  * @description Configuration Model for Qd-Table.
23821
24225
  */
@@ -23852,11 +24256,39 @@ class QdTablePaginatorComponent {
23852
24256
  this.totalCount$ = this.tableStoreService.totalCount$();
23853
24257
  this.selectedRowsCount$ = this.tableStoreService.selectedRows$().pipe(map(ids => ids?.length ?? 0));
23854
24258
  if (this.isConfigValid())
23855
- this.initPagination();
24259
+ this.startPagination();
23856
24260
  }
23857
24261
  ngOnDestroy() {
24262
+ this.routerConnector.disconnectPaginationFromRouter(this);
24263
+ this._destroyed$.next(null);
23858
24264
  this._destroyed$.complete();
23859
24265
  }
24266
+ /**
24267
+ * @description Whether this paginator should sync its state with the URL. Reads
24268
+ * `pagination.connectWithRouter` (default `false` — URL sync is opt-in and
24269
+ * requires an explicit `pagination: { connectWithRouter: true }`).
24270
+ *
24271
+ * Used by `QdTablePaginationRouterConnectorService` to decide whether to claim
24272
+ * the router-singleton for this paginator.
24273
+ */
24274
+ shouldConnectWithRouter() {
24275
+ const pagination = this.config?.pagination;
24276
+ if (typeof pagination !== 'object')
24277
+ return false;
24278
+ return pagination.connectWithRouter === true;
24279
+ }
24280
+ /**
24281
+ * @description The effective default page size for this paginator. Resolves
24282
+ * `pagination.pageSizeDefault` first, then falls back to the first entry of
24283
+ * `pagination.pageSizes`, finally to the framework constant `PAGE_SIZE_DEFAULT`.
24284
+ */
24285
+ getPageSizeDefault() {
24286
+ if (typeof this.config?.pagination !== 'object')
24287
+ return PAGE_SIZE_DEFAULT;
24288
+ const { pageSizeDefault, pageSizes } = this.config.pagination;
24289
+ const pageSize = pageSizes && pageSizes.length ? pageSizes[0] : PAGE_SIZE_DEFAULT;
24290
+ return pageSizeDefault || pageSize;
24291
+ }
23860
24292
  navigateToPage(direction) {
23861
24293
  if (!this.paginatorButtons)
23862
24294
  return;
@@ -23877,16 +24309,22 @@ class QdTablePaginatorComponent {
23877
24309
  }
23878
24310
  return true;
23879
24311
  }
24312
+ startPagination() {
24313
+ if (!this.shouldConnectWithRouter()) {
24314
+ this.initPagination();
24315
+ return;
24316
+ }
24317
+ this.routerConnector
24318
+ .connectPaginationWithRouter(this, this.tableStoreService)
24319
+ .pipe(takeUntil(this._destroyed$), first())
24320
+ .subscribe(connected => {
24321
+ if (!connected)
24322
+ this.initPagination();
24323
+ });
24324
+ }
23880
24325
  initPagination() {
23881
24326
  this.tableStoreService.setupPagination(this.getPageSizeDefault());
23882
24327
  }
23883
- getPageSizeDefault() {
23884
- if (typeof this.config?.pagination !== 'object')
23885
- return PAGE_SIZE_DEFAULT;
23886
- const { pageSizeDefault, pageSizes } = this.config.pagination;
23887
- const pageSize = pageSizes && pageSizes.length ? pageSizes[0] : PAGE_SIZE_DEFAULT;
23888
- return pageSizeDefault || pageSize;
23889
- }
23890
24328
  calculatePageNumber(direction, totalCount, pageSize, currentPage) {
23891
24329
  switch (direction) {
23892
24330
  case QdPaginatorDirection.NextPage: {
@@ -23905,11 +24343,11 @@ class QdTablePaginatorComponent {
23905
24343
  }
23906
24344
  }
23907
24345
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23908
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: QdTablePaginatorComponent, isStandalone: false, selector: "qd-table-paginator", inputs: { config: "config", testId: ["data-test-id", "testId"] }, viewQueries: [{ propertyName: "paginatorButtons", first: true, predicate: ["paginatorButtons"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"hasData$ | async\">\n <qd-table-paginator-page-size [pageSizes]=\"pageSizes\" *ngIf=\"pageSizes.length > 0\"></qd-table-paginator-page-size>\n <span class=\"paginator-current-page\" *ngIf=\"currentPage$ | async as page\">\n {{ page.start }}\u2014{{ page.end }}\n {{ \"i18n.qd.table.pagination.of\" | translate }}\n {{ page.totalCount }}\n {{\n page.totalCount === 1\n ? (\"i18n.qd.table.pagination.entry\" | translate)\n : (\"i18n.qd.table.pagination.entries\" | translate)\n }}\n </span>\n <span\n *ngIf=\"{ count: (selectedRowsCount$ | async) ?? 0 } as ctx\"\n [hidden]=\"ctx.count === 0 || config?.selection?.type !== 'multiSelect'\"\n class=\"paginator-selection-count\"\n [attr.data-test-id]=\"testId + '-paginator-selection-count'\"\n >\n {{\n ctx.count === 1\n ? (\"i18n.qd.table.pagination.selectedSingular\" | translate)\n : (\"i18n.qd.table.pagination.selectedPlural\" | translate : { count: ctx.count })\n }}\n </span>\n <span class=\"paginator-buttons\" data-test=\"paginator-buttons\" #paginatorButtons qdScrollToPagination>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-first-page'\"\n (click)=\"navigateToPage(pageNav.FirstPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageFirst1'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-backward'\"\n (click)=\"navigateToPage(pageNav.PreviousPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleLeftSolid'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button forward\"\n [attr.data-test-id]=\"testId + '-paginator-forward'\"\n (click)=\"navigateToPage(pageNav.NextPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleRightSolid'\"></qd-icon>\n </button>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-last-page'\"\n (click)=\"navigateToPage(pageNav.LastPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageLast'\"></qd-icon>\n </button>\n </span>\n</ng-container>\n", styles: [":host{color:#454545;font-size:.875rem;font-weight:400;line-height:1.3125rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;background-color:#fff}.paginator-current-page{margin-left:1rem}.paginator-selection-count{margin-right:1rem;margin-left:1rem}.paginator-buttons{margin-left:auto;text-align:right;white-space:nowrap}button.paginator-button{width:2.75rem;height:2.75rem;border-left:.0625rem solid rgb(229,229,229);background-color:unset;color:#454545;font-size:1.5rem}button.paginator-button:disabled{color:#b4b4b4;cursor:default}button.paginator-button:not(:disabled):hover{background-color:#e5e5e5;color:#171717}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "directive", type: QdScrollToPaginationDirective, selector: "[qdScrollToPagination]" }, { kind: "component", type: QdTablePaginatorPageSizeComponent, selector: "qd-table-paginator-page-size", inputs: ["pageSizes"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
24346
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: QdTablePaginatorComponent, isStandalone: false, selector: "qd-table-paginator", inputs: { config: "config", testId: ["data-test-id", "testId"] }, providers: [QdTablePaginationRouterConnectorService], viewQueries: [{ propertyName: "paginatorButtons", first: true, predicate: ["paginatorButtons"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"hasData$ | async\">\n <qd-table-paginator-page-size [pageSizes]=\"pageSizes\" *ngIf=\"pageSizes.length > 0\"></qd-table-paginator-page-size>\n <span class=\"paginator-current-page\" *ngIf=\"currentPage$ | async as page\">\n {{ page.start }}\u2014{{ page.end }}\n {{ \"i18n.qd.table.pagination.of\" | translate }}\n {{ page.totalCount }}\n {{\n page.totalCount === 1\n ? (\"i18n.qd.table.pagination.entry\" | translate)\n : (\"i18n.qd.table.pagination.entries\" | translate)\n }}\n </span>\n <span\n *ngIf=\"{ count: (selectedRowsCount$ | async) ?? 0 } as ctx\"\n [hidden]=\"ctx.count === 0 || config?.selection?.type !== 'multiSelect'\"\n class=\"paginator-selection-count\"\n [attr.data-test-id]=\"testId + '-paginator-selection-count'\"\n >\n {{\n ctx.count === 1\n ? (\"i18n.qd.table.pagination.selectedSingular\" | translate)\n : (\"i18n.qd.table.pagination.selectedPlural\" | translate : { count: ctx.count })\n }}\n </span>\n <span class=\"paginator-buttons\" data-test=\"paginator-buttons\" #paginatorButtons qdScrollToPagination>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-first-page'\"\n (click)=\"navigateToPage(pageNav.FirstPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageFirst1'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-backward'\"\n (click)=\"navigateToPage(pageNav.PreviousPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleLeftSolid'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button forward\"\n [attr.data-test-id]=\"testId + '-paginator-forward'\"\n (click)=\"navigateToPage(pageNav.NextPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleRightSolid'\"></qd-icon>\n </button>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-last-page'\"\n (click)=\"navigateToPage(pageNav.LastPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageLast'\"></qd-icon>\n </button>\n </span>\n</ng-container>\n", styles: [":host{color:#454545;font-size:.875rem;font-weight:400;line-height:1.3125rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;background-color:#fff}.paginator-current-page{margin-left:1rem}.paginator-selection-count{margin-right:1rem;margin-left:1rem}.paginator-buttons{margin-left:auto;text-align:right;white-space:nowrap}button.paginator-button{width:2.75rem;height:2.75rem;border-left:.0625rem solid rgb(229,229,229);background-color:unset;color:#454545;font-size:1.5rem}button.paginator-button:disabled{color:#b4b4b4;cursor:default}button.paginator-button:not(:disabled):hover{background-color:#e5e5e5;color:#171717}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "directive", type: QdScrollToPaginationDirective, selector: "[qdScrollToPagination]" }, { kind: "component", type: QdTablePaginatorPageSizeComponent, selector: "qd-table-paginator-page-size", inputs: ["pageSizes"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
23909
24347
  }
23910
24348
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginatorComponent, decorators: [{
23911
24349
  type: Component,
23912
- args: [{ selector: 'qd-table-paginator', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<ng-container *ngIf=\"hasData$ | async\">\n <qd-table-paginator-page-size [pageSizes]=\"pageSizes\" *ngIf=\"pageSizes.length > 0\"></qd-table-paginator-page-size>\n <span class=\"paginator-current-page\" *ngIf=\"currentPage$ | async as page\">\n {{ page.start }}\u2014{{ page.end }}\n {{ \"i18n.qd.table.pagination.of\" | translate }}\n {{ page.totalCount }}\n {{\n page.totalCount === 1\n ? (\"i18n.qd.table.pagination.entry\" | translate)\n : (\"i18n.qd.table.pagination.entries\" | translate)\n }}\n </span>\n <span\n *ngIf=\"{ count: (selectedRowsCount$ | async) ?? 0 } as ctx\"\n [hidden]=\"ctx.count === 0 || config?.selection?.type !== 'multiSelect'\"\n class=\"paginator-selection-count\"\n [attr.data-test-id]=\"testId + '-paginator-selection-count'\"\n >\n {{\n ctx.count === 1\n ? (\"i18n.qd.table.pagination.selectedSingular\" | translate)\n : (\"i18n.qd.table.pagination.selectedPlural\" | translate : { count: ctx.count })\n }}\n </span>\n <span class=\"paginator-buttons\" data-test=\"paginator-buttons\" #paginatorButtons qdScrollToPagination>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-first-page'\"\n (click)=\"navigateToPage(pageNav.FirstPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageFirst1'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-backward'\"\n (click)=\"navigateToPage(pageNav.PreviousPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleLeftSolid'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button forward\"\n [attr.data-test-id]=\"testId + '-paginator-forward'\"\n (click)=\"navigateToPage(pageNav.NextPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleRightSolid'\"></qd-icon>\n </button>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-last-page'\"\n (click)=\"navigateToPage(pageNav.LastPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageLast'\"></qd-icon>\n </button>\n </span>\n</ng-container>\n", styles: [":host{color:#454545;font-size:.875rem;font-weight:400;line-height:1.3125rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;background-color:#fff}.paginator-current-page{margin-left:1rem}.paginator-selection-count{margin-right:1rem;margin-left:1rem}.paginator-buttons{margin-left:auto;text-align:right;white-space:nowrap}button.paginator-button{width:2.75rem;height:2.75rem;border-left:.0625rem solid rgb(229,229,229);background-color:unset;color:#454545;font-size:1.5rem}button.paginator-button:disabled{color:#b4b4b4;cursor:default}button.paginator-button:not(:disabled):hover{background-color:#e5e5e5;color:#171717}\n"] }]
24350
+ args: [{ selector: 'qd-table-paginator', providers: [QdTablePaginationRouterConnectorService], changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<ng-container *ngIf=\"hasData$ | async\">\n <qd-table-paginator-page-size [pageSizes]=\"pageSizes\" *ngIf=\"pageSizes.length > 0\"></qd-table-paginator-page-size>\n <span class=\"paginator-current-page\" *ngIf=\"currentPage$ | async as page\">\n {{ page.start }}\u2014{{ page.end }}\n {{ \"i18n.qd.table.pagination.of\" | translate }}\n {{ page.totalCount }}\n {{\n page.totalCount === 1\n ? (\"i18n.qd.table.pagination.entry\" | translate)\n : (\"i18n.qd.table.pagination.entries\" | translate)\n }}\n </span>\n <span\n *ngIf=\"{ count: (selectedRowsCount$ | async) ?? 0 } as ctx\"\n [hidden]=\"ctx.count === 0 || config?.selection?.type !== 'multiSelect'\"\n class=\"paginator-selection-count\"\n [attr.data-test-id]=\"testId + '-paginator-selection-count'\"\n >\n {{\n ctx.count === 1\n ? (\"i18n.qd.table.pagination.selectedSingular\" | translate)\n : (\"i18n.qd.table.pagination.selectedPlural\" | translate : { count: ctx.count })\n }}\n </span>\n <span class=\"paginator-buttons\" data-test=\"paginator-buttons\" #paginatorButtons qdScrollToPagination>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-first-page'\"\n (click)=\"navigateToPage(pageNav.FirstPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageFirst1'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-backward'\"\n (click)=\"navigateToPage(pageNav.PreviousPage)\"\n [disabled]=\"(canPageBackward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleLeftSolid'\"></qd-icon>\n </button>\n <button\n class=\"paginator-button forward\"\n [attr.data-test-id]=\"testId + '-paginator-forward'\"\n (click)=\"navigateToPage(pageNav.NextPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'triangleRightSolid'\"></qd-icon>\n </button>\n <button\n *ngIf=\"config?.pagination['hasFirstLastPageNavigation']\"\n class=\"paginator-button\"\n [attr.data-test-id]=\"testId + '-paginator-last-page'\"\n (click)=\"navigateToPage(pageNav.LastPage)\"\n [disabled]=\"(canPageForward$ | async) === false\"\n >\n <qd-icon [icon]=\"'pageLast'\"></qd-icon>\n </button>\n </span>\n</ng-container>\n", styles: [":host{color:#454545;font-size:.875rem;font-weight:400;line-height:1.3125rem;display:flex;flex-direction:row;align-items:center;justify-content:space-between;background-color:#fff}.paginator-current-page{margin-left:1rem}.paginator-selection-count{margin-right:1rem;margin-left:1rem}.paginator-buttons{margin-left:auto;text-align:right;white-space:nowrap}button.paginator-button{width:2.75rem;height:2.75rem;border-left:.0625rem solid rgb(229,229,229);background-color:unset;color:#454545;font-size:1.5rem}button.paginator-button:disabled{color:#b4b4b4;cursor:default}button.paginator-button:not(:disabled):hover{background-color:#e5e5e5;color:#171717}\n"] }]
23913
24351
  }], propDecorators: { config: [{
23914
24352
  type: Input
23915
24353
  }], testId: [{
@@ -23920,6 +24358,147 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
23920
24358
  args: ['paginatorButtons']
23921
24359
  }] } });
23922
24360
 
24361
+ const SORT_PARAM_NAME = 'sort';
24362
+ const OWNED_PARAMS = [SORT_PARAM_NAME];
24363
+ const SEGMENT_SEPARATOR = ',';
24364
+ const COLUMN_DIRECTION_SEPARATOR = '.';
24365
+ class QdTableSortRouterConnectorService {
24366
+ hub = inject(QdRouterQueryParamHubService);
24367
+ destroyRef = inject(DestroyRef);
24368
+ _connection;
24369
+ _readSubscription;
24370
+ _writeSubscription;
24371
+ _activatedRouteCheckedSubject = new ReplaySubject(1);
24372
+ _activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
24373
+ _hasInitialUrlBeenSet = false;
24374
+ _hasWarnedMultiSegment = false;
24375
+ constructor() {
24376
+ this.destroyRef.onDestroy(() => {
24377
+ this.tearDownConnection();
24378
+ this.hub.release(OWNED_PARAMS, this);
24379
+ });
24380
+ }
24381
+ connectSortWithRouter(table, tableStoreService) {
24382
+ if (!this.shouldConnect(table) || !this.hub.isAvailable())
24383
+ return of(false);
24384
+ if (!this.hub.claim(OWNED_PARAMS, this))
24385
+ return of(false);
24386
+ this._connection = {
24387
+ table: table,
24388
+ tableStoreService: tableStoreService,
24389
+ configuredColumns: table.config.columns
24390
+ };
24391
+ this._hasInitialUrlBeenSet = false;
24392
+ this._hasWarnedMultiSegment = false;
24393
+ this._activatedRouteCheckedSubject = new ReplaySubject(1);
24394
+ this._activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
24395
+ this.subscribeToUrlChanges();
24396
+ this.subscribeToStoreChanges();
24397
+ return this._activatedRouteChecked$;
24398
+ }
24399
+ disconnectSortFromRouter(table) {
24400
+ if (this._connection?.table !== table)
24401
+ return;
24402
+ this.tearDownConnection();
24403
+ this.hub.release(OWNED_PARAMS, this);
24404
+ }
24405
+ tearDownConnection() {
24406
+ this._connection = undefined;
24407
+ this._hasInitialUrlBeenSet = false;
24408
+ this._hasWarnedMultiSegment = false;
24409
+ this._readSubscription?.unsubscribe();
24410
+ this._writeSubscription?.unsubscribe();
24411
+ }
24412
+ subscribeToUrlChanges() {
24413
+ const { tableStoreService } = this._connection;
24414
+ let isFirstEmit = true;
24415
+ this._readSubscription = this.hub.navigationSettled$
24416
+ .pipe(switchMap(() => this.hub.queryParams()), map(queryParams => (typeof queryParams[SORT_PARAM_NAME] === 'string' ? queryParams[SORT_PARAM_NAME] : '')), distinctUntilChanged(), map(raw => this.parseRawSortValue(raw)))
24417
+ .subscribe(segments => {
24418
+ if (segments.length === 1) {
24419
+ const [{ column, direction }] = segments;
24420
+ tableStoreService.setSort(column, direction);
24421
+ }
24422
+ if (isFirstEmit) {
24423
+ this._activatedRouteCheckedSubject.next(true);
24424
+ isFirstEmit = false;
24425
+ }
24426
+ });
24427
+ }
24428
+ subscribeToStoreChanges() {
24429
+ const { tableStoreService } = this._connection;
24430
+ this._writeSubscription = tableStoreService
24431
+ .tableSort$()
24432
+ .pipe(filter((sort) => Array.isArray(sort)), map(sort => this.serializeSort(sort)), distinctUntilChanged(), switchMap(serialized => this.hub.navigationSettled$.pipe(take(1), map(() => serialized))))
24433
+ .subscribe(serialized => this.writeUrl(serialized));
24434
+ }
24435
+ writeUrl(serialized) {
24436
+ const replaceUrl = !this._hasInitialUrlBeenSet;
24437
+ this._hasInitialUrlBeenSet = true;
24438
+ if (this.hub.snapshotQueryParam(SORT_PARAM_NAME) === serialized)
24439
+ return;
24440
+ this.hub.write({ [SORT_PARAM_NAME]: serialized }, replaceUrl);
24441
+ }
24442
+ shouldConnect(table) {
24443
+ const sortConfig = table.config.sort;
24444
+ if (sortConfig === true || sortConfig === undefined)
24445
+ return false;
24446
+ return sortConfig.connectWithRouter === true;
24447
+ }
24448
+ parseRawSortValue(raw) {
24449
+ if (raw.length === 0)
24450
+ return [];
24451
+ const rawSegments = raw.split(SEGMENT_SEPARATOR);
24452
+ const validSegments = rawSegments
24453
+ .map(segment => this.parseSegment(segment))
24454
+ .filter((segment) => segment !== undefined);
24455
+ if (validSegments.length > 1) {
24456
+ if (!this._hasWarnedMultiSegment) {
24457
+ console.warn('Quadrel Framework | QdTable - Multi-column sort URL is not yet supported. Using first valid segment only.');
24458
+ this._hasWarnedMultiSegment = true;
24459
+ }
24460
+ return [validSegments[0]];
24461
+ }
24462
+ return validSegments;
24463
+ }
24464
+ parseSegment(segment) {
24465
+ if (segment.length === 0)
24466
+ return undefined;
24467
+ const separatorIndex = segment.indexOf(COLUMN_DIRECTION_SEPARATOR);
24468
+ if (separatorIndex <= 0 || separatorIndex === segment.length - 1)
24469
+ return undefined;
24470
+ const column = segment.slice(0, separatorIndex);
24471
+ const directionRaw = segment.slice(separatorIndex + 1).toLowerCase();
24472
+ if (!this.isValidColumn(column))
24473
+ return undefined;
24474
+ if (directionRaw === 'asc')
24475
+ return { column, direction: QdSortDirection.ASC };
24476
+ if (directionRaw === 'desc')
24477
+ return { column, direction: QdSortDirection.DESC };
24478
+ return undefined;
24479
+ }
24480
+ isValidColumn(column) {
24481
+ const config = this._connection?.configuredColumns.find(c => c.column === column);
24482
+ return !!config && config.sort !== undefined && config.sort.isDisabled !== true;
24483
+ }
24484
+ serializeSort(sort) {
24485
+ const active = sort.filter((entry) => entry.direction === QdSortDirection.ASC || entry.direction === QdSortDirection.DESC);
24486
+ if (active.length === 0)
24487
+ return undefined;
24488
+ return active
24489
+ .map(entry => `${entry.column}${COLUMN_DIRECTION_SEPARATOR}${this.directionToString(entry.direction)}`)
24490
+ .join(SEGMENT_SEPARATOR);
24491
+ }
24492
+ directionToString(direction) {
24493
+ return direction === QdSortDirection.ASC ? 'asc' : 'desc';
24494
+ }
24495
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
24496
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService });
24497
+ }
24498
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService, decorators: [{
24499
+ type: Injectable
24500
+ }], ctorParameters: () => [] });
24501
+
23923
24502
  class QdTableRowActionsSecondaryMenuComponent {
23924
24503
  actionsService = inject(QdTableSecondaryActionsService);
23925
24504
  tableStore = inject(QdTableStoreService);
@@ -24535,6 +25114,7 @@ class QdTableComponent {
24535
25114
  breakpointService = inject(QdBreakpointService);
24536
25115
  resolverService = inject(QdTableResolverService);
24537
25116
  confirmationDialogService = inject(QdConfirmationDialogOpenerService);
25117
+ sortRouterConnector = inject(QdTableSortRouterConnectorService);
24538
25118
  /**
24539
25119
  * Configuration of the table. The generic type specifies the column definition. <br />
24540
25120
  *
@@ -24642,6 +25222,7 @@ class QdTableComponent {
24642
25222
  this.tableStoreService.initTableState(this._data, this.hasResolver, this._connectors, this.hasPagination);
24643
25223
  this.tableStoreService.updateTableStateRecentSecondaryAction(undefined);
24644
25224
  this.tableStoreService.setupSort(this.config.columns);
25225
+ this.sortRouterConnector.connectSortWithRouter(this, this.tableStoreService).pipe(take(1)).subscribe();
24645
25226
  this.resolverService.init(this.config.refreshOnLanguageChange, this.hasPagination);
24646
25227
  this.data$ = this.tableStoreService.tableDataEntries$();
24647
25228
  this.initializeResponsiveRowService();
@@ -24672,6 +25253,7 @@ class QdTableComponent {
24672
25253
  }
24673
25254
  }
24674
25255
  ngOnDestroy() {
25256
+ this.sortRouterConnector.disconnectSortFromRouter(this);
24675
25257
  this.tableStoreService.updateTableStateRecentSecondaryAction(undefined);
24676
25258
  this.tableStoreService.resetConnectorStates();
24677
25259
  this.fillingWidthService.destroy();
@@ -24841,7 +25423,8 @@ class QdTableComponent {
24841
25423
  QdTableRowSelectionService,
24842
25424
  QdTableFillingWidthService,
24843
25425
  QdTableResolverService,
24844
- QdTableExternalActionResultService
25426
+ QdTableExternalActionResultService,
25427
+ QdTableSortRouterConnectorService
24845
25428
  ], viewQueries: [{ propertyName: "paginator", first: true, predicate: QdTablePaginatorComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<table [class]=\"'qd-table__table'\">\n <tr qd-table-head [config]=\"config\" [data-test-id]=\"testId\"></tr>\n <tbody qd-table-body [config]=\"config\" [data]=\"(data$ | async) ?? []\" [data-test-id]=\"testId\"></tbody>\n</table>\n\n<qd-table-paginator [config]=\"config\" [data-test-id]=\"testId\" *ngIf=\"hasPagination\"></qd-table-paginator>\n<qd-table-empty-state *ngIf=\"hasEmptyStateView$ | async\" [config]=\"config.emptyStateView\"></qd-table-empty-state>\n", styles: [":host{display:inline-flex;flex-direction:column}:host .qd-table__table{background:#fff;border-spacing:0;color:#171717;font-size:.875rem;font-weight:400;line-height:2.5rem}:host .qd-table__head,:host .qd-table__body{vertical-align:center}:host .qd-table__head{background:#e5e5e5;text-align:left}:host .qd-table__head ::ng-deep .qd-table__head-cell{font-weight:600}:host .qd-table__body{color:#171717}:host ::ng-deep .qd-table__head-cell,:host ::ng-deep .qd-table__body-cell{padding:.125rem 1rem 0;vertical-align:top}:host ::ng-deep .qd-table__head-cell--selection,:host ::ng-deep .qd-table__body-cell--selection{width:1.875rem;padding-top:.1875rem;text-align:center}:host ::ng-deep .qd-table__head-cell--actions-inline-menu,:host ::ng-deep .qd-table__body-cell--actions-inline-menu{padding-top:.125rem;vertical-align:top}:host.main-column-fills-width.table-has-remaining-width:not(.table-has-right-aligned-filling-column) ::ng-deep th.main-column,:host.main-column-fills-width.table-has-remaining-width:not(.table-has-right-aligned-filling-column) ::ng-deep td.main-column{width:100%}:host.main-column-fills-width.table-has-remaining-width ::ng-deep th:not(.main-column),:host.main-column-fills-width.table-has-remaining-width ::ng-deep td:not(.main-column){white-space:nowrap}:host.last-column-fills-width.table-has-remaining-width:not(.table-has-right-aligned-filling-column) ::ng-deep th.last-column,:host.last-column-fills-width.table-has-remaining-width:not(.table-has-right-aligned-filling-column) ::ng-deep td.last-column{width:100%}:host.last-column-fills-width.table-has-remaining-width ::ng-deep th:not(.last-column),:host.last-column-fills-width.table-has-remaining-width ::ng-deep td:not(.last-column){white-space:nowrap}:host.harmonized{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: QdTableBodyComponent, selector: "[qd-table-body]", inputs: ["config", "data", "data-test-id"] }, { kind: "component", type: QdTableEmptyStateComponent, selector: "qd-table-empty-state", inputs: ["config"] }, { kind: "component", type: QdTableHeadComponent, selector: "[qd-table-head]", inputs: ["config", "data-test-id"] }, { kind: "component", type: QdTablePaginatorComponent, selector: "qd-table-paginator", inputs: ["config", "data-test-id"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
24846
25429
  }
24847
25430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableComponent, decorators: [{
@@ -24855,7 +25438,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
24855
25438
  QdTableRowSelectionService,
24856
25439
  QdTableFillingWidthService,
24857
25440
  QdTableResolverService,
24858
- QdTableExternalActionResultService
25441
+ QdTableExternalActionResultService,
25442
+ QdTableSortRouterConnectorService
24859
25443
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
24860
25444
  '[class.qd-table]': 'true',
24861
25445
  '[class.main-column-fills-width]': 'whichColumnFillsWidth === "main"',
@@ -30550,147 +31134,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
30550
31134
  args: [{ selector: 'qd-shell-header-search', standalone: false, template: "<qd-search [configData]=\"config\"> </qd-search>\n", styles: [":host{display:none}:host:not(:last-child){margin-right:1rem}:host ::ng-deep .qd-input-input{border-color:#fff0!important;background:#efefef!important}:host ::ng-deep input{background:#fff0!important}:host ::ng-deep input::placeholder{color:#979797!important}:host ::ng-deep input:hover::placeholder,:host ::ng-deep input:focus::placeholder{color:#171717!important}@media (min-width: 1280px){:host{display:block}}\n"] }]
30551
31135
  }] });
30552
31136
 
30553
- // @ts-strict-ignore
30554
- class QdNavigationService {
30555
- router = inject(Router);
30556
- activatedRoute = inject(ActivatedRoute);
30557
- routeLeafSnapshot$;
30558
- routeData$;
30559
- routeComponentInstanceSubject = new ReplaySubject(1);
30560
- constructor() {
30561
- this.routeLeafSnapshot$ = this.router.events.pipe(filter(event => event instanceof NavigationEnd), map(() => this.activatedRoute), map(route => this.getLeafRoute(route).snapshot), filter(snapshot => snapshot.outlet === 'primary'));
30562
- this.routeData$ = this.routeLeafSnapshot$.pipe(map((snapshot) => snapshot.routeConfig?.data || {}), shareReplay(1));
30563
- }
30564
- getLeafRoute(route) {
30565
- if (!route.firstChild)
30566
- return route;
30567
- return this.getLeafRoute(route.firstChild);
30568
- }
30569
- isHome$() {
30570
- return this.routeData$.pipe(map(({ isHome }) => isHome ?? false));
30571
- }
30572
- getRouteParams$() {
30573
- return this.routeLeafSnapshot$.pipe(map(this.getMergedRouteParams.bind(this)));
30574
- }
30575
- getMergedRouteParams(snapshot) {
30576
- if (!snapshot)
30577
- return {};
30578
- return {
30579
- ...this.getMergedRouteParams(snapshot.parent),
30580
- ...(snapshot.params || {})
30581
- };
30582
- }
30583
- getPreviousHref$() {
30584
- return this.routeData$.pipe(map(({ previousHref }) => previousHref));
30585
- }
30586
- navigate(commands, extras) {
30587
- return this.router.navigate(commands, extras);
30588
- }
30589
- navigateByUrl(url, extras) {
30590
- return this.router.navigateByUrl(url, extras);
30591
- }
30592
- updateRouteComponentInstance(routeComponentInstance) {
30593
- this.routeComponentInstanceSubject.next(routeComponentInstance);
30594
- }
30595
- getRouteComponentInstance$() {
30596
- return this.routeComponentInstanceSubject.asObservable();
30597
- }
30598
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30599
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService });
30600
- }
30601
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, decorators: [{
30602
- type: Injectable
30603
- }], ctorParameters: () => [] });
30604
-
30605
- // @ts-strict-ignore
30606
- class QdShellLeftService {
30607
- _hasNavigation = new BehaviorSubject(false);
30608
- _isNavigationPinned = new BehaviorSubject(false);
30609
- _isNavigationRolledOver = new BehaviorSubject(false);
30610
- hasNavigation$ = this._hasNavigation.asObservable();
30611
- isNavigationPinned$ = this._isNavigationPinned.asObservable();
30612
- isNavigationRolledOver$ = this._isNavigationRolledOver.asObservable();
30613
- set config(config) {
30614
- this._hasNavigation.next(config.navigation?.length > 0);
30615
- }
30616
- set isNavigationRolledOver(value) {
30617
- this._isNavigationRolledOver.next(value);
30618
- }
30619
- togglePinnedNavigation() {
30620
- this._isNavigationPinned.next(!this._isNavigationPinned.value);
30621
- }
30622
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30623
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService });
30624
- }
30625
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, decorators: [{
30626
- type: Injectable
30627
- }] });
30628
-
30629
- class QdShellRightService {
30630
- notificationsService = inject(QdNotificationsService);
30631
- _open = new BehaviorSubject(false);
30632
- _pinned = new BehaviorSubject(false);
30633
- _hasNotificationsToggle = new BehaviorSubject(false);
30634
- open$ = this._open.asObservable();
30635
- pinned$ = this._pinned.asObservable();
30636
- notifications$;
30637
- set open(open) {
30638
- this._open.next(open);
30639
- }
30640
- get hasNotificationsToggle$() {
30641
- return combineLatest([this._hasNotificationsToggle, this.hasNotifications$]).pipe(map(([hasNotificationsToggle, hasNotifications]) => hasNotificationsToggle || hasNotifications));
30642
- }
30643
- get hasNotifications$() {
30644
- return this.notifications$.pipe(map(notifications => notifications.length > 0));
30645
- }
30646
- set config(config) {
30647
- this._hasNotificationsToggle.next(config.hasNotificationsToggle ?? false);
30648
- }
30649
- constructor() {
30650
- const notificationsService = this.notificationsService;
30651
- this.notifications$ = notificationsService.getNotificationsForContext('shell');
30652
- this._open.pipe(filter(open => open)).subscribe(() => {
30653
- this._pinned.next(false);
30654
- });
30655
- }
30656
- toggleOpen() {
30657
- this._open.next(!this._open.value);
30658
- }
30659
- togglePinned() {
30660
- this._pinned.next(!this._pinned.value);
30661
- }
30662
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30663
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService });
30664
- }
30665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, decorators: [{
30666
- type: Injectable
30667
- }], ctorParameters: () => [] });
30668
-
30669
- // @ts-strict-ignore
30670
- class QdShellHeaderMinimizationService {
30671
- navigationService = inject(QdNavigationService);
30672
- breakpointService = inject(QdBreakpointService);
30673
- _headerMinimizedBreakpoints = ['sm', 'xs'];
30674
- _config;
30675
- _isInternal$ = new BehaviorSubject(false);
30676
- set config(config) {
30677
- this._config = config;
30678
- this._isInternal$.next(config.isInternal);
30679
- }
30680
- isHeaderMinimized$() {
30681
- const isMinimizedForAllBreakpoints$ = this._isInternal$.pipe(combineLatestWith(this.navigationService.isHome$()), map(([isInternal, isHomePage]) => isInternal ?? !isHomePage));
30682
- return isMinimizedForAllBreakpoints$.pipe(combineLatestWith(this.breakpointService.getMatchingBreakpoint()), map(([isMinimizedForAllBreakpoints, breakpoint]) => isMinimizedForAllBreakpoints || this._isMinimizedBreakpoint(breakpoint)));
30683
- }
30684
- _isMinimizedBreakpoint(breakpoint) {
30685
- return this._headerMinimizedBreakpoints.includes(breakpoint);
30686
- }
30687
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30688
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService });
30689
- }
30690
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, decorators: [{
30691
- type: Injectable
30692
- }] });
30693
-
30694
31137
  // @ts-strict-ignore
30695
31138
  const loadJavascriptAsset = (path, scriptElementAttributes = {}) => {
30696
31139
  const scriptElement = document.createElement('script');
@@ -31148,6 +31591,162 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
31148
31591
  args: ['serviceNavigation']
31149
31592
  }] } });
31150
31593
 
31594
+ class QdShellServiceNavigationModule {
31595
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
31596
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, declarations: [QdShellServiceNavigationComponent], imports: [CommonModule], exports: [QdShellServiceNavigationComponent] });
31597
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, imports: [CommonModule] });
31598
+ }
31599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, decorators: [{
31600
+ type: NgModule,
31601
+ args: [{
31602
+ imports: [CommonModule],
31603
+ declarations: [QdShellServiceNavigationComponent],
31604
+ exports: [QdShellServiceNavigationComponent],
31605
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
31606
+ }]
31607
+ }] });
31608
+
31609
+ // @ts-strict-ignore
31610
+ class QdNavigationService {
31611
+ router = inject(Router);
31612
+ activatedRoute = inject(ActivatedRoute);
31613
+ routeLeafSnapshot$;
31614
+ routeData$;
31615
+ routeComponentInstanceSubject = new ReplaySubject(1);
31616
+ constructor() {
31617
+ this.routeLeafSnapshot$ = this.router.events.pipe(filter(event => event instanceof NavigationEnd), map(() => this.activatedRoute), map(route => this.getLeafRoute(route).snapshot), filter(snapshot => snapshot.outlet === 'primary'));
31618
+ this.routeData$ = this.routeLeafSnapshot$.pipe(map((snapshot) => snapshot.routeConfig?.data || {}), shareReplay(1));
31619
+ }
31620
+ getLeafRoute(route) {
31621
+ if (!route.firstChild)
31622
+ return route;
31623
+ return this.getLeafRoute(route.firstChild);
31624
+ }
31625
+ isHome$() {
31626
+ return this.routeData$.pipe(map(({ isHome }) => isHome ?? false));
31627
+ }
31628
+ getRouteParams$() {
31629
+ return this.routeLeafSnapshot$.pipe(map(this.getMergedRouteParams.bind(this)));
31630
+ }
31631
+ getMergedRouteParams(snapshot) {
31632
+ if (!snapshot)
31633
+ return {};
31634
+ return {
31635
+ ...this.getMergedRouteParams(snapshot.parent),
31636
+ ...(snapshot.params || {})
31637
+ };
31638
+ }
31639
+ getPreviousHref$() {
31640
+ return this.routeData$.pipe(map(({ previousHref }) => previousHref));
31641
+ }
31642
+ navigate(commands, extras) {
31643
+ return this.router.navigate(commands, extras);
31644
+ }
31645
+ navigateByUrl(url, extras) {
31646
+ return this.router.navigateByUrl(url, extras);
31647
+ }
31648
+ updateRouteComponentInstance(routeComponentInstance) {
31649
+ this.routeComponentInstanceSubject.next(routeComponentInstance);
31650
+ }
31651
+ getRouteComponentInstance$() {
31652
+ return this.routeComponentInstanceSubject.asObservable();
31653
+ }
31654
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31655
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService });
31656
+ }
31657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, decorators: [{
31658
+ type: Injectable
31659
+ }], ctorParameters: () => [] });
31660
+
31661
+ // @ts-strict-ignore
31662
+ class QdShellLeftService {
31663
+ _hasNavigation = new BehaviorSubject(false);
31664
+ _isNavigationPinned = new BehaviorSubject(false);
31665
+ _isNavigationRolledOver = new BehaviorSubject(false);
31666
+ hasNavigation$ = this._hasNavigation.asObservable();
31667
+ isNavigationPinned$ = this._isNavigationPinned.asObservable();
31668
+ isNavigationRolledOver$ = this._isNavigationRolledOver.asObservable();
31669
+ set config(config) {
31670
+ this._hasNavigation.next(config.navigation?.length > 0);
31671
+ }
31672
+ set isNavigationRolledOver(value) {
31673
+ this._isNavigationRolledOver.next(value);
31674
+ }
31675
+ togglePinnedNavigation() {
31676
+ this._isNavigationPinned.next(!this._isNavigationPinned.value);
31677
+ }
31678
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31679
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService });
31680
+ }
31681
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, decorators: [{
31682
+ type: Injectable
31683
+ }] });
31684
+
31685
+ class QdShellRightService {
31686
+ notificationsService = inject(QdNotificationsService);
31687
+ _open = new BehaviorSubject(false);
31688
+ _pinned = new BehaviorSubject(false);
31689
+ _hasNotificationsToggle = new BehaviorSubject(false);
31690
+ open$ = this._open.asObservable();
31691
+ pinned$ = this._pinned.asObservable();
31692
+ notifications$;
31693
+ set open(open) {
31694
+ this._open.next(open);
31695
+ }
31696
+ get hasNotificationsToggle$() {
31697
+ return combineLatest([this._hasNotificationsToggle, this.hasNotifications$]).pipe(map(([hasNotificationsToggle, hasNotifications]) => hasNotificationsToggle || hasNotifications));
31698
+ }
31699
+ get hasNotifications$() {
31700
+ return this.notifications$.pipe(map(notifications => notifications.length > 0));
31701
+ }
31702
+ set config(config) {
31703
+ this._hasNotificationsToggle.next(config.hasNotificationsToggle ?? false);
31704
+ }
31705
+ constructor() {
31706
+ const notificationsService = this.notificationsService;
31707
+ this.notifications$ = notificationsService.getNotificationsForContext('shell');
31708
+ this._open.pipe(filter(open => open)).subscribe(() => {
31709
+ this._pinned.next(false);
31710
+ });
31711
+ }
31712
+ toggleOpen() {
31713
+ this._open.next(!this._open.value);
31714
+ }
31715
+ togglePinned() {
31716
+ this._pinned.next(!this._pinned.value);
31717
+ }
31718
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31719
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService });
31720
+ }
31721
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, decorators: [{
31722
+ type: Injectable
31723
+ }], ctorParameters: () => [] });
31724
+
31725
+ // @ts-strict-ignore
31726
+ class QdShellHeaderMinimizationService {
31727
+ navigationService = inject(QdNavigationService);
31728
+ breakpointService = inject(QdBreakpointService);
31729
+ _headerMinimizedBreakpoints = ['sm', 'xs'];
31730
+ _config;
31731
+ _isInternal$ = new BehaviorSubject(false);
31732
+ set config(config) {
31733
+ this._config = config;
31734
+ this._isInternal$.next(config.isInternal);
31735
+ }
31736
+ isHeaderMinimized$() {
31737
+ const isMinimizedForAllBreakpoints$ = this._isInternal$.pipe(combineLatestWith(this.navigationService.isHome$()), map(([isInternal, isHomePage]) => isInternal ?? !isHomePage));
31738
+ return isMinimizedForAllBreakpoints$.pipe(combineLatestWith(this.breakpointService.getMatchingBreakpoint()), map(([isMinimizedForAllBreakpoints, breakpoint]) => isMinimizedForAllBreakpoints || this._isMinimizedBreakpoint(breakpoint)));
31739
+ }
31740
+ _isMinimizedBreakpoint(breakpoint) {
31741
+ return this._headerMinimizedBreakpoints.includes(breakpoint);
31742
+ }
31743
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31744
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService });
31745
+ }
31746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, decorators: [{
31747
+ type: Injectable
31748
+ }] });
31749
+
31151
31750
  // @ts-strict-ignore
31152
31751
  const DEFAULT_LANGUAGE_LIST$1 = ['de', 'fr', 'it', 'en'];
31153
31752
  class QdShellHeaderWidgetService {
@@ -32230,21 +32829,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
32230
32829
  args: [QdCommentsComponent]
32231
32830
  }] } });
32232
32831
 
32233
- class QdShellServiceNavigationModule {
32234
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
32235
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, declarations: [QdShellServiceNavigationComponent], imports: [CommonModule], exports: [QdShellServiceNavigationComponent] });
32236
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, imports: [CommonModule] });
32237
- }
32238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, decorators: [{
32239
- type: NgModule,
32240
- args: [{
32241
- imports: [CommonModule],
32242
- declarations: [QdShellServiceNavigationComponent],
32243
- exports: [QdShellServiceNavigationComponent],
32244
- schemas: [CUSTOM_ELEMENTS_SCHEMA]
32245
- }]
32246
- }] });
32247
-
32248
32832
  function initializeBreadcrumbServices(breadcrumbsService, dialogBreadcrumbsService) {
32249
32833
  return () => {
32250
32834
  breadcrumbsService.initialize();
@@ -33497,5 +34081,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
33497
34081
  * Generated bundle index. Do not edit.
33498
34082
  */
33499
34083
 
33500
- export { APP_ENVIRONMENT, AVAILABLE_ICONS, BACKEND_ERROR_CODES, MockLocaleDatePipe, NavigationTileComponent, NavigationTilesComponent, QD_DIALOG_CONFIRMATION_RESOLVER_TOKEN, QD_FILE_MANAGER_TOKEN, QD_FILE_UPLOAD_MANAGER_TOKEN, QD_FORM_OPTIONS_RESOLVER, QD_PAGE_OBJECT_RESOLVER_TOKEN, QD_PAGE_STEP_RESOLVER_TOKEN, QD_POPOVER_TOP_FIRST, QD_SAFE_BOTTOM_OFFSET, QD_TABLE_DATA_RESOLVER_TOKEN, QD_UPLOAD_HTTP_OPTIONS, QdButtonComponent, QdButtonGhostDirective, QdButtonGridComponent, QdButtonLinkDirective, QdButtonModule, QdButtonStackButtonComponent, QdButtonStackComponent, QdCheckboxChipsComponent, QdCheckboxComponent, QdCheckboxesComponent, QdChipComponent, QdChipModule, QdColumnAutoFillDirective, QdColumnBreakBeforeDirective, QdColumnDirective, QdColumnDisableResponsiveColspansDirective, QdColumnFullGridWidthDirective, QdColumnNextInSameRowDirective, QdColumnsDirective, QdColumnsDisableAutoFillDirective, QdColumnsDisableResponsiveColspansDirective, QdColumnsMaxDirective, QdCommentsComponent, QdCommentsModule, QdConnectFormStateToPageDirective, QdConnectorTableContextDirective, QdConnectorTableFilterDirective, QdConnectorTableSearchDirective, QdContactCardComponent, QdContactCardModule, QdContainerPairsCaptionComponent, QdContainerPairsContainerComponent, QdContainerPairsHeaderComponent, QdContainerPairsItemComponent, QdContainerPairsValueComponent, QdContextService, QdCoreModule, QdDatepickerComponent, QdDialogActionComponent, QdDialogAuthSessionEndComponent, QdDialogAuthSessionEndService, QdDialogComponent, QdDialogConfirmationComponent, QdDialogConfirmationErrorDirective, QdDialogConfirmationInfoDirective, QdDialogConfirmationSuccessDirective, QdDialogModule, QdDialogRecordStepperComponent, QdDialogService, QdDialogSize, QdDisabledDirective, QdDropdownComponent, QdFileCollectorComponent, QdFileCollectorModule, QdFileSizePipe$1 as QdFileSizePipe, QdFileUploadComponent, QdFileUploadService, QdFilterComponent, QdFilterFormItemsComponent, QdFilterModule, QdFilterRestParamBuilder, QdFilterService, QdFormArray, QdFormBuilder, QdFormControl, QdFormGroup, QdFormModule, QdGridComponent, QdGridModule, QdHorizontalPairsCaptionComponent, QdHorizontalPairsComponent, QdHorizontalPairsItemComponent, QdHorizontalPairsValueComponent, QdIconButtonComponent, QdIconComponent, QdIconModule, QdImageComponent, QdImageModule, QdIndeterminateProgressBarComponent, QdInputComponent, QdListModule, QdMenuButtonComponent, QdMockBreakpointService, QdMockButtonComponent, QdMockButtonGhostDirective, QdMockButtonGridComponent, QdMockButtonLinkDirective, QdMockButtonModule, QdMockButtonStackButtonComponent, QdMockButtonStackComponent, QdMockCalendarComponent, QdMockCheckboxChipsComponent, QdMockCheckboxComponent, QdMockCheckboxesComponent, QdMockChipComponent, QdMockChipModule, QdMockColumnDirective, QdMockColumnsDirective, QdMockContactCardComponent, QdMockContactCardModule, QdMockContainerPairsCaptionComponent, QdMockContainerPairsContainerComponent, QdMockContainerPairsHeaderComponent, QdMockContainerPairsItemComponent, QdMockContainerPairsValueComponent, QdMockCoreModule, QdMockCounterBadgeComponent, QdMockDatepickerComponent, QdMockDisabledDirective, QdMockDropdownComponent, QdMockFileCollectorComponent, QdMockFileCollectorModule, QdMockFilterCategoryBooleanComponent, QdMockFilterCategoryComponent, QdMockFilterCategoryDateComponent, QdMockFilterCategoryDateRangeComponent, QdMockFilterCategoryFreeTextComponent, QdMockFilterCategorySelectComponent, QdMockFilterComponent, QdMockFilterFormItemsComponent, QdMockFilterItemBooleanComponent, QdMockFilterItemDateComponent, QdMockFilterItemDateRangeComponent, QdMockFilterItemFreeTextComponent, QdMockFilterItemMultiSelectComponent, QdMockFilterItemSingleSelectComponent, QdMockFilterModule, QdMockFilterService, QdMockFormErrorComponent, QdMockFormGroupErrorComponent, QdMockFormHintComponent, QdMockFormLabelComponent, QdMockFormReadonlyComponent, QdMockFormViewonlyComponent, QdMockFormsModule, QdMockGridModule, QdMockIconButtonComponent, QdMockIconComponent, QdMockIconModule, QdMockImageComponent, QdMockImageModule, QdMockIndeterminateProgressBarComponent, QdMockInputComponent, QdMockListModule, QdMockNavigationTileComponent, QdMockNavigationTilesComponent, QdMockNavigationTilesModule, QdMockNotificationComponent, QdMockNotificationContentComponent, QdMockNotificationsComponent, QdMockNotificationsModule, QdMockNotificationsService, QdMockPageComponent, QdMockPageModule, QdMockPercentageProgressBarComponent, QdMockPinCodeComponent, QdMockPlaceHolderModule, QdMockPopoverOnClickDirective, QdMockProgressBarModule, QdMockQdPlaceHolderComponent, QdMockRadioButtonsComponent, QdMockRwdDisabledDirective, QdMockSearchComponent, QdMockSearchModule, QdMockSectionComponent, QdMockSectionModule, QdMockShellComponent, QdMockShellFooterComponent, QdMockShellHeaderBannerComponent, QdMockShellHeaderComponent, QdMockShellHeaderSearchComponent, QdMockShellHeaderWidgetComponent, QdMockShellModule, QdMockShellToolbarComponent, QdMockShellToolbarItemComponent, QdMockStatusIndicatorCaptionComponent, QdMockStatusIndicatorComponent, QdMockStatusIndicatorItemComponent, QdMockStatusIndicatorModule, QdMockStatusPairsCaptionComponent, QdMockStatusPairsComponent, QdMockStatusPairsErrorComponent, QdMockStatusPairsItemComponent, QdMockStatusPairsValueComponent, QdMockSwitchComponent, QdMockSwitchesComponent, QdMockTableComponent, QdMockTableModule, QdMockTextSectionComponent, QdMockTextSectionHeadlineComponent, QdMockTextSectionModule, QdMockTextSectionParagraphComponent, QdMockTextareaComponent, QdMockTileButtonListComponent, QdMockTileComponent, QdMockTileTextListComponent, QdMockTileTextListItemComponent, QdMockTileTitleComponent, QdMockTilesContainerComponent, QdMockTilesContainerTitleComponent, QdMockTilesModule, QdMockTranslatePipe, QdMockVisuallyHiddenDirective, QdMultiInputComponent, QdNavigationTilesModule, QdNotificationComponent, QdNotificationContentComponent, QdNotificationsComponent, QdNotificationsHttpInterceptorService, QdNotificationsModule, QdNotificationsService, QdNotificationsSnackbarListenerDirective, QdNumberInputService, QdPageComponent, QdPageControlPanelComponent, QdPageFooterComponent, QdPageFooterCustomContentDirective, QdPageInfoBannerComponent, QdPageModule, QdPageStepComponent, QdPageStepperAdapterDirective, QdPageStepperComponent, QdPageStepperModule, QdPageStoreService, QdPageTabComponent, QdPageTabsAdapterDirective, QdPageTabsComponent, QdPageTabsModule, QdPanelSectionActionsComponent, QdPanelSectionComponent, QdPanelSectionModule, QdPanelSectionStatusComponent, QdPanelSectionTextParagraphComponent, QdPendingChangesGuardDirective, QdPercentageProgressBarComponent, QdPinCodeComponent, QdPlaceHolderComponent, QdPlaceHolderModule, QdPlaceholderPipe, QdProgressBarModule, QdProjectionGuardComponent, QdPushEventsService, QdQuickEditComponent, QdQuickEditModule, QdRadioButtonsComponent, QdRichtextComponent, QdRwdDisabledDirective, QdSearchComponent, QdSearchModule, QdSectionAdapterDirective, QdSectionComponent, QdSectionModule, QdSectionToolbarComponent, QdShellComponent, QdShellModule, QdSortDirection, QdSpinnerComponent, QdSpinnerModule, QdStatusIndicatorComponent, QdStatusIndicatorModule, QdStatusPairsCaptionComponent, QdStatusPairsComponent, QdStatusPairsErrorComponent, QdStatusPairsItemComponent, QdStatusPairsValueComponent, QdSubgridComponent, QdSwitchComponent, QdSwitchesComponent, QdTableComponent, QdTableModule, QdTableSpringTools, QdTextSectionComponent, QdTextSectionHeadlineComponent, QdTextSectionModule, QdTextSectionParagraphComponent, QdTextareaComponent, QdTileButtonListComponent, QdTileComponent, QdTileTextListComponent, QdTileTextListItemComponent, QdTileTitleComponent, QdTilesComponent, QdTilesModule, QdTilesTitleComponent, QdTooltipAtIntersectionDirective, QdTooltipIconComponent, QdTreeComponent, QdTreeModule, QdTreeRowExpanderService, QdUiMockModule, QdUiModule, QdUploadErrorType, QdValidators, QdViewportAdaptiveDirective, QdVisuallyHiddenDirective, chipColorDefault, createMetadataStream, updateHtmlLang };
34084
+ export { APP_ENVIRONMENT, AVAILABLE_ICONS, BACKEND_ERROR_CODES, MockLocaleDatePipe, NavigationTileComponent, NavigationTilesComponent, QD_DIALOG_CONFIRMATION_RESOLVER_TOKEN, QD_FILE_MANAGER_TOKEN, QD_FILE_UPLOAD_MANAGER_TOKEN, QD_FORM_OPTIONS_RESOLVER, QD_PAGE_OBJECT_RESOLVER_TOKEN, QD_PAGE_STEP_RESOLVER_TOKEN, QD_POPOVER_TOP_FIRST, QD_SAFE_BOTTOM_OFFSET, QD_TABLE_DATA_RESOLVER_TOKEN, QD_UPLOAD_HTTP_OPTIONS, QdButtonComponent, QdButtonGhostDirective, QdButtonGridComponent, QdButtonLinkDirective, QdButtonModule, QdButtonStackButtonComponent, QdButtonStackComponent, QdCheckboxChipsComponent, QdCheckboxComponent, QdCheckboxesComponent, QdChipComponent, QdChipModule, QdColumnAutoFillDirective, QdColumnBreakBeforeDirective, QdColumnDirective, QdColumnDisableResponsiveColspansDirective, QdColumnFullGridWidthDirective, QdColumnNextInSameRowDirective, QdColumnsDirective, QdColumnsDisableAutoFillDirective, QdColumnsDisableResponsiveColspansDirective, QdColumnsMaxDirective, QdCommentsComponent, QdCommentsModule, QdConnectFormStateToPageDirective, QdConnectorTableContextDirective, QdConnectorTableFilterDirective, QdConnectorTableSearchDirective, QdContactCardComponent, QdContactCardModule, QdContainerPairsCaptionComponent, QdContainerPairsContainerComponent, QdContainerPairsHeaderComponent, QdContainerPairsItemComponent, QdContainerPairsValueComponent, QdContextService, QdCoreModule, QdDatepickerComponent, QdDialogActionComponent, QdDialogAuthSessionEndComponent, QdDialogAuthSessionEndService, QdDialogComponent, QdDialogConfirmationComponent, QdDialogConfirmationErrorDirective, QdDialogConfirmationInfoDirective, QdDialogConfirmationSuccessDirective, QdDialogModule, QdDialogRecordStepperComponent, QdDialogService, QdDialogSize, QdDisabledDirective, QdDropdownComponent, QdFileCollectorComponent, QdFileCollectorModule, QdFileSizePipe$1 as QdFileSizePipe, QdFileUploadComponent, QdFileUploadService, QdFilterComponent, QdFilterFormItemsComponent, QdFilterModule, QdFilterRestParamBuilder, QdFilterService, QdFormArray, QdFormBuilder, QdFormControl, QdFormGroup, QdFormModule, QdGridComponent, QdGridModule, QdHorizontalPairsCaptionComponent, QdHorizontalPairsComponent, QdHorizontalPairsItemComponent, QdHorizontalPairsValueComponent, QdIconButtonComponent, QdIconComponent, QdIconModule, QdImageComponent, QdImageModule, QdIndeterminateProgressBarComponent, QdInputComponent, QdListModule, QdMenuButtonComponent, QdMockBreakpointService, QdMockButtonComponent, QdMockButtonGhostDirective, QdMockButtonGridComponent, QdMockButtonLinkDirective, QdMockButtonModule, QdMockButtonStackButtonComponent, QdMockButtonStackComponent, QdMockCalendarComponent, QdMockCheckboxChipsComponent, QdMockCheckboxComponent, QdMockCheckboxesComponent, QdMockChipComponent, QdMockChipModule, QdMockColumnDirective, QdMockColumnsDirective, QdMockContactCardComponent, QdMockContactCardModule, QdMockContainerPairsCaptionComponent, QdMockContainerPairsContainerComponent, QdMockContainerPairsHeaderComponent, QdMockContainerPairsItemComponent, QdMockContainerPairsValueComponent, QdMockCoreModule, QdMockCounterBadgeComponent, QdMockDatepickerComponent, QdMockDisabledDirective, QdMockDropdownComponent, QdMockFileCollectorComponent, QdMockFileCollectorModule, QdMockFilterCategoryBooleanComponent, QdMockFilterCategoryComponent, QdMockFilterCategoryDateComponent, QdMockFilterCategoryDateRangeComponent, QdMockFilterCategoryFreeTextComponent, QdMockFilterCategorySelectComponent, QdMockFilterComponent, QdMockFilterFormItemsComponent, QdMockFilterItemBooleanComponent, QdMockFilterItemDateComponent, QdMockFilterItemDateRangeComponent, QdMockFilterItemFreeTextComponent, QdMockFilterItemMultiSelectComponent, QdMockFilterItemSingleSelectComponent, QdMockFilterModule, QdMockFilterService, QdMockFormErrorComponent, QdMockFormGroupErrorComponent, QdMockFormHintComponent, QdMockFormLabelComponent, QdMockFormReadonlyComponent, QdMockFormViewonlyComponent, QdMockFormsModule, QdMockGridModule, QdMockIconButtonComponent, QdMockIconComponent, QdMockIconModule, QdMockImageComponent, QdMockImageModule, QdMockIndeterminateProgressBarComponent, QdMockInputComponent, QdMockListModule, QdMockNavigationTileComponent, QdMockNavigationTilesComponent, QdMockNavigationTilesModule, QdMockNotificationComponent, QdMockNotificationContentComponent, QdMockNotificationsComponent, QdMockNotificationsModule, QdMockNotificationsService, QdMockPageComponent, QdMockPageModule, QdMockPercentageProgressBarComponent, QdMockPinCodeComponent, QdMockPlaceHolderModule, QdMockPopoverOnClickDirective, QdMockProgressBarModule, QdMockQdPlaceHolderComponent, QdMockRadioButtonsComponent, QdMockRwdDisabledDirective, QdMockSearchComponent, QdMockSearchModule, QdMockSectionComponent, QdMockSectionModule, QdMockShellComponent, QdMockShellFooterComponent, QdMockShellHeaderBannerComponent, QdMockShellHeaderComponent, QdMockShellHeaderSearchComponent, QdMockShellHeaderWidgetComponent, QdMockShellModule, QdMockShellToolbarComponent, QdMockShellToolbarItemComponent, QdMockStatusIndicatorCaptionComponent, QdMockStatusIndicatorComponent, QdMockStatusIndicatorItemComponent, QdMockStatusIndicatorModule, QdMockStatusPairsCaptionComponent, QdMockStatusPairsComponent, QdMockStatusPairsErrorComponent, QdMockStatusPairsItemComponent, QdMockStatusPairsValueComponent, QdMockSwitchComponent, QdMockSwitchesComponent, QdMockTableComponent, QdMockTableModule, QdMockTextSectionComponent, QdMockTextSectionHeadlineComponent, QdMockTextSectionModule, QdMockTextSectionParagraphComponent, QdMockTextareaComponent, QdMockTileButtonListComponent, QdMockTileComponent, QdMockTileTextListComponent, QdMockTileTextListItemComponent, QdMockTileTitleComponent, QdMockTilesContainerComponent, QdMockTilesContainerTitleComponent, QdMockTilesModule, QdMockTranslatePipe, QdMockVisuallyHiddenDirective, QdMultiInputComponent, QdNavigationTilesModule, QdNotificationComponent, QdNotificationContentComponent, QdNotificationsComponent, QdNotificationsHttpInterceptorService, QdNotificationsModule, QdNotificationsService, QdNotificationsSnackbarListenerDirective, QdNumberInputService, QdPageComponent, QdPageControlPanelComponent, QdPageFooterComponent, QdPageFooterCustomContentDirective, QdPageInfoBannerComponent, QdPageModule, QdPageStepComponent, QdPageStepperAdapterDirective, QdPageStepperComponent, QdPageStepperModule, QdPageStoreService, QdPageTabComponent, QdPageTabsAdapterDirective, QdPageTabsComponent, QdPageTabsModule, QdPanelSectionActionsComponent, QdPanelSectionComponent, QdPanelSectionModule, QdPanelSectionStatusComponent, QdPanelSectionTextParagraphComponent, QdPendingChangesGuardDirective, QdPercentageProgressBarComponent, QdPinCodeComponent, QdPlaceHolderComponent, QdPlaceHolderModule, QdPlaceholderPipe, QdProgressBarModule, QdProjectionGuardComponent, QdPushEventsService, QdQuickEditComponent, QdQuickEditModule, QdRadioButtonsComponent, QdRichtextComponent, QdRouterQueryParamHubService, QdRwdDisabledDirective, QdSearchComponent, QdSearchModule, QdSectionAdapterDirective, QdSectionComponent, QdSectionModule, QdSectionToolbarComponent, QdShellComponent, QdShellModule, QdSortDirection, QdSpinnerComponent, QdSpinnerModule, QdStatusIndicatorComponent, QdStatusIndicatorModule, QdStatusPairsCaptionComponent, QdStatusPairsComponent, QdStatusPairsErrorComponent, QdStatusPairsItemComponent, QdStatusPairsValueComponent, QdSubgridComponent, QdSwitchComponent, QdSwitchesComponent, QdTableComponent, QdTableModule, QdTableSpringTools, QdTextSectionComponent, QdTextSectionHeadlineComponent, QdTextSectionModule, QdTextSectionParagraphComponent, QdTextareaComponent, QdTileButtonListComponent, QdTileComponent, QdTileTextListComponent, QdTileTextListItemComponent, QdTileTitleComponent, QdTilesComponent, QdTilesModule, QdTilesTitleComponent, QdTooltipAtIntersectionDirective, QdTooltipIconComponent, QdTreeComponent, QdTreeModule, QdTreeRowExpanderService, QdUiMockModule, QdUiModule, QdUploadErrorType, QdValidators, QdViewportAdaptiveDirective, QdVisuallyHiddenDirective, chipColorDefault, createMetadataStream, updateHtmlLang };
33501
34085
  //# sourceMappingURL=quadrel-enterprise-ui-framework.mjs.map