@quadrel-enterprise-ui/framework 20.11.2 → 20.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, Directive, InjectionToken, HostBinding, Input, ViewEncapsulation, Component, Injectable, Injector, HostListener, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, NgModule, EventEmitter, Output, Renderer2, Pipe, ViewContainerRef, NO_ERRORS_SCHEMA, SecurityContext, NgZone, ViewChildren, forwardRef, DestroyRef, ContentChildren, ContentChild, isDevMode, QueryList, CUSTOM_ELEMENTS_SCHEMA, provideAppInitializer, TemplateRef } from '@angular/core';
2
+ import { inject, ElementRef, Directive, InjectionToken, HostBinding, Input, ViewEncapsulation, Component, Injectable, Injector, HostListener, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, NgModule, EventEmitter, Output, Renderer2, Pipe, ViewContainerRef, NO_ERRORS_SCHEMA, DestroyRef, SecurityContext, NgZone, ViewChildren, forwardRef, ContentChildren, ContentChild, isDevMode, QueryList, CUSTOM_ELEMENTS_SCHEMA, provideAppInitializer, TemplateRef } from '@angular/core';
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';
@@ -19,6 +19,7 @@ import { ComponentPortal } from '@angular/cdk/portal';
19
19
  import { OverlayPositionBuilder, Overlay } from '@angular/cdk/overlay';
20
20
  import isNumber from 'lodash/isNumber';
21
21
  import { EventSourcePolyfill } from 'event-source-polyfill';
22
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
22
23
  import { DomSanitizer } from '@angular/platform-browser';
23
24
  import * as i3$1 from 'ngx-editor';
24
25
  import { Editor, NgxEditorModule } from 'ngx-editor';
@@ -31,7 +32,6 @@ import 'moment/locale/fr';
31
32
  import 'moment/locale/it';
32
33
  import moment$1 from 'moment/moment';
33
34
  import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
34
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
35
35
  import * as i1$1 from '@ngrx/store';
36
36
  import { createAction, props, createReducer, on, createSelector, createFeatureSelector, Store, StoreModule } from '@ngrx/store';
37
37
  import { diff } from 'deep-object-diff';
@@ -7115,6 +7115,277 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7115
7115
  }]
7116
7116
  }] });
7117
7117
 
