@yuuvis/client-framework 3.23.0 → 3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/yuuvis-client-framework-forms.mjs +311 -17
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-metadata-form.mjs +8 -6
- package/fesm2022/yuuvis-client-framework-metadata-form.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-form.mjs +27 -4
- package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +144 -69
- package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-smart-search.mjs +35 -3
- package/fesm2022/yuuvis-client-framework-smart-search.mjs.map +1 -1
- package/lib/assets/i18n/de.json +1 -0
- package/lib/assets/i18n/en.json +1 -0
- package/package.json +5 -5
- package/types/yuuvis-client-framework-forms.d.ts +104 -4
- package/types/yuuvis-client-framework-query-list.d.ts +20 -12
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, viewChild, contentChild, input, output, computed, untracked, effect, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
2
|
+
import { inject, signal, viewChild, contentChild, input, output, computed, linkedSignal, untracked, effect, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
3
3
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
6
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
7
|
import * as i3 from '@angular/material/paginator';
|
|
7
|
-
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
8
|
+
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
8
9
|
import { SearchService } from '@yuuvis/client-core';
|
|
9
10
|
import { ClickDoubleDirective, DragSelectDirective, DragSelectItemDirective } from '@yuuvis/client-framework/common';
|
|
10
11
|
import * as i2 from '@yuuvis/client-framework/list';
|
|
11
12
|
import { YuvListModule } from '@yuuvis/client-framework/list';
|
|
12
13
|
import { DeviceService } from '@yuuvis/material';
|
|
14
|
+
import { Subject, switchMap, EMPTY, defer, map, catchError, finalize } from 'rxjs';
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Query-driven list component that executes a search query and renders the results
|
|
@@ -78,6 +80,14 @@ class QueryListComponent {
|
|
|
78
80
|
#items;
|
|
79
81
|
#dropInItems;
|
|
80
82
|
#listItemUpdates;
|
|
83
|
+
// Every search the list runs — new query, page change, refresh — goes through this one stream, so
|
|
84
|
+
// a newer request cancels the one still in flight instead of racing it, and a late response can
|
|
85
|
+
// never overwrite a newer one (see `#load`). `null` cancels without a new request (see `#cancel`).
|
|
86
|
+
#requests;
|
|
87
|
+
// The request still in flight — `busy` follows it — and the one whose result is on screen: what
|
|
88
|
+
// `refresh()` re-runs.
|
|
89
|
+
#pendingRequest;
|
|
90
|
+
#shownRequest;
|
|
81
91
|
//#endregion
|
|
82
92
|
constructor() {
|
|
83
93
|
//#region Dependencies
|
|
@@ -132,8 +142,8 @@ class QueryListComponent {
|
|
|
132
142
|
*
|
|
133
143
|
* Accepts either a structured `SearchQuery` object (field filters, sort orders, etc.)
|
|
134
144
|
* or a raw CMIS query string. The query is re-executed reactively every time this
|
|
135
|
-
* input changes. Set to `null` or `undefined` to
|
|
136
|
-
*
|
|
145
|
+
* input changes. Set to `null` or `undefined` to stop searching: a request still in
|
|
146
|
+
* flight is cancelled, and the list keeps showing the result it has.
|
|
137
147
|
*/
|
|
138
148
|
this.query = input(...(ngDevMode ? [undefined, { debugName: "query" }] : /* istanbul ignore next */ []));
|
|
139
149
|
/**
|
|
@@ -375,27 +385,44 @@ class QueryListComponent {
|
|
|
375
385
|
/**
|
|
376
386
|
* Indicates whether a search request is currently in flight.
|
|
377
387
|
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
388
|
+
* `true` from the moment a query or page request is dispatched to the search service until
|
|
389
|
+
* the latest request settles (response, error or cancellation). A request superseded by a
|
|
390
|
+
* newer one is cancelled, and `busy` stays `true` across that switch. Derived from the request
|
|
391
|
+
* in flight but still writable: a value set from outside holds until the loading state changes.
|
|
380
392
|
* Bind this to a loading indicator or `BusyOverlayDirective` in the parent template:
|
|
381
393
|
* ```html
|
|
382
394
|
* <yuv-query-list #qList ...>...</yuv-query-list>
|
|
383
395
|
* <yuv-busy-overlay [active]="qList.busy()" />
|
|
384
396
|
* ```
|
|
385
397
|
*/
|
|
386
|
-
this.busy =
|
|
398
|
+
this.busy = linkedSignal(() => this.#pendingRequest() !== null, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
|
|
399
|
+
// Only there while the result has several pages. TS `private` because a signal query cannot sit
|
|
400
|
+
// on an ES-private field (NG1053).
|
|
401
|
+
this.paginator = viewChild(MatPaginator, ...(ngDevMode ? [{ debugName: "paginator" }] : /* istanbul ignore next */ []));
|
|
387
402
|
this.#items = signal([], ...(ngDevMode ? [{ debugName: "#items" }] : /* istanbul ignore next */ []));
|
|
388
403
|
this.#dropInItems = signal([], ...(ngDevMode ? [{ debugName: "#dropInItems" }] : /* istanbul ignore next */ []));
|
|
389
404
|
this.#listItemUpdates = signal({}, ...(ngDevMode ? [{ debugName: "#listItemUpdates" }] : /* istanbul ignore next */ []));
|
|
405
|
+
// Every search the list runs — new query, page change, refresh — goes through this one stream, so
|
|
406
|
+
// a newer request cancels the one still in flight instead of racing it, and a late response can
|
|
407
|
+
// never overwrite a newer one (see `#load`). `null` cancels without a new request (see `#cancel`).
|
|
408
|
+
this.#requests = new Subject();
|
|
409
|
+
// The request still in flight — `busy` follows it — and the one whose result is on screen: what
|
|
410
|
+
// `refresh()` re-runs.
|
|
411
|
+
this.#pendingRequest = signal(null, ...(ngDevMode ? [{ debugName: "#pendingRequest" }] : /* istanbul ignore next */ []));
|
|
412
|
+
this.#shownRequest = signal(null, ...(ngDevMode ? [{ debugName: "#shownRequest" }] : /* istanbul ignore next */ []));
|
|
390
413
|
//#endregion
|
|
391
414
|
//#region Effects
|
|
392
415
|
this.#executeQueryEffect = () => {
|
|
393
416
|
// execute the query each time it changes
|
|
394
417
|
const query = this.query();
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
this.#
|
|
398
|
-
}
|
|
418
|
+
untracked(() => {
|
|
419
|
+
if (query) {
|
|
420
|
+
this.#request({ query, page: null });
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
this.#cancel();
|
|
424
|
+
}
|
|
425
|
+
});
|
|
399
426
|
};
|
|
400
427
|
/**
|
|
401
428
|
* Keeps the inner list's positional selection aligned with the id-based {@link selectedIds}
|
|
@@ -433,6 +460,9 @@ class QueryListComponent {
|
|
|
433
460
|
};
|
|
434
461
|
effect(this.#executeQueryEffect);
|
|
435
462
|
effect(this.#resyncSelectionEffect);
|
|
463
|
+
this.#requests
|
|
464
|
+
.pipe(switchMap((request) => (request ? this.#load(request) : EMPTY)), takeUntilDestroyed())
|
|
465
|
+
.subscribe(({ request, result }) => this.#showResult(request, result));
|
|
436
466
|
}
|
|
437
467
|
//#region UI Methods
|
|
438
468
|
/** Resolves the tracking key for a result item in the `@for` loop. */
|
|
@@ -591,7 +621,7 @@ class QueryListComponent {
|
|
|
591
621
|
* appear in the current query (e.g. because the index has not been updated), drop it
|
|
592
622
|
* in temporarily so the user sees it immediately without a full refresh.
|
|
593
623
|
*
|
|
594
|
-
* Drop-in items are cleared automatically
|
|
624
|
+
* Drop-in items are cleared automatically once a page the user navigates to is shown.
|
|
595
625
|
* Call `dropItems([])` to remove them programmatically.
|
|
596
626
|
*
|
|
597
627
|
* @param items Items to prepend. Must be of type `T` (same as query result items).
|
|
@@ -699,21 +729,24 @@ class QueryListComponent {
|
|
|
699
729
|
/**
|
|
700
730
|
* Re-executes the current query without changing the page or query parameters.
|
|
701
731
|
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
732
|
+
* Re-runs what the list is about to show or is showing: a request still in flight, otherwise
|
|
733
|
+
* the page the user is currently on, or the query from scratch if it has only one page. If that
|
|
734
|
+
* page no longer exists — its objects were deleted — the list moves to the last page there is.
|
|
704
735
|
*
|
|
705
736
|
* Use this to reflect server-side changes (e.g. after a create/delete operation)
|
|
706
737
|
* without navigating away from the current view.
|
|
707
738
|
*/
|
|
708
739
|
refresh() {
|
|
709
740
|
const query = this.query();
|
|
710
|
-
if (query)
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
741
|
+
if (!query)
|
|
742
|
+
return;
|
|
743
|
+
// A request in flight is re-run as it is, so a page change still clears the drop-in items. The shown
|
|
744
|
+
// one only for its page: its drop-ins are gone already, and any there now were added since.
|
|
745
|
+
// Not `pagination()`: after a new query failed to load, that still describes the previous query's
|
|
746
|
+
// result, and its page number would be applied to the new one.
|
|
747
|
+
const pending = this.#pendingRequest();
|
|
748
|
+
const shown = this.#shownRequest();
|
|
749
|
+
this.#request(pending?.query === query ? pending : { query, page: shown?.query === query ? shown.page : null });
|
|
717
750
|
}
|
|
718
751
|
/**
|
|
719
752
|
* Forces the `transformer` function to be re-applied to the current result set.
|
|
@@ -730,25 +763,33 @@ class QueryListComponent {
|
|
|
730
763
|
/**
|
|
731
764
|
* Handles a page-change event emitted by the `mat-paginator`.
|
|
732
765
|
*
|
|
733
|
-
*
|
|
734
|
-
*
|
|
766
|
+
* Loads the page for the zero-based `pageEvent.pageIndex`, like `goToPage()`, and clears the
|
|
767
|
+
* drop-in items once that page is shown. If it fails to load, they stay.
|
|
735
768
|
*
|
|
736
769
|
* Bound to `(page)` on the `mat-paginator` in the template.
|
|
737
770
|
*
|
|
771
|
+
* Ignored while the paginator still shows the previous query's result — a new query is loading or
|
|
772
|
+
* failed to load — since its page numbers mean nothing for the current query.
|
|
773
|
+
*
|
|
738
774
|
* @param pageEvent The pagination event emitted by `MatPaginatorModule`.
|
|
739
775
|
*/
|
|
740
776
|
changePage(pageEvent) {
|
|
741
|
-
this.#
|
|
742
|
-
|
|
777
|
+
const shown = this.#shownRequest();
|
|
778
|
+
if (!shown || shown.query !== this.query()) {
|
|
779
|
+
this.#syncPaginatorPage();
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
this.#request({ query: shown.query, page: pageEvent.pageIndex + 1, clearDropIns: true });
|
|
743
783
|
}
|
|
744
784
|
/**
|
|
745
785
|
* Fetches and displays the given page of the current query result.
|
|
746
786
|
*
|
|
747
787
|
* Sets `busy` to `true` for the duration of the request. On success, updates
|
|
748
788
|
* the pagination state, clears all optimistic overrides (they are page-scoped),
|
|
749
|
-
* and replaces `#items` with the new page's results.
|
|
750
|
-
*
|
|
751
|
-
*
|
|
789
|
+
* and replaces `#items` with the new page's results. A request still in flight — an earlier
|
|
790
|
+
* page change or a new query — is cancelled. If loading the page fails, the list and the
|
|
791
|
+
* paginator stay on the page that was loaded before. A page past the last one loads the last
|
|
792
|
+
* page instead.
|
|
752
793
|
*
|
|
753
794
|
* @param page One-based page number to navigate to.
|
|
754
795
|
*/
|
|
@@ -756,21 +797,7 @@ class QueryListComponent {
|
|
|
756
797
|
const query = this.query();
|
|
757
798
|
if (!query)
|
|
758
799
|
return;
|
|
759
|
-
this
|
|
760
|
-
this.#searchService.getPage(query, page, this.effectivePageSize(), this.includePermissions()).subscribe({
|
|
761
|
-
next: (res) => {
|
|
762
|
-
this.#setupPagination(res);
|
|
763
|
-
this.#listItemUpdates.set({});
|
|
764
|
-
this.#items.set(res.items);
|
|
765
|
-
this.queryResult.emit({ totalCount: res.totalNumItems, items: res.items });
|
|
766
|
-
this.busy.set(false);
|
|
767
|
-
},
|
|
768
|
-
error: (err) => {
|
|
769
|
-
// TODO: how should errors be handles in case hat loading pages fail
|
|
770
|
-
this.busy.set(false);
|
|
771
|
-
console.error(err);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
800
|
+
this.#request({ query, page });
|
|
774
801
|
}
|
|
775
802
|
//#endregion
|
|
776
803
|
//#region Utilities
|
|
@@ -782,32 +809,80 @@ class QueryListComponent {
|
|
|
782
809
|
const value = item[prop];
|
|
783
810
|
return value == null ? undefined : String(value);
|
|
784
811
|
}
|
|
812
|
+
/** Starts `request`, cancelling any request still in flight (see `#requests`). */
|
|
813
|
+
#request(request) {
|
|
814
|
+
// A copy: `#load` tells requests apart by identity, and `request` may be the one still in flight.
|
|
815
|
+
const started = { ...request };
|
|
816
|
+
// Before `next()`: `switchMap` cancels the superseded request first, and its `finalize` must already
|
|
817
|
+
// find a newer request pending, or it would clear `busy` while this one is still loading.
|
|
818
|
+
this.#pendingRequest.set(started);
|
|
819
|
+
this.#requests.next(started);
|
|
820
|
+
}
|
|
785
821
|
/**
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
* This may be a SearchQuery object or a string. If it's a string, it is supposed to
|
|
789
|
-
* be a CMIS query statement.
|
|
822
|
+
* Cancels the request still in flight, if any; the list keeps what it shows. With no newer request
|
|
823
|
+
* pending, the cancelled one's `finalize` clears `busy` and syncs the paginator.
|
|
790
824
|
*/
|
|
791
|
-
#
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
825
|
+
#cancel() {
|
|
826
|
+
this.#requests.next(null);
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Loads one request. A failure is logged and leaves the current result in place, and it must not
|
|
830
|
+
* end `#requests` — every later search goes through that same stream.
|
|
831
|
+
*/
|
|
832
|
+
#load(request) {
|
|
833
|
+
// `defer`: building the search can throw — e.g. a query that cannot be serialized — and a throw
|
|
834
|
+
// outside the pipe would get past `catchError`.
|
|
835
|
+
return defer(() => this.#search(request)).pipe(map((result) => ({ request, result })), catchError((err) => {
|
|
836
|
+
console.error(err);
|
|
837
|
+
return EMPTY;
|
|
838
|
+
}), finalize(() => {
|
|
839
|
+
// A superseded request leaves `busy` and the paginator to the one that replaced it.
|
|
840
|
+
if (this.#pendingRequest() !== request)
|
|
841
|
+
return;
|
|
842
|
+
this.#pendingRequest.set(null);
|
|
843
|
+
this.#syncPaginatorPage();
|
|
844
|
+
}));
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* The search call for `request`. The query may be a `SearchQuery` object or a string; a string is
|
|
848
|
+
* supposed to be a CMIS query statement.
|
|
849
|
+
*/
|
|
850
|
+
#search({ query, page }) {
|
|
851
|
+
const size = this.effectivePageSize();
|
|
852
|
+
// `getPage` writes `from` onto a query object and pages it by the object's own `size`, so it gets a copy
|
|
853
|
+
// sized to this list's pages. Left on the consumer's object, `from` would open its next search — or a
|
|
854
|
+
// copy made for a sort change — on a later page.
|
|
855
|
+
const target = typeof query === 'string' ? query : { ...query, size };
|
|
856
|
+
return this.#searchService.getPage(target, page ?? 1, size, this.includePermissions());
|
|
857
|
+
}
|
|
858
|
+
#showResult(request, result) {
|
|
859
|
+
const lastPage = result.paging?.totalPages ?? 1;
|
|
860
|
+
if (request.page !== null && request.page > lastPage) {
|
|
861
|
+
// The page is gone, e.g. `refresh()` after its objects were deleted. Showing it empty would strand
|
|
862
|
+
// the user, and with a single page left there is not even a paginator to leave it with.
|
|
863
|
+
this.#request({ ...request, page: lastPage > 1 ? lastPage : null });
|
|
864
|
+
return;
|
|
810
865
|
}
|
|
866
|
+
this.#shownRequest.set(request);
|
|
867
|
+
// Before `queryResult`: `TileListComponent` keeps as many leading items as there are drop-ins then.
|
|
868
|
+
if (request.clearDropIns)
|
|
869
|
+
this.#dropInItems.set([]);
|
|
870
|
+
this.#setupPagination(result);
|
|
871
|
+
this.#listItemUpdates.set({});
|
|
872
|
+
this.#items.set(result.items);
|
|
873
|
+
this.queryResult.emit({ totalCount: result.totalNumItems, items: result.items });
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Puts the paginator on the page that is actually loaded. It moves to the requested page as soon as
|
|
877
|
+
* it is clicked, and its `[pageIndex]` binding cannot undo that when the click does not load: the
|
|
878
|
+
* request failed, or a newer one replaced it and loaded the page that was bound before. The bound
|
|
879
|
+
* value has not changed, so Angular does not re-apply it.
|
|
880
|
+
*/
|
|
881
|
+
#syncPaginatorPage() {
|
|
882
|
+
const paginator = this.paginator();
|
|
883
|
+
const page = this.pagination()?.page;
|
|
884
|
+
if (paginator && page)
|
|
885
|
+
paginator.pageIndex = page - 1;
|
|
811
886
|
}
|
|
812
887
|
#setupPagination(searchResult) {
|
|
813
888
|
this.pagination.set(searchResult.paging
|
|
@@ -835,7 +910,7 @@ class QueryListComponent {
|
|
|
835
910
|
*/
|
|
836
911
|
#resyncSelectionEffect;
|
|
837
912
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: QueryListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
838
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: QueryListComponent, isStandalone: true, selector: "yuv-query-list", inputs: { query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, idProperty: { classPropertyName: "idProperty", publicName: "idProperty", isSignal: true, isRequired: false, transformFunction: null }, transformer: { classPropertyName: "transformer", publicName: "transformer", isSignal: true, isRequired: false, transformFunction: null }, preventChangeUntil: { classPropertyName: "preventChangeUntil", publicName: "preventChangeUntil", isSignal: true, isRequired: false, transformFunction: null }, autoSelect: { classPropertyName: "autoSelect", publicName: "autoSelect", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, enableDragSelect: { classPropertyName: "enableDragSelect", publicName: "enableDragSelect", isSignal: true, isRequired: false, transformFunction: null }, multiselect: { classPropertyName: "multiselect", publicName: "multiselect", isSignal: true, isRequired: false, transformFunction: null }, selfHandleSelection: { classPropertyName: "selfHandleSelection", publicName: "selfHandleSelection", isSignal: true, isRequired: false, transformFunction: null }, includePermissions: { classPropertyName: "includePermissions", publicName: "includePermissions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", dragSelectChange: "dragSelectChange", itemDoubleClick: "itemDoubleClick", queryResult: "queryResult" }, host: { properties: { "class.pagination": "!!pagination()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: ["yuvQueryListItem"], descendants: true, isSignal: true }, { propertyName: "emptyTemplate", first: true, predicate: ["yuvQueryListEmpty"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-list\n #list\n [multiselect]=\"multiselect()\"\n [autoSelect]=\"autoSelect()\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [selfHandleClick]=\"true\"\n [selfHandleSelection]=\"selfHandleSelection()\"\n [externalSelectionVisuals]=\"idSelection()\"\n [yuvDragSelect]=\"{ disabled: !enableDragSelect() || !multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n (itemSelect)=\"onInnerItemSelect($event)\"\n>\n @for (resultItem of resultItems(); track trackItem(resultItem, $index)) {\n <div\n yuvListItem\n yuvDragSelectItem\n [selected]=\"isRowSelected(resultItem)\"\n [class.drop-in]=\"$index < dropInSize()\"\n (click.single)=\"onItemClick($index, $event)\"\n (click.double)=\"onItemDoubleClick($index, $event)\"\n >\n <ng-container *ngTemplateOutlet=\"itemTemplate() || null; context: { $implicit: resultItem, index: $index }\" />\n </div>\n } @empty {\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || null\" />\n }\n</yuv-list>\n@if (pagination(); as pag) {\n <mat-paginator\n class=\"paginator\"\n [length]=\"pag.total\"\n [pageSize]=\"effectivePageSize()\"\n (page)=\"changePage($event)\"\n hidePageSize\n />\n}\n", styles: [":host{--paging-background: var(--ymt-surface);--drop-in-item-outline: 2px dashed rgb(from var(--ymt-primary) r g b / .9);--drop-in-item-outline-offset: -3px;display:flex;flex-direction:column;max-height:100%}:host [yuvListItem].drop-in{outline:var(--drop-in-item-outline);outline-offset:var(--drop-in-item-outline-offset);overflow:hidden}:host yuv-list{flex:1;overflow-y:auto}:host mat-paginator{flex:0 0 auto;font:inherit;border-block-start:1px solid var(--ymt-outline-variant);background-color:var(--paging-background)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i2.ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "externalSelectionVisuals", "selfHandleClick", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i2.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "directive", type: ClickDoubleDirective, selector: "[click.single],[click.double]", inputs: ["debounceTime"], outputs: ["click.double", "click.single"] }, { kind: "directive", type: DragSelectDirective, selector: "[yuvDragSelect]", inputs: ["yuvDragSelect"], outputs: ["dragSelectChange", "dragSelect"] }, { kind: "directive", type: DragSelectItemDirective, selector: "[yuvDragSelectItem]" }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
913
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: QueryListComponent, isStandalone: true, selector: "yuv-query-list", inputs: { query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, idProperty: { classPropertyName: "idProperty", publicName: "idProperty", isSignal: true, isRequired: false, transformFunction: null }, transformer: { classPropertyName: "transformer", publicName: "transformer", isSignal: true, isRequired: false, transformFunction: null }, preventChangeUntil: { classPropertyName: "preventChangeUntil", publicName: "preventChangeUntil", isSignal: true, isRequired: false, transformFunction: null }, autoSelect: { classPropertyName: "autoSelect", publicName: "autoSelect", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, enableDragSelect: { classPropertyName: "enableDragSelect", publicName: "enableDragSelect", isSignal: true, isRequired: false, transformFunction: null }, multiselect: { classPropertyName: "multiselect", publicName: "multiselect", isSignal: true, isRequired: false, transformFunction: null }, selfHandleSelection: { classPropertyName: "selfHandleSelection", publicName: "selfHandleSelection", isSignal: true, isRequired: false, transformFunction: null }, includePermissions: { classPropertyName: "includePermissions", publicName: "includePermissions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", dragSelectChange: "dragSelectChange", itemDoubleClick: "itemDoubleClick", queryResult: "queryResult" }, host: { properties: { "class.pagination": "!!pagination()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: ["yuvQueryListItem"], descendants: true, isSignal: true }, { propertyName: "emptyTemplate", first: true, predicate: ["yuvQueryListEmpty"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-list\n #list\n [multiselect]=\"multiselect()\"\n [autoSelect]=\"autoSelect()\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [selfHandleClick]=\"true\"\n [selfHandleSelection]=\"selfHandleSelection()\"\n [externalSelectionVisuals]=\"idSelection()\"\n [yuvDragSelect]=\"{ disabled: !enableDragSelect() || !multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n (itemSelect)=\"onInnerItemSelect($event)\"\n>\n @for (resultItem of resultItems(); track trackItem(resultItem, $index)) {\n <div\n yuvListItem\n yuvDragSelectItem\n [selected]=\"isRowSelected(resultItem)\"\n [class.drop-in]=\"$index < dropInSize()\"\n (click.single)=\"onItemClick($index, $event)\"\n (click.double)=\"onItemDoubleClick($index, $event)\"\n >\n <ng-container *ngTemplateOutlet=\"itemTemplate() || null; context: { $implicit: resultItem, index: $index }\" />\n </div>\n } @empty {\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || null\" />\n }\n</yuv-list>\n@if (pagination(); as pag) {\n <mat-paginator\n class=\"paginator\"\n [length]=\"pag.total\"\n [pageIndex]=\"pag.page - 1\"\n [pageSize]=\"effectivePageSize()\"\n (page)=\"changePage($event)\"\n hidePageSize\n />\n}\n", styles: [":host{--paging-background: var(--ymt-surface);--drop-in-item-outline: 2px dashed rgb(from var(--ymt-primary) r g b / .9);--drop-in-item-outline-offset: -3px;display:flex;flex-direction:column;max-height:100%}:host [yuvListItem].drop-in{outline:var(--drop-in-item-outline);outline-offset:var(--drop-in-item-outline-offset);overflow:hidden}:host yuv-list{flex:1;overflow-y:auto}:host mat-paginator{flex:0 0 auto;font:inherit;border-block-start:1px solid var(--ymt-outline-variant);background-color:var(--paging-background)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i2.ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "externalSelectionVisuals", "selfHandleClick", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i2.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "directive", type: ClickDoubleDirective, selector: "[click.single],[click.double]", inputs: ["debounceTime"], outputs: ["click.double", "click.single"] }, { kind: "directive", type: DragSelectDirective, selector: "[yuvDragSelect]", inputs: ["yuvDragSelect"], outputs: ["dragSelectChange", "dragSelect"] }, { kind: "directive", type: DragSelectItemDirective, selector: "[yuvDragSelectItem]" }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
839
914
|
}
|
|
840
915
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: QueryListComponent, decorators: [{
|
|
841
916
|
type: Component,
|
|
@@ -846,8 +921,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
|
|
|
846
921
|
DragSelectDirective,
|
|
847
922
|
DragSelectItemDirective,
|
|
848
923
|
MatPaginatorModule
|
|
849
|
-
], host: { '[class.pagination]': '!!pagination()' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<yuv-list\n #list\n [multiselect]=\"multiselect()\"\n [autoSelect]=\"autoSelect()\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [selfHandleClick]=\"true\"\n [selfHandleSelection]=\"selfHandleSelection()\"\n [externalSelectionVisuals]=\"idSelection()\"\n [yuvDragSelect]=\"{ disabled: !enableDragSelect() || !multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n (itemSelect)=\"onInnerItemSelect($event)\"\n>\n @for (resultItem of resultItems(); track trackItem(resultItem, $index)) {\n <div\n yuvListItem\n yuvDragSelectItem\n [selected]=\"isRowSelected(resultItem)\"\n [class.drop-in]=\"$index < dropInSize()\"\n (click.single)=\"onItemClick($index, $event)\"\n (click.double)=\"onItemDoubleClick($index, $event)\"\n >\n <ng-container *ngTemplateOutlet=\"itemTemplate() || null; context: { $implicit: resultItem, index: $index }\" />\n </div>\n } @empty {\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || null\" />\n }\n</yuv-list>\n@if (pagination(); as pag) {\n <mat-paginator\n class=\"paginator\"\n [length]=\"pag.total\"\n [pageSize]=\"effectivePageSize()\"\n (page)=\"changePage($event)\"\n hidePageSize\n />\n}\n", styles: [":host{--paging-background: var(--ymt-surface);--drop-in-item-outline: 2px dashed rgb(from var(--ymt-primary) r g b / .9);--drop-in-item-outline-offset: -3px;display:flex;flex-direction:column;max-height:100%}:host [yuvListItem].drop-in{outline:var(--drop-in-item-outline);outline-offset:var(--drop-in-item-outline-offset);overflow:hidden}:host yuv-list{flex:1;overflow-y:auto}:host mat-paginator{flex:0 0 auto;font:inherit;border-block-start:1px solid var(--ymt-outline-variant);background-color:var(--paging-background)}\n"] }]
|
|
850
|
-
}], ctorParameters: () => [], propDecorators: { list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }], itemTemplate: [{ type: i0.ContentChild, args: ['yuvQueryListItem', { isSignal: true }] }], emptyTemplate: [{ type: i0.ContentChild, args: ['yuvQueryListEmpty', { isSignal: true }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], idProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "idProperty", required: false }] }], transformer: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformer", required: false }] }], preventChangeUntil: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventChangeUntil", required: false }] }], autoSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], itemSelect: [{ type: i0.Output, args: ["itemSelect"] }], dragSelectChange: [{ type: i0.Output, args: ["dragSelectChange"] }], itemDoubleClick: [{ type: i0.Output, args: ["itemDoubleClick"] }], queryResult: [{ type: i0.Output, args: ["queryResult"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], enableDragSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDragSelect", required: false }] }], multiselect: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiselect", required: false }] }], selfHandleSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selfHandleSelection", required: false }] }], includePermissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "includePermissions", required: false }] }] } });
|
|
924
|
+
], host: { '[class.pagination]': '!!pagination()' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<yuv-list\n #list\n [multiselect]=\"multiselect()\"\n [autoSelect]=\"autoSelect()\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [selfHandleClick]=\"true\"\n [selfHandleSelection]=\"selfHandleSelection()\"\n [externalSelectionVisuals]=\"idSelection()\"\n [yuvDragSelect]=\"{ disabled: !enableDragSelect() || !multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n (itemSelect)=\"onInnerItemSelect($event)\"\n>\n @for (resultItem of resultItems(); track trackItem(resultItem, $index)) {\n <div\n yuvListItem\n yuvDragSelectItem\n [selected]=\"isRowSelected(resultItem)\"\n [class.drop-in]=\"$index < dropInSize()\"\n (click.single)=\"onItemClick($index, $event)\"\n (click.double)=\"onItemDoubleClick($index, $event)\"\n >\n <ng-container *ngTemplateOutlet=\"itemTemplate() || null; context: { $implicit: resultItem, index: $index }\" />\n </div>\n } @empty {\n <ng-container *ngTemplateOutlet=\"emptyTemplate() || null\" />\n }\n</yuv-list>\n@if (pagination(); as pag) {\n <mat-paginator\n class=\"paginator\"\n [length]=\"pag.total\"\n [pageIndex]=\"pag.page - 1\"\n [pageSize]=\"effectivePageSize()\"\n (page)=\"changePage($event)\"\n hidePageSize\n />\n}\n", styles: [":host{--paging-background: var(--ymt-surface);--drop-in-item-outline: 2px dashed rgb(from var(--ymt-primary) r g b / .9);--drop-in-item-outline-offset: -3px;display:flex;flex-direction:column;max-height:100%}:host [yuvListItem].drop-in{outline:var(--drop-in-item-outline);outline-offset:var(--drop-in-item-outline-offset);overflow:hidden}:host yuv-list{flex:1;overflow-y:auto}:host mat-paginator{flex:0 0 auto;font:inherit;border-block-start:1px solid var(--ymt-outline-variant);background-color:var(--paging-background)}\n"] }]
|
|
925
|
+
}], ctorParameters: () => [], propDecorators: { list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }], itemTemplate: [{ type: i0.ContentChild, args: ['yuvQueryListItem', { isSignal: true }] }], emptyTemplate: [{ type: i0.ContentChild, args: ['yuvQueryListEmpty', { isSignal: true }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], idProperty: [{ type: i0.Input, args: [{ isSignal: true, alias: "idProperty", required: false }] }], transformer: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformer", required: false }] }], preventChangeUntil: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventChangeUntil", required: false }] }], autoSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], itemSelect: [{ type: i0.Output, args: ["itemSelect"] }], dragSelectChange: [{ type: i0.Output, args: ["dragSelectChange"] }], itemDoubleClick: [{ type: i0.Output, args: ["itemDoubleClick"] }], queryResult: [{ type: i0.Output, args: ["queryResult"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], enableDragSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDragSelect", required: false }] }], multiselect: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiselect", required: false }] }], selfHandleSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selfHandleSelection", required: false }] }], includePermissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "includePermissions", required: false }] }], paginator: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatPaginator), { isSignal: true }] }] } });
|
|
851
926
|
|
|
852
927
|
const cmp = [QueryListComponent];
|
|
853
928
|
class YuvQueryListModule {
|