7118
+ /**
7119
+ * Framework-wide funnel for syncing application state with the URL `?key=value` query string.
7120
+ *
7121
+ * Several Quadrel features mirror their state to the URL — the table's sort and pagination today,
7122
+ * filter, search, and `qd-page-tabs` over time. Without coordination they each call
7123
+ * `router.navigate(...)` directly, which produces two failure modes:
7124
+ *
7125
+ * 1. **Race**: two navigates issued in the same JS turn cancel each other. Only the last writer
7126
+ * wins; the URL silently loses the cancelled feature's params.
7127
+ * 2. **History pollution**: a single user action that changes two features (e.g. clicking a sort
7128
+ * header resets the page index) ends up as two history entries. Browser-back only undoes one.
7129
+ *
7130
+ * `QdRouterQueryParamHubService` is the single funnel through which features run their query-param
7131
+ * reads and writes. It does three jobs:
7132
+ *
7133
+ * - **Ownership** — `claim()` / `release()` enforce one writer per param key, app-wide.
7134
+ * - **Shared reads** — `queryParams()` and `snapshotQueryParam()` expose the route state without
7135
+ * each feature needing its own `ActivatedRoute` subscription.
7136
+ * - **Coordinated writes** — `write()` buffers param updates within a microtask and serializes
7137
+ * navigations via a Promise chain, so two writes in the same JS turn become one history entry
7138
+ * and concurrent writes never race.
7139
+ *
7140
+ * The hub is feature-agnostic. Per-feature adapters (e.g. `QdTableSortRouterConnectorService`)
7141
+ * own their parsing/serialization and delegate the URL plumbing to the hub.
7142
+ *
7143
+ * ### Usage
7144
+ *
7145
+ * ```ts
7146
+ * @Injectable()
7147
+ * export class FilterRouterAdapterService {
7148
+ * private readonly _hub = inject(QdRouterQueryParamHubService);
7149
+ * private readonly _destroyRef = inject(DestroyRef);
7150
+ *
7151
+ * connect(state$: Observable<FilterState>, dispatch: (state: FilterState) => void): void {
7152
+ * if (!this._hub.isAvailable()) return;
7153
+ * if (!this._hub.claim(['filter'], this, this._destroyRef)) return;
7154
+ *
7155
+ * this._hub
7156
+ * .queryParams()
7157
+ * .pipe(takeUntilDestroyed(this._destroyRef))
7158
+ * .subscribe(params => dispatch(parseFilter(params['filter'])));
7159
+ *
7160
+ * state$
7161
+ * .pipe(takeUntilDestroyed(this._destroyRef))
7162
+ * .subscribe(state => this._hub.write({ filter: serializeFilter(state) }, false));
7163
+ * }
7164
+ * }
7165
+ * ```
7166
+ */
7167
+ class QdRouterQueryParamHubService {
7168
+ /**
7169
+ * Replays whenever the router has finished a navigation (`NavigationEnd`, `NavigationCancel`
7170
+ * or `NavigationError` — every event that ends a navigation, regardless of outcome).
7171
+ * Adapters that want to delay a write until any in-flight navigation has settled can take(1)
7172
+ * on this stream before calling `write()`.
7173
+ *
7174
+ * Late subscribers receive the most recent settling event immediately, so an adapter that
7175
+ * mounts after the initial route navigation can observe the route as already-settled. The
7176
+ * first replayed tick may represent that initial route navigation rather than a user-driven
7177
+ * settling event — adapters that need to distinguish "the route just changed" should compare
7178
+ * `ActivatedRoute.snapshot` themselves.
7179
+ *
7180
+ * **When the hub is unavailable** (no `Router` / `ActivatedRoute` in the injector — see
7181
+ * `isAvailable()`) this observable never emits. Adapters that compose `navigationSettled$`
7182
+ * via operators like `switchMap` or `concat` must guard with `isAvailable()` first, otherwise
7183
+ * their pipelines hang silently.
7184
+ */
7185
+ navigationSettled$;
7186
+ _router = inject(Router, { optional: true });
7187
+ _activatedRoute = inject(ActivatedRoute, { optional: true });
7188
+ _destroyRef = inject(DestroyRef);
7189
+ _ownership = new Map();
7190
+ _destroyClaims = new WeakMap();
7191
+ _navigationSettledSubject = new ReplaySubject(1);
7192
+ _pendingParams = {};
7193
+ _pendingReplaceUrl = false;
7194
+ _flushScheduled = false;
7195
+ _navigationChain = Promise.resolve();
7196
+ constructor() {
7197
+ this.navigationSettled$ = this._navigationSettledSubject.asObservable();
7198
+ if (!this._router || !this._activatedRoute)
7199
+ return;
7200
+ this.replayCurrentRouterStateForLateSubscribers(this._router);
7201
+ this.forwardSettlingRouterEventsToNavigationSettled(this._router);
7202
+ }
7203
+ /**
7204
+ * Returns whether the hub can sync at all. False when the consuming injector has neither a
7205
+ * `Router` nor an `ActivatedRoute` available — for example in unit tests that omit
7206
+ * `RouterTestingModule`. Adapters should bail out early when this returns false.
7207
+ */
7208
+ isAvailable() {
7209
+ return !!this._router && !!this._activatedRoute;
7210
+ }
7211
+ /**
7212
+ * Reserves exclusive write access to the given query-param keys for `owner`.
7213
+ *
7214
+ * The same `owner` may claim the same keys repeatedly without conflict — claims are idempotent
7215
+ * per owner. A different owner attempting to claim an already-claimed key fails: the hub logs
7216
+ * a `console.error` listing every contested key and returns `false`. The original owner keeps
7217
+ * the keys until it calls `release()` (or until its `DestroyRef` fires, if a `destroyRef` is
7218
+ * passed here).
7219
+ *
7220
+ * Atomicity: when the call fails, no keys are claimed, even partially. The hub checks every
7221
+ * requested key against the registry before mutating anything.
7222
+ *
7223
+ * **Pass `destroyRef` to opt into auto-release.** Without it, the hub keeps a strong reference
7224
+ * to `owner` until `release()` is called manually — a destroyed adapter that forgets to release
7225
+ * pins itself in the registry. Passing the adapter's `DestroyRef` registers an `onDestroy`
7226
+ * callback that releases exactly the keys claimed via this call (and any later claims that
7227
+ * reuse the same `destroyRef`), which is the recommended path.
7228
+ *
7229
+ * Each `destroyRef` releases only the keys it owns. If the same owner uses two different
7230
+ * `DestroyRef`s in two `claim()` calls, each fires independently and only releases its own
7231
+ * keys — keys claimed via the still-alive `destroyRef` stay reserved.
7232
+ *
7233
+ * Re-claiming with the same `destroyRef` appends to the same destroy listener — no duplicate
7234
+ * listeners are registered, even when the second claim names a different owner. Each appended
7235
+ * entry carries its own owner, so when the `destroyRef` fires the hub releases each entry's
7236
+ * keys against that entry's owner. An empty `keys` array is a no-op even when `destroyRef`
7237
+ * is provided: no listener is attached, so the hub does not pin a destroy hook that would
7238
+ * release nothing.
7239
+ *
7240
+ * @param keys The query-param keys this adapter wants to own (e.g. `['sort']`, `['page', 'size']`).
7241
+ * @param owner Stable identity of the caller — usually `this`. Used as the registry key.
7242
+ * @param destroyRef Optional. If provided, the hub releases the keys automatically when the
7243
+ * `DestroyRef` fires. Pass the adapter's `inject(DestroyRef)` to make leaks impossible.
7244
+ * @returns `true` if every requested key is now owned by `owner`. `false` if at least one key
7245
+ * was already owned by a different adapter; the registry is left untouched and `destroyRef`
7246
+ * is not registered.
7247
+ */
7248
+ claim(keys, owner, destroyRef) {
7249
+ const conflicts = [];
7250
+ for (const key of keys) {
7251
+ const existing = this._ownership.get(key);
7252
+ if (existing && existing !== owner)
7253
+ conflicts.push(key);
7254
+ }
7255
+ if (conflicts.length > 0) {
7256
+ const list = conflicts.map(k => `"${k}"`).join(', ');
7257
+ console.error(`Quadrel Framework | QdRouterQueryParamHub - Query param ${list} ${conflicts.length === 1 ? 'is' : 'are'} ` +
7258
+ `already owned by another adapter. Disable the conflicting feature's URL sync or move it to a ` +
7259
+ `different param key.`);
7260
+ return false;
7261
+ }
7262
+ keys.forEach(key => this._ownership.set(key, owner));
7263
+ if (destroyRef && keys.length > 0)
7264
+ this.registerAutoRelease(owner, keys, destroyRef);
7265
+ return true;
7266
+ }
7267
+ /**
7268
+ * Drops `owner`'s claim on the given keys. Keys not owned by `owner` are left untouched —
7269
+ * a foreign release call cannot steal another adapter's ownership.
7270
+ *
7271
+ * Adapters typically release in their `DestroyRef.onDestroy` callback so a destroyed component
7272
+ * frees its keys for the next adapter that mounts.
7273
+ */
7274
+ release(keys, owner) {
7275
+ keys.forEach(key => {
7276
+ if (this._ownership.get(key) === owner)
7277
+ this._ownership.delete(key);
7278
+ });
7279
+ }
7280
+ /**
7281
+ * Reactive view of `ActivatedRoute.queryParams`. Returns the empty observable if the hub is
7282
+ * not available (no Router/ActivatedRoute). Adapters subscribe here instead of injecting
7283
+ * `ActivatedRoute` themselves so the hub stays the single read funnel.
7284
+ *
7285
+ * The observable is hot — late subscribers receive the current params immediately.
7286
+ */
7287
+ queryParams() {
7288
+ return this._activatedRoute?.queryParams ?? of({});
7289
+ }
7290
+ /**
7291
+ * Synchronous read of a single query param from the latest `ActivatedRoute` snapshot.
7292
+ * Adapters use this to detect "URL already matches the desired state" and skip a redundant
7293
+ * `write()`.
7294
+ *
7295
+ * @returns The param value, or `undefined` if the param is missing or the hub is unavailable.
7296
+ */
7297
+ snapshotQueryParam(key) {
7298
+ return this._activatedRoute?.snapshot.queryParamMap.get(key) ?? undefined;
7299
+ }
7300
+ /**
7301
+ * Schedules a query-param update.
7302
+ *
7303
+ * Two coordination guarantees:
7304
+ *
7305
+ * - **Microtask batching** — every `write()` issued in the same JavaScript turn is merged into
7306
+ * a single `router.navigate(...)` call. A user action that changes two features at once
7307
+ * (e.g. sort change resets the page) becomes one history entry, not two. Note: batching is
7308
+ * per JS turn, not per logical user action — writes that fall into the next microtask after
7309
+ * a settled navigation produce a separate history entry, even when they belong to the same
7310
+ * conceptual gesture.
7311
+ * - **Serialized navigations** — flushes are chained on a Promise so a second flush only fires
7312
+ * after the previous `router.navigate` has settled. Concurrent navigates can therefore not
7313
+ * cancel each other. A rejected `router.navigate` (cancelled by a guard, redirected, or
7314
+ * failed) does not stop the chain — the next pending flush still runs. Rejections are not
7315
+ * logged here; consumers that need routing diagnostics should subscribe to `router.events`.
7316
+ *
7317
+ * Adapters are still responsible for skipping no-op writes (compare the desired value against
7318
+ * `snapshotQueryParam()` first), since the hub does not deduplicate identical values.
7319
+ *
7320
+ * Setting a param value to `undefined` removes the param from the URL via Angular Router's
7321
+ * `merge` behavior. Other params not mentioned in the call are preserved.
7322
+ *
7323
+ * @param params Partial map of query-param keys to their new values. Missing keys are not touched.
7324
+ * An empty object short-circuits and is a no-op.
7325
+ * @param replaceUrl `true` replaces the current history entry; `false` pushes a new entry.
7326
+ * When several `write()` calls in the same microtask disagree, `true` wins (so an initial
7327
+ * replace is preserved when a follow-up write would otherwise push). The escalation is
7328
+ * per-batch — after each flush the pending flag resets to `false`, so writes that arrive
7329
+ * in the next microtask start a fresh batch with their own `replaceUrl` argument.
7330
+ */
7331
+ write(params, replaceUrl) {
7332
+ const router = this._router;
7333
+ const activatedRoute = this._activatedRoute;
7334
+ if (!router || !activatedRoute)
7335
+ return;
7336
+ if (Object.keys(params).length === 0)
7337
+ return;
7338
+ Object.assign(this._pendingParams, params);
7339
+ this._pendingReplaceUrl = this._pendingReplaceUrl || replaceUrl;
7340
+ if (this._flushScheduled)
7341
+ return;
7342
+ this._flushScheduled = true;
7343
+ Promise.resolve().then(() => this.flush(router, activatedRoute));
7344
+ }
7345
+ replayCurrentRouterStateForLateSubscribers(router) {
7346
+ if (router.navigated)
7347
+ this._navigationSettledSubject.next();
7348
+ }
7349
+ forwardSettlingRouterEventsToNavigationSettled(router) {
7350
+ router.events
7351
+ .pipe(filter(event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError), takeUntilDestroyed(this._destroyRef))
7352
+ .subscribe(() => this._navigationSettledSubject.next());
7353
+ }
7354
+ registerAutoRelease(owner, keys, destroyRef) {
7355
+ const existingClaims = this._destroyClaims.get(destroyRef);
7356
+ if (existingClaims) {
7357
+ existingClaims.push({ owner, keys });
7358
+ return;
7359
+ }
7360
+ const claims = [{ owner, keys }];
7361
+ this._destroyClaims.set(destroyRef, claims);
7362
+ destroyRef.onDestroy(() => {
7363
+ for (const claim of claims)
7364
+ this.release(claim.keys, claim.owner);
7365
+ });
7366
+ }
7367
+ flush(router, activatedRoute) {
7368
+ const params = this._pendingParams;
7369
+ const replaceUrl = this._pendingReplaceUrl;
7370
+ this._pendingParams = {};
7371
+ this._pendingReplaceUrl = false;
7372
+ this._flushScheduled = false;
7373
+ const exec = () => router.navigate([], {
7374
+ relativeTo: activatedRoute,
7375
+ queryParams: params,
7376
+ queryParamsHandling: 'merge',
7377
+ replaceUrl
7378
+ });
7379
+ this._navigationChain = this._navigationChain.catch(() => undefined).then(exec);
7380
+ }
7381
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7382
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, providedIn: 'root' });
7383
+ }
7384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdRouterQueryParamHubService, decorators: [{
7385
+ type: Injectable,
7386
+ args: [{ providedIn: 'root' }]
7387
+ }], ctorParameters: () => [] });
7388
+
7118
7389
  const MAX_TOOLTIP_CHARACTER = 512;
7119
7390
  const TOOLTIP_POSITIONS = [
7120
7391
  { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' },
@@ -11418,6 +11689,8 @@ class QdDatepickerComponent {
11418
11689
  timePicker;
11419
11690
  _disabledDatesValidator;
11420
11691
  _disabledTimesValidator;
11692
+ _boundDisabledDates;
11693
+ _boundDisabledTimes;
11421
11694
  _subs = new Subscription();
11422
11695
  _onChange = () => { };
11423
11696
  _onTouched = () => { };
@@ -11429,17 +11702,17 @@ class QdDatepickerComponent {
11429
11702
  this.updateConfiguration();
11430
11703
  this.updateDisplayedDate();
11431
11704
  this.updateDisplayedDateTime();
11432
- this.validateDisabledDates();
11433
- this.validateDisabledTimes();
11434
11705
  this._subs.add(this.initOpModeSubscription());
11435
11706
  }
11436
11707
  ngOnChanges(changes) {
11437
11708
  if (changes.config) {
11438
11709
  this.updateConfiguration();
11439
- this.validateDisabledDates();
11440
- this.validateDisabledTimes();
11441
11710
  }
11442
11711
  }
11712
+ ngDoCheck() {
11713
+ this.rebindDisabledDatesValidatorIfChanged();
11714
+ this.rebindDisabledTimesValidatorIfChanged();
11715
+ }
11443
11716
  ngOnDestroy() {
11444
11717
  this._subs.unsubscribe();
11445
11718
  }
@@ -11610,6 +11883,20 @@ class QdDatepickerComponent {
11610
11883
  this.displayedDateTime = QdDateAdapter.formatToDateTimeLocaleString(currentValue, this.config?.enableSeconds);
11611
11884
  this.displayedTime = QdDateAdapter.formatToTimeLocaleString(currentValue, this.config?.enableSeconds);
11612
11885
  }
11886
+ rebindDisabledDatesValidatorIfChanged() {
11887
+ const current = this.config?.disabledDates;
11888
+ if (current === this._boundDisabledDates)
11889
+ return;
11890
+ this._boundDisabledDates = current;
11891
+ this.validateDisabledDates();
11892
+ }
11893
+ rebindDisabledTimesValidatorIfChanged() {
11894
+ const current = this.config?.timePicker?.disabledTimes;
11895
+ if (current === this._boundDisabledTimes)
11896
+ return;
11897
+ this._boundDisabledTimes = current;
11898
+ this.validateDisabledTimes();
11899
+ }
11613
11900
  validateDisabledDates() {
11614
11901
  if (!this.control)
11615
11902
  return;
@@ -22704,6 +22991,9 @@ class QdTableStoreSelectorService {
22704
22991
  return sort.find(entry => entry.column === column)?.direction ?? QdSortDirection.NONE;
22705
22992
  });
22706
22993
  }
22994
+ tableSort() {
22995
+ return createSelector(this.selectTables, tables => this.getTable(tables)?.sort);
22996
+ }
22707
22997
  selectIsLoading() {
22708
22998
  return createSelector(this.selectTables, tables => {
22709
22999
  const { requestState } = this.getTable(tables) || {};
@@ -22890,6 +23180,9 @@ class QdTableStoreService {
22890
23180
  columnSortDirection$(column) {
22891
23181
  return this.store.select(this.tableStoreSelectorService.columnSortDirection(column));
22892
23182
  }
23183
+ tableSort$() {
23184
+ return this.store.select(this.tableStoreSelectorService.tableSort());
23185
+ }
22893
23186
  selectIsLoading$() {
22894
23187
  return this.store.select(this.tableStoreSelectorService.selectIsLoading());
22895
23188
  }
@@ -23360,6 +23653,130 @@ var QdPaginatorDirection;
23360
23653
  QdPaginatorDirection[QdPaginatorDirection["LastPage"] = 3] = "LastPage";
23361
23654
  })(QdPaginatorDirection || (QdPaginatorDirection = {}));
23362
23655
 
23656
+ const PAGE_PARAM_NAME = 'page';
23657
+ const SIZE_PARAM_NAME = 'size';
23658
+ const OWNED_PARAMS$1 = [PAGE_PARAM_NAME, SIZE_PARAM_NAME];
23659
+ const SIZE_SANITY_MAX = 1000;
23660
+ class QdTablePaginationRouterConnectorService {
23661
+ hub = inject(QdRouterQueryParamHubService);
23662
+ destroyRef = inject(DestroyRef);
23663
+ _connection;
23664
+ _readSubscription;
23665
+ _writeSubscription;
23666
+ _activatedRouteCheckedSubject = new ReplaySubject(1);
23667
+ _activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
23668
+ _hasInitialUrlBeenSet = false;
23669
+ constructor() {
23670
+ this.destroyRef.onDestroy(() => {
23671
+ this.tearDownConnection();
23672
+ this.hub.release(OWNED_PARAMS$1, this);
23673
+ });
23674
+ }
23675
+ connectPaginationWithRouter(paginator, tableStoreService) {
23676
+ if (!paginator.shouldConnectWithRouter() || !this.hub.isAvailable())
23677
+ return of(false);
23678
+ if (!this.hub.claim(OWNED_PARAMS$1, this))
23679
+ return of(false);
23680
+ this._connection = {
23681
+ paginator: paginator,
23682
+ tableStoreService: tableStoreService
23683
+ };
23684
+ this._hasInitialUrlBeenSet = false;
23685
+ this._activatedRouteCheckedSubject = new ReplaySubject(1);
23686
+ this._activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
23687
+ this.subscribeToUrlChanges();
23688
+ this.subscribeToStoreChanges();
23689
+ return this._activatedRouteChecked$;
23690
+ }
23691
+ disconnectPaginationFromRouter(paginator) {
23692
+ if (this._connection?.paginator !== paginator)
23693
+ return;
23694
+ this.tearDownConnection();
23695
+ this.hub.release(OWNED_PARAMS$1, this);
23696
+ }
23697
+ tearDownConnection() {
23698
+ this._connection = undefined;
23699
+ this._hasInitialUrlBeenSet = false;
23700
+ this._readSubscription?.unsubscribe();
23701
+ this._writeSubscription?.unsubscribe();
23702
+ }
23703
+ subscribeToUrlChanges() {
23704
+ const { tableStoreService } = this._connection;
23705
+ let isFirstEmit = true;
23706
+ this._readSubscription = this.hub.navigationSettled$
23707
+ .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 })))))
23708
+ .subscribe(({ params, currentInfo, totalCount }) => {
23709
+ const target = this.toStoreState(params);
23710
+ const isChanged = !currentInfo || currentInfo.pageIndex !== target.pageIndex || currentInfo.pageSize !== target.pageSize;
23711
+ if (isChanged) {
23712
+ tableStoreService.setPageParams(target.pageIndex, target.pageSize, totalCount);
23713
+ }
23714
+ if (isFirstEmit) {
23715
+ this._activatedRouteCheckedSubject.next(true);
23716
+ isFirstEmit = false;
23717
+ }
23718
+ });
23719
+ }
23720
+ subscribeToStoreChanges() {
23721
+ const { tableStoreService } = this._connection;
23722
+ this._writeSubscription = tableStoreService
23723
+ .pageChangeInfo$()
23724
+ .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))))
23725
+ .subscribe(info => this.writeUrl(info.pageIndex, info.pageSize));
23726
+ }
23727
+ writeUrl(pageIndex, pageSize) {
23728
+ const replaceUrl = !this._hasInitialUrlBeenSet;
23729
+ this._hasInitialUrlBeenSet = true;
23730
+ const targetPage = String(pageIndex + 1);
23731
+ const targetSize = String(pageSize);
23732
+ const urlAlreadyMatches = this.hub.snapshotQueryParam(PAGE_PARAM_NAME) === targetPage &&
23733
+ this.hub.snapshotQueryParam(SIZE_PARAM_NAME) === targetSize;
23734
+ if (urlAlreadyMatches)
23735
+ return;
23736
+ this.hub.write({ [PAGE_PARAM_NAME]: targetPage, [SIZE_PARAM_NAME]: targetSize }, replaceUrl);
23737
+ }
23738
+ parseUrlParams(queryParams) {
23739
+ const result = {};
23740
+ const rawPage = queryParams[PAGE_PARAM_NAME];
23741
+ if (typeof rawPage === 'string' && this.isValidPositiveIntegerString(rawPage)) {
23742
+ result.page = Number(rawPage);
23743
+ }
23744
+ const rawSize = queryParams[SIZE_PARAM_NAME];
23745
+ if (typeof rawSize === 'string' &&
23746
+ this.isValidPositiveIntegerString(rawSize) &&
23747
+ this.isValidSize(Number(rawSize))) {
23748
+ result.size = Number(rawSize);
23749
+ }
23750
+ return result;
23751
+ }
23752
+ isValidPositiveIntegerString(raw) {
23753
+ return /^[1-9]\d*$/.test(raw);
23754
+ }
23755
+ isValidSize(value) {
23756
+ const pageSizes = this.getConfiguredPageSizes();
23757
+ if (pageSizes && pageSizes.length > 0) {
23758
+ return pageSizes.includes(value);
23759
+ }
23760
+ return value <= SIZE_SANITY_MAX;
23761
+ }
23762
+ getConfiguredPageSizes() {
23763
+ const pagination = this._connection?.paginator.config?.pagination;
23764
+ return typeof pagination === 'object' ? pagination.pageSizes : undefined;
23765
+ }
23766
+ toStoreState(params) {
23767
+ const { paginator } = this._connection;
23768
+ return {
23769
+ pageIndex: params.page !== undefined ? params.page - 1 : 0,
23770
+ pageSize: params.size ?? paginator.getPageSizeDefault()
23771
+ };
23772
+ }
23773
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23774
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService });
23775
+ }
23776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginationRouterConnectorService, decorators: [{
23777
+ type: Injectable
23778
+ }], ctorParameters: () => [] });
23779
+
23363
23780
  class QdScrollingService {
23364
23781
  scrollIntoViewIfNeeded(element, borderDirection = 'top', targetBorderDistance = 0) {
23365
23782
  this.scrollIntoView(element, borderDirection, targetBorderDistance, true);
@@ -23588,6 +24005,7 @@ const PAGE_SIZE_DEFAULT = 25;
23588
24005
  class QdTablePaginatorComponent {
23589
24006
  tableDataResolver = inject(QD_TABLE_DATA_RESOLVER_TOKEN, { optional: true });
23590
24007
  tableStoreService = inject(QdTableStoreService);
24008
+ routerConnector = inject(QdTablePaginationRouterConnectorService);
23591
24009
  /**
23592
24010
  * @description Configuration Model for Qd-Table.
23593
24011
  */
@@ -23624,11 +24042,39 @@ class QdTablePaginatorComponent {
23624
24042
  this.totalCount$ = this.tableStoreService.totalCount$();
23625
24043
  this.selectedRowsCount$ = this.tableStoreService.selectedRows$().pipe(map(ids => ids?.length ?? 0));
23626
24044
  if (this.isConfigValid())
23627
- this.initPagination();
24045
+ this.startPagination();
23628
24046
  }
23629
24047
  ngOnDestroy() {
24048
+ this.routerConnector.disconnectPaginationFromRouter(this);
24049
+ this._destroyed$.next(null);
23630
24050
  this._destroyed$.complete();
23631
24051
  }
24052
+ /**
24053
+ * @description Whether this paginator should sync its state with the URL. Reads
24054
+ * `pagination.connectWithRouter` (default `false` — URL sync is opt-in and
24055
+ * requires an explicit `pagination: { connectWithRouter: true }`).
24056
+ *
24057
+ * Used by `QdTablePaginationRouterConnectorService` to decide whether to claim
24058
+ * the router-singleton for this paginator.
24059
+ */
24060
+ shouldConnectWithRouter() {
24061
+ const pagination = this.config?.pagination;
24062
+ if (typeof pagination !== 'object')
24063
+ return false;
24064
+ return pagination.connectWithRouter === true;
24065
+ }
24066
+ /**
24067
+ * @description The effective default page size for this paginator. Resolves
24068
+ * `pagination.pageSizeDefault` first, then falls back to the first entry of
24069
+ * `pagination.pageSizes`, finally to the framework constant `PAGE_SIZE_DEFAULT`.
24070
+ */
24071
+ getPageSizeDefault() {
24072
+ if (typeof this.config?.pagination !== 'object')
24073
+ return PAGE_SIZE_DEFAULT;
24074
+ const { pageSizeDefault, pageSizes } = this.config.pagination;
24075
+ const pageSize = pageSizes && pageSizes.length ? pageSizes[0] : PAGE_SIZE_DEFAULT;
24076
+ return pageSizeDefault || pageSize;
24077
+ }
23632
24078
  navigateToPage(direction) {
23633
24079
  if (!this.paginatorButtons)
23634
24080
  return;
@@ -23649,16 +24095,22 @@ class QdTablePaginatorComponent {
23649
24095
  }
23650
24096
  return true;
23651
24097
  }
24098
+ startPagination() {
24099
+ if (!this.shouldConnectWithRouter()) {
24100
+ this.initPagination();
24101
+ return;
24102
+ }
24103
+ this.routerConnector
24104
+ .connectPaginationWithRouter(this, this.tableStoreService)
24105
+ .pipe(takeUntil(this._destroyed$), first())
24106
+ .subscribe(connected => {
24107
+ if (!connected)
24108
+ this.initPagination();
24109
+ });
24110
+ }
23652
24111
  initPagination() {
23653
24112
  this.tableStoreService.setupPagination(this.getPageSizeDefault());
23654
24113
  }
23655
- getPageSizeDefault() {
23656
- if (typeof this.config?.pagination !== 'object')
23657
- return PAGE_SIZE_DEFAULT;
23658
- const { pageSizeDefault, pageSizes } = this.config.pagination;
23659
- const pageSize = pageSizes && pageSizes.length ? pageSizes[0] : PAGE_SIZE_DEFAULT;
23660
- return pageSizeDefault || pageSize;
23661
- }
23662
24114
  calculatePageNumber(direction, totalCount, pageSize, currentPage) {
23663
24115
  switch (direction) {
23664
24116
  case QdPaginatorDirection.NextPage: {
@@ -23677,11 +24129,11 @@ class QdTablePaginatorComponent {
23677
24129
  }
23678
24130
  }
23679
24131
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23680
- 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 });
24132
+ 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 });
23681
24133
  }
23682
24134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTablePaginatorComponent, decorators: [{
23683
24135
  type: Component,
23684
- 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"] }]
24136
+ 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"] }]
23685
24137
  }], propDecorators: { config: [{
23686
24138
  type: Input
23687
24139
  }], testId: [{
@@ -23692,6 +24144,147 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
23692
24144
  args: ['paginatorButtons']
23693
24145
  }] } });
23694
24146
 
24147
+ const SORT_PARAM_NAME = 'sort';
24148
+ const OWNED_PARAMS = [SORT_PARAM_NAME];
24149
+ const SEGMENT_SEPARATOR = ',';
24150
+ const COLUMN_DIRECTION_SEPARATOR = '.';
24151
+ class QdTableSortRouterConnectorService {
24152
+ hub = inject(QdRouterQueryParamHubService);
24153
+ destroyRef = inject(DestroyRef);
24154
+ _connection;
24155
+ _readSubscription;
24156
+ _writeSubscription;
24157
+ _activatedRouteCheckedSubject = new ReplaySubject(1);
24158
+ _activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
24159
+ _hasInitialUrlBeenSet = false;
24160
+ _hasWarnedMultiSegment = false;
24161
+ constructor() {
24162
+ this.destroyRef.onDestroy(() => {
24163
+ this.tearDownConnection();
24164
+ this.hub.release(OWNED_PARAMS, this);
24165
+ });
24166
+ }
24167
+ connectSortWithRouter(table, tableStoreService) {
24168
+ if (!this.shouldConnect(table) || !this.hub.isAvailable())
24169
+ return of(false);
24170
+ if (!this.hub.claim(OWNED_PARAMS, this))
24171
+ return of(false);
24172
+ this._connection = {
24173
+ table: table,
24174
+ tableStoreService: tableStoreService,
24175
+ configuredColumns: table.config.columns
24176
+ };
24177
+ this._hasInitialUrlBeenSet = false;
24178
+ this._hasWarnedMultiSegment = false;
24179
+ this._activatedRouteCheckedSubject = new ReplaySubject(1);
24180
+ this._activatedRouteChecked$ = this._activatedRouteCheckedSubject.asObservable();
24181
+ this.subscribeToUrlChanges();
24182
+ this.subscribeToStoreChanges();
24183
+ return this._activatedRouteChecked$;
24184
+ }
24185
+ disconnectSortFromRouter(table) {
24186
+ if (this._connection?.table !== table)
24187
+ return;
24188
+ this.tearDownConnection();
24189
+ this.hub.release(OWNED_PARAMS, this);
24190
+ }
24191
+ tearDownConnection() {
24192
+ this._connection = undefined;
24193
+ this._hasInitialUrlBeenSet = false;
24194
+ this._hasWarnedMultiSegment = false;
24195
+ this._readSubscription?.unsubscribe();
24196
+ this._writeSubscription?.unsubscribe();
24197
+ }
24198
+ subscribeToUrlChanges() {
24199
+ const { tableStoreService } = this._connection;
24200
+ let isFirstEmit = true;
24201
+ this._readSubscription = this.hub.navigationSettled$
24202
+ .pipe(switchMap(() => this.hub.queryParams()), map(queryParams => (typeof queryParams[SORT_PARAM_NAME] === 'string' ? queryParams[SORT_PARAM_NAME] : '')), distinctUntilChanged(), map(raw => this.parseRawSortValue(raw)))
24203
+ .subscribe(segments => {
24204
+ if (segments.length === 1) {
24205
+ const [{ column, direction }] = segments;
24206
+ tableStoreService.setSort(column, direction);
24207
+ }
24208
+ if (isFirstEmit) {
24209
+ this._activatedRouteCheckedSubject.next(true);
24210
+ isFirstEmit = false;
24211
+ }
24212
+ });
24213
+ }
24214
+ subscribeToStoreChanges() {
24215
+ const { tableStoreService } = this._connection;
24216
+ this._writeSubscription = tableStoreService
24217
+ .tableSort$()
24218
+ .pipe(filter((sort) => Array.isArray(sort)), map(sort => this.serializeSort(sort)), distinctUntilChanged(), switchMap(serialized => this.hub.navigationSettled$.pipe(take(1), map(() => serialized))))
24219
+ .subscribe(serialized => this.writeUrl(serialized));
24220
+ }
24221
+ writeUrl(serialized) {
24222
+ const replaceUrl = !this._hasInitialUrlBeenSet;
24223
+ this._hasInitialUrlBeenSet = true;
24224
+ if (this.hub.snapshotQueryParam(SORT_PARAM_NAME) === serialized)
24225
+ return;
24226
+ this.hub.write({ [SORT_PARAM_NAME]: serialized }, replaceUrl);
24227
+ }
24228
+ shouldConnect(table) {
24229
+ const sortConfig = table.config.sort;
24230
+ if (sortConfig === true || sortConfig === undefined)
24231
+ return false;
24232
+ return sortConfig.connectWithRouter === true;
24233
+ }
24234
+ parseRawSortValue(raw) {
24235
+ if (raw.length === 0)
24236
+ return [];
24237
+ const rawSegments = raw.split(SEGMENT_SEPARATOR);
24238
+ const validSegments = rawSegments
24239
+ .map(segment => this.parseSegment(segment))
24240
+ .filter((segment) => segment !== undefined);
24241
+ if (validSegments.length > 1) {
24242
+ if (!this._hasWarnedMultiSegment) {
24243
+ console.warn('Quadrel Framework | QdTable - Multi-column sort URL is not yet supported. Using first valid segment only.');
24244
+ this._hasWarnedMultiSegment = true;
24245
+ }
24246
+ return [validSegments[0]];
24247
+ }
24248
+ return validSegments;
24249
+ }
24250
+ parseSegment(segment) {
24251
+ if (segment.length === 0)
24252
+ return undefined;
24253
+ const separatorIndex = segment.indexOf(COLUMN_DIRECTION_SEPARATOR);
24254
+ if (separatorIndex <= 0 || separatorIndex === segment.length - 1)
24255
+ return undefined;
24256
+ const column = segment.slice(0, separatorIndex);
24257
+ const directionRaw = segment.slice(separatorIndex + 1).toLowerCase();
24258
+ if (!this.isValidColumn(column))
24259
+ return undefined;
24260
+ if (directionRaw === 'asc')
24261
+ return { column, direction: QdSortDirection.ASC };
24262
+ if (directionRaw === 'desc')
24263
+ return { column, direction: QdSortDirection.DESC };
24264
+ return undefined;
24265
+ }
24266
+ isValidColumn(column) {
24267
+ const config = this._connection?.configuredColumns.find(c => c.column === column);
24268
+ return !!config && config.sort !== undefined && config.sort.isDisabled !== true;
24269
+ }
24270
+ serializeSort(sort) {
24271
+ const active = sort.filter((entry) => entry.direction === QdSortDirection.ASC || entry.direction === QdSortDirection.DESC);
24272
+ if (active.length === 0)
24273
+ return undefined;
24274
+ return active
24275
+ .map(entry => `${entry.column}${COLUMN_DIRECTION_SEPARATOR}${this.directionToString(entry.direction)}`)
24276
+ .join(SEGMENT_SEPARATOR);
24277
+ }
24278
+ directionToString(direction) {
24279
+ return direction === QdSortDirection.ASC ? 'asc' : 'desc';
24280
+ }
24281
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
24282
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService });
24283
+ }
24284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableSortRouterConnectorService, decorators: [{
24285
+ type: Injectable
24286
+ }], ctorParameters: () => [] });
24287
+
23695
24288
  class QdTableRowActionsSecondaryMenuComponent {
23696
24289
  actionsService = inject(QdTableSecondaryActionsService);
23697
24290
  tableStore = inject(QdTableStoreService);
@@ -24307,6 +24900,7 @@ class QdTableComponent {
24307
24900
  breakpointService = inject(QdBreakpointService);
24308
24901
  resolverService = inject(QdTableResolverService);
24309
24902
  confirmationDialogService = inject(QdConfirmationDialogOpenerService);
24903
+ sortRouterConnector = inject(QdTableSortRouterConnectorService);
24310
24904
  /**
24311
24905
  * Configuration of the table. The generic type specifies the column definition. <br />
24312
24906
  *
@@ -24414,6 +25008,7 @@ class QdTableComponent {
24414
25008
  this.tableStoreService.initTableState(this._data, this.hasResolver, this._connectors, this.hasPagination);
24415
25009
  this.tableStoreService.updateTableStateRecentSecondaryAction(undefined);
24416
25010
  this.tableStoreService.setupSort(this.config.columns);
25011
+ this.sortRouterConnector.connectSortWithRouter(this, this.tableStoreService).pipe(take(1)).subscribe();
24417
25012
  this.resolverService.init(this.config.refreshOnLanguageChange, this.hasPagination);
24418
25013
  this.data$ = this.tableStoreService.tableDataEntries$();
24419
25014
  this.initializeResponsiveRowService();
@@ -24444,6 +25039,7 @@ class QdTableComponent {
24444
25039
  }
24445
25040
  }
24446
25041
  ngOnDestroy() {
25042
+ this.sortRouterConnector.disconnectSortFromRouter(this);
24447
25043
  this.tableStoreService.updateTableStateRecentSecondaryAction(undefined);
24448
25044
  this.tableStoreService.resetConnectorStates();
24449
25045
  this.fillingWidthService.destroy();
@@ -24613,7 +25209,8 @@ class QdTableComponent {
24613
25209
  QdTableRowSelectionService,
24614
25210
  QdTableFillingWidthService,
24615
25211
  QdTableResolverService,
24616
- QdTableExternalActionResultService
25212
+ QdTableExternalActionResultService,
25213
+ QdTableSortRouterConnectorService
24617
25214
  ], 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 });
24618
25215
  }
24619
25216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdTableComponent, decorators: [{
@@ -24627,7 +25224,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
24627
25224
  QdTableRowSelectionService,
24628
25225
  QdTableFillingWidthService,
24629
25226
  QdTableResolverService,
24630
- QdTableExternalActionResultService
25227
+ QdTableExternalActionResultService,
25228
+ QdTableSortRouterConnectorService
24631
25229
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
24632
25230
  '[class.qd-table]': 'true',
24633
25231
  '[class.main-column-fills-width]': 'whichColumnFillsWidth === "main"',
@@ -30322,147 +30920,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
30322
30920
  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"] }]
30323
30921
  }] });
30324
30922
 
30325
- // @ts-strict-ignore
30326
- class QdNavigationService {
30327
- router = inject(Router);
30328
- activatedRoute = inject(ActivatedRoute);
30329
- routeLeafSnapshot$;
30330
- routeData$;
30331
- routeComponentInstanceSubject = new ReplaySubject(1);
30332
- constructor() {
30333
- 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'));
30334
- this.routeData$ = this.routeLeafSnapshot$.pipe(map((snapshot) => snapshot.routeConfig?.data || {}), shareReplay(1));
30335
- }
30336
- getLeafRoute(route) {
30337
- if (!route.firstChild)
30338
- return route;
30339
- return this.getLeafRoute(route.firstChild);
30340
- }
30341
- isHome$() {
30342
- return this.routeData$.pipe(map(({ isHome }) => isHome ?? false));
30343
- }
30344
- getRouteParams$() {
30345
- return this.routeLeafSnapshot$.pipe(map(this.getMergedRouteParams.bind(this)));
30346
- }
30347
- getMergedRouteParams(snapshot) {
30348
- if (!snapshot)
30349
- return {};
30350
- return {
30351
- ...this.getMergedRouteParams(snapshot.parent),
30352
- ...(snapshot.params || {})
30353
- };
30354
- }
30355
- getPreviousHref$() {
30356
- return this.routeData$.pipe(map(({ previousHref }) => previousHref));
30357
- }
30358
- navigate(commands, extras) {
30359
- return this.router.navigate(commands, extras);
30360
- }
30361
- navigateByUrl(url, extras) {
30362
- return this.router.navigateByUrl(url, extras);
30363
- }
30364
- updateRouteComponentInstance(routeComponentInstance) {
30365
- this.routeComponentInstanceSubject.next(routeComponentInstance);
30366
- }
30367
- getRouteComponentInstance$() {
30368
- return this.routeComponentInstanceSubject.asObservable();
30369
- }
30370
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30371
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService });
30372
- }
30373
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, decorators: [{
30374
- type: Injectable
30375
- }], ctorParameters: () => [] });
30376
-
30377
- // @ts-strict-ignore
30378
- class QdShellLeftService {
30379
- _hasNavigation = new BehaviorSubject(false);
30380
- _isNavigationPinned = new BehaviorSubject(false);
30381
- _isNavigationRolledOver = new BehaviorSubject(false);
30382
- hasNavigation$ = this._hasNavigation.asObservable();
30383
- isNavigationPinned$ = this._isNavigationPinned.asObservable();
30384
- isNavigationRolledOver$ = this._isNavigationRolledOver.asObservable();
30385
- set config(config) {
30386
- this._hasNavigation.next(config.navigation?.length > 0);
30387
- }
30388
- set isNavigationRolledOver(value) {
30389
- this._isNavigationRolledOver.next(value);
30390
- }
30391
- togglePinnedNavigation() {
30392
- this._isNavigationPinned.next(!this._isNavigationPinned.value);
30393
- }
30394
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30395
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService });
30396
- }
30397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, decorators: [{
30398
- type: Injectable
30399
- }] });
30400
-
30401
- class QdShellRightService {
30402
- notificationsService = inject(QdNotificationsService);
30403
- _open = new BehaviorSubject(false);
30404
- _pinned = new BehaviorSubject(false);
30405
- _hasNotificationsToggle = new BehaviorSubject(false);
30406
- open$ = this._open.asObservable();
30407
- pinned$ = this._pinned.asObservable();
30408
- notifications$;
30409
- set open(open) {
30410
- this._open.next(open);
30411
- }
30412
- get hasNotificationsToggle$() {
30413
- return combineLatest([this._hasNotificationsToggle, this.hasNotifications$]).pipe(map(([hasNotificationsToggle, hasNotifications]) => hasNotificationsToggle || hasNotifications));
30414
- }
30415
- get hasNotifications$() {
30416
- return this.notifications$.pipe(map(notifications => notifications.length > 0));
30417
- }
30418
- set config(config) {
30419
- this._hasNotificationsToggle.next(config.hasNotificationsToggle ?? false);
30420
- }
30421
- constructor() {
30422
- const notificationsService = this.notificationsService;
30423
- this.notifications$ = notificationsService.getNotificationsForContext('shell');
30424
- this._open.pipe(filter(open => open)).subscribe(() => {
30425
- this._pinned.next(false);
30426
- });
30427
- }
30428
- toggleOpen() {
30429
- this._open.next(!this._open.value);
30430
- }
30431
- togglePinned() {
30432
- this._pinned.next(!this._pinned.value);
30433
- }
30434
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30435
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService });
30436
- }
30437
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, decorators: [{
30438
- type: Injectable
30439
- }], ctorParameters: () => [] });
30440
-
30441
- // @ts-strict-ignore
30442
- class QdShellHeaderMinimizationService {
30443
- navigationService = inject(QdNavigationService);
30444
- breakpointService = inject(QdBreakpointService);
30445
- _headerMinimizedBreakpoints = ['sm', 'xs'];
30446
- _config;
30447
- _isInternal$ = new BehaviorSubject(false);
30448
- set config(config) {
30449
- this._config = config;
30450
- this._isInternal$.next(config.isInternal);
30451
- }
30452
- isHeaderMinimized$() {
30453
- const isMinimizedForAllBreakpoints$ = this._isInternal$.pipe(combineLatestWith(this.navigationService.isHome$()), map(([isInternal, isHomePage]) => isInternal ?? !isHomePage));
30454
- return isMinimizedForAllBreakpoints$.pipe(combineLatestWith(this.breakpointService.getMatchingBreakpoint()), map(([isMinimizedForAllBreakpoints, breakpoint]) => isMinimizedForAllBreakpoints || this._isMinimizedBreakpoint(breakpoint)));
30455
- }
30456
- _isMinimizedBreakpoint(breakpoint) {
30457
- return this._headerMinimizedBreakpoints.includes(breakpoint);
30458
- }
30459
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30460
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService });
30461
- }
30462
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, decorators: [{
30463
- type: Injectable
30464
- }] });
30465
-
30466
30923
  // @ts-strict-ignore
30467
30924
  const loadJavascriptAsset = (path, scriptElementAttributes = {}) => {
30468
30925
  const scriptElement = document.createElement('script');
@@ -30918,6 +31375,162 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
30918
31375
  args: ['serviceNavigation']
30919
31376
  }] } });
30920
31377
 
31378
+ class QdShellServiceNavigationModule {
31379
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
31380
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, declarations: [QdShellServiceNavigationComponent], imports: [CommonModule], exports: [QdShellServiceNavigationComponent] });
31381
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, imports: [CommonModule] });
31382
+ }
31383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, decorators: [{
31384
+ type: NgModule,
31385
+ args: [{
31386
+ imports: [CommonModule],
31387
+ declarations: [QdShellServiceNavigationComponent],
31388
+ exports: [QdShellServiceNavigationComponent],
31389
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
31390
+ }]
31391
+ }] });
31392
+
31393
+ // @ts-strict-ignore
31394
+ class QdNavigationService {
31395
+ router = inject(Router);
31396
+ activatedRoute = inject(ActivatedRoute);
31397
+ routeLeafSnapshot$;
31398
+ routeData$;
31399
+ routeComponentInstanceSubject = new ReplaySubject(1);
31400
+ constructor() {
31401
+ 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'));
31402
+ this.routeData$ = this.routeLeafSnapshot$.pipe(map((snapshot) => snapshot.routeConfig?.data || {}), shareReplay(1));
31403
+ }
31404
+ getLeafRoute(route) {
31405
+ if (!route.firstChild)
31406
+ return route;
31407
+ return this.getLeafRoute(route.firstChild);
31408
+ }
31409
+ isHome$() {
31410
+ return this.routeData$.pipe(map(({ isHome }) => isHome ?? false));
31411
+ }
31412
+ getRouteParams$() {
31413
+ return this.routeLeafSnapshot$.pipe(map(this.getMergedRouteParams.bind(this)));
31414
+ }
31415
+ getMergedRouteParams(snapshot) {
31416
+ if (!snapshot)
31417
+ return {};
31418
+ return {
31419
+ ...this.getMergedRouteParams(snapshot.parent),
31420
+ ...(snapshot.params || {})
31421
+ };
31422
+ }
31423
+ getPreviousHref$() {
31424
+ return this.routeData$.pipe(map(({ previousHref }) => previousHref));
31425
+ }
31426
+ navigate(commands, extras) {
31427
+ return this.router.navigate(commands, extras);
31428
+ }
31429
+ navigateByUrl(url, extras) {
31430
+ return this.router.navigateByUrl(url, extras);
31431
+ }
31432
+ updateRouteComponentInstance(routeComponentInstance) {
31433
+ this.routeComponentInstanceSubject.next(routeComponentInstance);
31434
+ }
31435
+ getRouteComponentInstance$() {
31436
+ return this.routeComponentInstanceSubject.asObservable();
31437
+ }
31438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31439
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService });
31440
+ }
31441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdNavigationService, decorators: [{
31442
+ type: Injectable
31443
+ }], ctorParameters: () => [] });
31444
+
31445
+ // @ts-strict-ignore
31446
+ class QdShellLeftService {
31447
+ _hasNavigation = new BehaviorSubject(false);
31448
+ _isNavigationPinned = new BehaviorSubject(false);
31449
+ _isNavigationRolledOver = new BehaviorSubject(false);
31450
+ hasNavigation$ = this._hasNavigation.asObservable();
31451
+ isNavigationPinned$ = this._isNavigationPinned.asObservable();
31452
+ isNavigationRolledOver$ = this._isNavigationRolledOver.asObservable();
31453
+ set config(config) {
31454
+ this._hasNavigation.next(config.navigation?.length > 0);
31455
+ }
31456
+ set isNavigationRolledOver(value) {
31457
+ this._isNavigationRolledOver.next(value);
31458
+ }
31459
+ togglePinnedNavigation() {
31460
+ this._isNavigationPinned.next(!this._isNavigationPinned.value);
31461
+ }
31462
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31463
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService });
31464
+ }
31465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellLeftService, decorators: [{
31466
+ type: Injectable
31467
+ }] });
31468
+
31469
+ class QdShellRightService {
31470
+ notificationsService = inject(QdNotificationsService);
31471
+ _open = new BehaviorSubject(false);
31472
+ _pinned = new BehaviorSubject(false);
31473
+ _hasNotificationsToggle = new BehaviorSubject(false);
31474
+ open$ = this._open.asObservable();
31475
+ pinned$ = this._pinned.asObservable();
31476
+ notifications$;
31477
+ set open(open) {
31478
+ this._open.next(open);
31479
+ }
31480
+ get hasNotificationsToggle$() {
31481
+ return combineLatest([this._hasNotificationsToggle, this.hasNotifications$]).pipe(map(([hasNotificationsToggle, hasNotifications]) => hasNotificationsToggle || hasNotifications));
31482
+ }
31483
+ get hasNotifications$() {
31484
+ return this.notifications$.pipe(map(notifications => notifications.length > 0));
31485
+ }
31486
+ set config(config) {
31487
+ this._hasNotificationsToggle.next(config.hasNotificationsToggle ?? false);
31488
+ }
31489
+ constructor() {
31490
+ const notificationsService = this.notificationsService;
31491
+ this.notifications$ = notificationsService.getNotificationsForContext('shell');
31492
+ this._open.pipe(filter(open => open)).subscribe(() => {
31493
+ this._pinned.next(false);
31494
+ });
31495
+ }
31496
+ toggleOpen() {
31497
+ this._open.next(!this._open.value);
31498
+ }
31499
+ togglePinned() {
31500
+ this._pinned.next(!this._pinned.value);
31501
+ }
31502
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31503
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService });
31504
+ }
31505
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellRightService, decorators: [{
31506
+ type: Injectable
31507
+ }], ctorParameters: () => [] });
31508
+
31509
+ // @ts-strict-ignore
31510
+ class QdShellHeaderMinimizationService {
31511
+ navigationService = inject(QdNavigationService);
31512
+ breakpointService = inject(QdBreakpointService);
31513
+ _headerMinimizedBreakpoints = ['sm', 'xs'];
31514
+ _config;
31515
+ _isInternal$ = new BehaviorSubject(false);
31516
+ set config(config) {
31517
+ this._config = config;
31518
+ this._isInternal$.next(config.isInternal);
31519
+ }
31520
+ isHeaderMinimized$() {
31521
+ const isMinimizedForAllBreakpoints$ = this._isInternal$.pipe(combineLatestWith(this.navigationService.isHome$()), map(([isInternal, isHomePage]) => isInternal ?? !isHomePage));
31522
+ return isMinimizedForAllBreakpoints$.pipe(combineLatestWith(this.breakpointService.getMatchingBreakpoint()), map(([isMinimizedForAllBreakpoints, breakpoint]) => isMinimizedForAllBreakpoints || this._isMinimizedBreakpoint(breakpoint)));
31523
+ }
31524
+ _isMinimizedBreakpoint(breakpoint) {
31525
+ return this._headerMinimizedBreakpoints.includes(breakpoint);
31526
+ }
31527
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
31528
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService });
31529
+ }
31530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellHeaderMinimizationService, decorators: [{
31531
+ type: Injectable
31532
+ }] });
31533
+
30921
31534
  // @ts-strict-ignore
30922
31535
  const DEFAULT_LANGUAGE_LIST$1 = ['de', 'fr', 'it', 'en'];
30923
31536
  class QdShellHeaderWidgetService {
@@ -32000,21 +32613,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
32000
32613
  args: [QdCommentsComponent]
32001
32614
  }] } });
32002
32615
 
32003
- class QdShellServiceNavigationModule {
32004
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
32005
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, declarations: [QdShellServiceNavigationComponent], imports: [CommonModule], exports: [QdShellServiceNavigationComponent] });
32006
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, imports: [CommonModule] });
32007
- }
32008
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: QdShellServiceNavigationModule, decorators: [{
32009
- type: NgModule,
32010
- args: [{
32011
- imports: [CommonModule],
32012
- declarations: [QdShellServiceNavigationComponent],
32013
- exports: [QdShellServiceNavigationComponent],
32014
- schemas: [CUSTOM_ELEMENTS_SCHEMA]
32015
- }]
32016
- }] });
32017
-
32018
32616
  function initializeBreadcrumbServices(breadcrumbsService, dialogBreadcrumbsService) {
32019
32617
  return () => {
32020
32618
  breadcrumbsService.initialize();
@@ -33267,5 +33865,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
33267
33865
  * Generated bundle index. Do not edit.
33268
33866
  */
33269
33867
 
33270
- 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, 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 };
33868
+ 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, 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 };
33271
33869
  //# sourceMappingURL=quadrel-enterprise-ui-framework.mjs.map