ngx-edu-sharing-metaqs2 0.9.37 → 0.9.38
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/esm2022/lib/collection-count-history/collection-count-history.component.mjs +1 -1
- package/esm2022/lib/collection-count-history/monthpicker/monthpicker.component.mjs +4 -4
- package/esm2022/lib/components/quality-matrix/quality_matrix.mjs +154 -155
- package/esm2022/lib/counts-with-history/counts-with-history.component.mjs +101 -85
- package/esm2022/lib/meta-api.service.mjs +1 -1
- package/esm2022/lib/tree-license/tree-license.component.mjs +55 -29
- package/fesm2022/ngx-edu-sharing-metaqs2.mjs +573 -531
- package/fesm2022/ngx-edu-sharing-metaqs2.mjs.map +1 -1
- package/lib/collection-count-history/collection-count-history.component.d.ts +1 -1
- package/lib/collection-count-history/monthpicker/monthpicker.component.d.ts +0 -1
- package/lib/components/quality-matrix/quality_matrix.d.ts +31 -29
- package/lib/counts-with-history/counts-with-history.component.d.ts +38 -20
- package/lib/meta-api.service.d.ts +1 -1
- package/lib/tree-license/tree-license.component.d.ts +12 -7
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Pipe, Component, Input, Output, inject, Renderer2, Injector, ChangeDetectionStrategy, HostBinding, LOCALE_ID, ElementRef, ViewChild, Directive, signal, computed, ViewChildren, HostListener, EventEmitter, effect, enableProdMode, importProvidersFrom } from '@angular/core';
|
|
2
|
+
import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Pipe, Component, Input, Output, inject, Renderer2, Injector, ChangeDetectionStrategy, HostBinding, LOCALE_ID, ElementRef, ViewChild, Directive, DestroyRef, signal, computed, ViewChildren, HostListener, EventEmitter, effect, enableProdMode, importProvidersFrom } from '@angular/core';
|
|
3
3
|
import * as i3$1 from '@angular/material/card';
|
|
4
4
|
import { MatCard, MatCardHeader, MatCardTitle, MatCardContent, MatCardModule } from '@angular/material/card';
|
|
5
5
|
import { MatTreeModule } from '@angular/material/tree';
|
|
@@ -13,7 +13,7 @@ import * as i6 from '@angular/material/button';
|
|
|
13
13
|
import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
|
|
14
14
|
import * as i2$2 from '@angular/material/progress-spinner';
|
|
15
15
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
16
|
-
import * as
|
|
16
|
+
import * as i5$1 from '@angular/material/table';
|
|
17
17
|
import { MatTable, MatCell, MatColumnDef, MatHeaderCell, MatHeaderRow, MatRow, MatHeaderRowDef, MatRowDef, MatHeaderCellDef, MatCellDef, MatTableModule } from '@angular/material/table';
|
|
18
18
|
import { MatGridListModule } from '@angular/material/grid-list';
|
|
19
19
|
import * as i1$1 from '@angular/material/form-field';
|
|
@@ -21,14 +21,14 @@ import { MatFormFieldModule, MatFormField, MatLabel, MatSuffix } from '@angular/
|
|
|
21
21
|
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
22
22
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
23
23
|
import * as i1$2 from '@angular/forms';
|
|
24
|
-
import { FormControl, ReactiveFormsModule, FormsModule,
|
|
24
|
+
import { FormControl, ReactiveFormsModule, FormsModule, FormRecord, FormGroup } from '@angular/forms';
|
|
25
25
|
import * as i2 from '@angular/material/select';
|
|
26
26
|
import { MatSelectModule } from '@angular/material/select';
|
|
27
27
|
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
|
|
28
28
|
import * as i1 from '@angular/common/http';
|
|
29
29
|
import { HttpHeaders, HttpContext, HttpParams, provideHttpClient, withInterceptorsFromDi, HttpClient } from '@angular/common/http';
|
|
30
|
-
import { pipe, of, BehaviorSubject,
|
|
31
|
-
import { map, catchError, startWith, take,
|
|
30
|
+
import { pipe, of, BehaviorSubject, Subject, combineLatest, forkJoin } from 'rxjs';
|
|
31
|
+
import { map, catchError, startWith, take, tap, switchMap, finalize, filter, throttleTime, takeUntil, shareReplay, distinctUntilChanged, skipWhile } from 'rxjs/operators';
|
|
32
32
|
import * as i2$4 from '@angular/platform-browser';
|
|
33
33
|
import { BrowserModule, createApplication } from '@angular/platform-browser';
|
|
34
34
|
import { MatListModule } from '@angular/material/list';
|
|
@@ -40,7 +40,7 @@ import * as i3 from '@angular/material/core';
|
|
|
40
40
|
import { DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS, MatRipple } from '@angular/material/core';
|
|
41
41
|
import * as i2$3 from '@ngx-translate/core';
|
|
42
42
|
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
|
43
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
43
|
+
import { toSignal, takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
44
44
|
import { DateTime } from 'luxon';
|
|
45
45
|
import * as i1$3 from '@angular/cdk/overlay';
|
|
46
46
|
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
|
@@ -1547,6 +1547,239 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
1547
1547
|
type: Output
|
|
1548
1548
|
}] } });
|
|
1549
1549
|
|
|
1550
|
+
/**
|
|
1551
|
+
* This class is a thin wrapper around the API services.
|
|
1552
|
+
*/
|
|
1553
|
+
class MetaApiService {
|
|
1554
|
+
constructor(collectionsAPI, replicationsAPI, filterAPI, editorsAPI) {
|
|
1555
|
+
this.collectionsAPI = collectionsAPI;
|
|
1556
|
+
this.replicationsAPI = replicationsAPI;
|
|
1557
|
+
this.filterAPI = filterAPI;
|
|
1558
|
+
this.editorsAPI = editorsAPI;
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Get the filters for the quality matrix.
|
|
1562
|
+
* It pipes the observable to take only one value.
|
|
1563
|
+
*/
|
|
1564
|
+
getSearchFilters() {
|
|
1565
|
+
return this.filterAPI.getQualitxMatrixFilters().pipe(take(1));
|
|
1566
|
+
}
|
|
1567
|
+
getCategoryFilters() {
|
|
1568
|
+
return this.getSearchFilters().pipe(map((filters) => filters.filter((filter) => filter.field !== 'timerange')));
|
|
1569
|
+
}
|
|
1570
|
+
getCollectionsFilter() {
|
|
1571
|
+
return this.collectionsAPI.getTopLevelCollection();
|
|
1572
|
+
}
|
|
1573
|
+
/**
|
|
1574
|
+
* Get the timerange filter for the quality matrix.
|
|
1575
|
+
* Returns the first filter of the historical timerange filters.
|
|
1576
|
+
*/
|
|
1577
|
+
getTimerangeFilter() {
|
|
1578
|
+
return this.filterAPI.getHistoricalTimerange().pipe(take(1), map((filters) => filters[0]));
|
|
1579
|
+
}
|
|
1580
|
+
getMaterialCountMatrixPerCollection(nodeRef, oerOnly) {
|
|
1581
|
+
return this.collectionsAPI.getMaterialCountMatrixPerCollection(nodeRef, oerOnly);
|
|
1582
|
+
}
|
|
1583
|
+
getCollectionCompleteness(colId) {
|
|
1584
|
+
return this.collectionsAPI.getCompleteness(colId);
|
|
1585
|
+
}
|
|
1586
|
+
getQualityMatrixWithFiltersV2(body) {
|
|
1587
|
+
return this.replicationsAPI.getQualityMatrixV2(body);
|
|
1588
|
+
}
|
|
1589
|
+
getEditorialMaterialCounts(body) {
|
|
1590
|
+
return this.editorsAPI.getMaterialCount(body);
|
|
1591
|
+
}
|
|
1592
|
+
getMaterialTypeCountsByReplicationSource(body) {
|
|
1593
|
+
return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndType(body);
|
|
1594
|
+
}
|
|
1595
|
+
getLicenseCountsByReplicationSource(body) {
|
|
1596
|
+
return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndLicense(body);
|
|
1597
|
+
}
|
|
1598
|
+
getLicenseCountsByLicenseGroup(colId, filters) {
|
|
1599
|
+
return this.collectionsAPI.getMaterialCountMatrixByLicenseGroup1(colId, filters);
|
|
1600
|
+
}
|
|
1601
|
+
getMaterialCountMatrixByLicenseGroup(body) {
|
|
1602
|
+
return this.editorsAPI.getMaterialCountMatrixByLicenseGroup(body);
|
|
1603
|
+
}
|
|
1604
|
+
getCompletenessForDisciplinaryPortals(body) {
|
|
1605
|
+
return this.editorsAPI.getCompletenessForDisciplinaryPortals(body);
|
|
1606
|
+
}
|
|
1607
|
+
getCompletenessForReplicationSources(body) {
|
|
1608
|
+
return this.replicationsAPI.getCompletenessForReplicationSources(body);
|
|
1609
|
+
}
|
|
1610
|
+
getMaterialTypesMapping() {
|
|
1611
|
+
return this.filterAPI.getMaterialTypesMapping();
|
|
1612
|
+
}
|
|
1613
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, deps: [{ token: CollectionAPIService }, { token: ReplicationSourceAPIService }, { token: FilterAPIService }, { token: EditorsAPIService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1614
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, providedIn: 'root' }); }
|
|
1615
|
+
}
|
|
1616
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, decorators: [{
|
|
1617
|
+
type: Injectable,
|
|
1618
|
+
args: [{
|
|
1619
|
+
providedIn: 'root',
|
|
1620
|
+
}]
|
|
1621
|
+
}], ctorParameters: () => [{ type: CollectionAPIService }, { type: ReplicationSourceAPIService }, { type: FilterAPIService }, { type: EditorsAPIService }] });
|
|
1622
|
+
|
|
1623
|
+
/**
|
|
1624
|
+
* This service provides methods to create links to the editorial desk with specific filters.
|
|
1625
|
+
*/
|
|
1626
|
+
/* This map makes it easier for me to keep track which issues are mapped to which filters */
|
|
1627
|
+
const FilterNames2Issues = {
|
|
1628
|
+
//Lizenzen
|
|
1629
|
+
'virtual:editorial_license': ['oer', 'other_cc', 'copyright', 'without_license'],
|
|
1630
|
+
//Materialtypen werden im Constructor gesetzt
|
|
1631
|
+
'virtual:oeh_lrt': [],
|
|
1632
|
+
'virtual:editorial_exclusion': [
|
|
1633
|
+
'outdated',
|
|
1634
|
+
'without_preview',
|
|
1635
|
+
'without_title',
|
|
1636
|
+
'without_description',
|
|
1637
|
+
'without_url',
|
|
1638
|
+
'without_type',
|
|
1639
|
+
'without_taxonomy_id',
|
|
1640
|
+
'without_education_level',
|
|
1641
|
+
'without_target_group',
|
|
1642
|
+
'without_license',
|
|
1643
|
+
'without_publisher',
|
|
1644
|
+
],
|
|
1645
|
+
};
|
|
1646
|
+
// Here we map back the issues to the filter names in the editorial desk, so we can look up the filter name for a given issue
|
|
1647
|
+
const Issues2FilterNames = Object.entries(FilterNames2Issues).reduce((map, [key, value]) => {
|
|
1648
|
+
value.forEach((issue) => map.set(issue, key));
|
|
1649
|
+
return map;
|
|
1650
|
+
}, new Map());
|
|
1651
|
+
// maps our values to the values of the filter in the editorial desk
|
|
1652
|
+
const MapValuesForFilter = {
|
|
1653
|
+
'virtual:editorial_exclusion': {
|
|
1654
|
+
outdated: null,
|
|
1655
|
+
without_preview: null,
|
|
1656
|
+
without_title: ['missing_title'],
|
|
1657
|
+
without_description: ['missing_description'],
|
|
1658
|
+
without_url: ['links'],
|
|
1659
|
+
without_type: ['missing_oeh_lrt'],
|
|
1660
|
+
without_taxonomy_id: ['without_taxonomy_id'],
|
|
1661
|
+
without_education_level: ['missing_educationalcontext'],
|
|
1662
|
+
without_target_group: ['missing_educationalintendedenduserrole'],
|
|
1663
|
+
without_license: ['missing_license'],
|
|
1664
|
+
without_publisher: ['missing_replicationsource'],
|
|
1665
|
+
},
|
|
1666
|
+
'virtual:editorial_license': {
|
|
1667
|
+
oer: ['oer'],
|
|
1668
|
+
copyright: ['none_oer'],
|
|
1669
|
+
without_license: ['none'],
|
|
1670
|
+
},
|
|
1671
|
+
'virtual:oeh_lrt': {},
|
|
1672
|
+
};
|
|
1673
|
+
/*
|
|
1674
|
+
This is a map from properties of a document to filter names
|
|
1675
|
+
*/
|
|
1676
|
+
const PROPERTIES2FILTERS = new Map([
|
|
1677
|
+
['metadata.educationalContexts', 'ccm:educationalcontext'],
|
|
1678
|
+
['metadata.disciplines', 'virtual:taxonid'],
|
|
1679
|
+
//["responsibility", "virtual:collection_id_primary"] // das zeigt auf "sammlungszugehörigkeit" und ist falsch
|
|
1680
|
+
]);
|
|
1681
|
+
class EditorialLinkService {
|
|
1682
|
+
constructor() {
|
|
1683
|
+
this.env = inject(ConfigHelperService);
|
|
1684
|
+
this.api = inject(MetaApiService);
|
|
1685
|
+
this.typesLoaded$ = new BehaviorSubject(false);
|
|
1686
|
+
this.api
|
|
1687
|
+
.getMaterialTypesMapping()
|
|
1688
|
+
.pipe(take(1))
|
|
1689
|
+
.subscribe((types) => {
|
|
1690
|
+
for (const [key, value] of Object.entries(types)) {
|
|
1691
|
+
Issues2FilterNames.set(key, 'virtual:oeh_lrt');
|
|
1692
|
+
MapValuesForFilter['virtual:oeh_lrt'][key] = value;
|
|
1693
|
+
}
|
|
1694
|
+
this.typesLoaded$.next(true);
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
openByReplicationsourceAndIssueTypeWithFilters(source, issue, selectedFilters) {
|
|
1698
|
+
const filters = {};
|
|
1699
|
+
filters['virtual:audit_filter'] = ['all'];
|
|
1700
|
+
filters['ccm:oeh_publisher_combined'] = [source];
|
|
1701
|
+
filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issue];
|
|
1702
|
+
for (const [field, values] of Object.entries(selectedFilters)) {
|
|
1703
|
+
if (values && values.length) {
|
|
1704
|
+
const editorialFiltername = PROPERTIES2FILTERS.get(field);
|
|
1705
|
+
filters[editorialFiltername] = values;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
1709
|
+
const params = new URLSearchParams();
|
|
1710
|
+
params.set('mode', 'audit');
|
|
1711
|
+
params.set('filters', JSON.stringify(filters));
|
|
1712
|
+
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
1713
|
+
}
|
|
1714
|
+
openByCollectionAndIssueType(collectionId, issueType, pageTitle) {
|
|
1715
|
+
const filters = {};
|
|
1716
|
+
filters['virtual:audit_filter'] = ['all'];
|
|
1717
|
+
filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issueType];
|
|
1718
|
+
filters['virtual:collection_id_primary'] = [collectionId];
|
|
1719
|
+
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
1720
|
+
const params = new URLSearchParams();
|
|
1721
|
+
params.set('title', pageTitle);
|
|
1722
|
+
params.set('mode', 'audit');
|
|
1723
|
+
params.set('filters', JSON.stringify(filters));
|
|
1724
|
+
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
1725
|
+
}
|
|
1726
|
+
openByCollectionId(collectionId) {
|
|
1727
|
+
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
1728
|
+
const params = new URLSearchParams();
|
|
1729
|
+
params.set('ids', collectionId);
|
|
1730
|
+
params.set('mode', 'render');
|
|
1731
|
+
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* This method creates a link to the editorial desk with specific filters.
|
|
1735
|
+
* It returns the URL to the editorial desk with the filters applied or null if the issueId is not mapped to a filter.
|
|
1736
|
+
* With this we can render a link with an href attribute to the editorial desk in the frontend.
|
|
1737
|
+
* @see the counts-with-history.component.scss how we style links only if their hrefs are not null
|
|
1738
|
+
*
|
|
1739
|
+
* @param sourceType The type of the source, e.g. "replicationSource" or "collection"
|
|
1740
|
+
* @param sourceId The id of the source. This is the first column in the table.
|
|
1741
|
+
* @param issueId The id of the issue. These are the other columns in the table.
|
|
1742
|
+
*/
|
|
1743
|
+
createLinkForCountsWithHistory(sourceType, sourceId, issueId) {
|
|
1744
|
+
const filters = {};
|
|
1745
|
+
filters['virtual:audit_filter'] = ['all'];
|
|
1746
|
+
// determine the "main" filter
|
|
1747
|
+
if (sourceType === 'replicationSource') {
|
|
1748
|
+
filters['ccm:oeh_publisher_combined'] = [sourceId];
|
|
1749
|
+
}
|
|
1750
|
+
else if (sourceType === 'collection') {
|
|
1751
|
+
filters['virtual:collection_id_primary'] = [sourceId];
|
|
1752
|
+
}
|
|
1753
|
+
if (!Issues2FilterNames.has(issueId)) {
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
const filterName = Issues2FilterNames.get(issueId);
|
|
1757
|
+
if (!filterName) {
|
|
1758
|
+
// console.debug("No filter name found for issue id: " + issueId);
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
const filterValue = MapValuesForFilter[filterName][issueId];
|
|
1762
|
+
if (!filterValue) {
|
|
1763
|
+
// console.debug("No filter value found for issue id: " + issueId);
|
|
1764
|
+
return null;
|
|
1765
|
+
}
|
|
1766
|
+
filters[filterName] = filterValue;
|
|
1767
|
+
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
1768
|
+
const params = new URLSearchParams();
|
|
1769
|
+
params.set('mode', 'audit');
|
|
1770
|
+
params.set('filters', JSON.stringify(filters));
|
|
1771
|
+
return `${theUrl}?${params}`;
|
|
1772
|
+
}
|
|
1773
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1774
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, providedIn: 'root' }); }
|
|
1775
|
+
}
|
|
1776
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, decorators: [{
|
|
1777
|
+
type: Injectable,
|
|
1778
|
+
args: [{
|
|
1779
|
+
providedIn: 'root',
|
|
1780
|
+
}]
|
|
1781
|
+
}], ctorParameters: () => [] });
|
|
1782
|
+
|
|
1550
1783
|
const TOOLTIP_DATA = new InjectionToken('TOOLTIP_DATA');
|
|
1551
1784
|
const TOOLTIP_REF = new InjectionToken('TOOLTIP_REF');
|
|
1552
1785
|
const noop = Object.freeze(() => { });
|
|
@@ -2043,297 +2276,65 @@ class ProgressSpinnerComponent {
|
|
|
2043
2276
|
see https://stackoverflow.com/questions/63579801/how-do-i-create-a-custom-overlay-container-for-angular-material
|
|
2044
2277
|
how to create a overlay container.
|
|
2045
2278
|
With such a directive we can have a spinner that greys-out only e.g. the table like seen here:
|
|
2046
|
-
https://reppners.github.io/ngx-cdk-dynamic-overlay-container/
|
|
2047
|
-
*/
|
|
2048
|
-
this.progressSpinnerOverlayConfig['positionStrategy'] = this.overlayService.positionFlexibleConnected(this.el);
|
|
2049
|
-
}
|
|
2050
|
-
// Create Overlay for progress spinner
|
|
2051
|
-
this.overlayRef = this.overlayService.createOverlay(this.progressSpinnerOverlayConfig);
|
|
2052
|
-
}
|
|
2053
|
-
ngOnChanges(changes) {
|
|
2054
|
-
changes.displayProgressSpinner.currentValue
|
|
2055
|
-
? this.overlayService.attachTemplatePortal(this.overlayRef, this.progressSpinnerRef, this.vcRef)
|
|
2056
|
-
: this.overlayRef.detach();
|
|
2057
|
-
}
|
|
2058
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressSpinnerComponent, deps: [{ token: i0.ViewContainerRef }, { token: OverlayService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2059
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProgressSpinnerComponent, isStandalone: true, selector: "metaqs2-progress-spinner", inputs: { color: "color", diameter: "diameter", strokeWidth: "strokeWidth", backdropEnabled: "backdropEnabled", positionGloballyCenter: "positionGloballyCenter", displayProgressSpinner: "displayProgressSpinner" }, viewQueries: [{ propertyName: "progressSpinnerRef", first: true, predicate: ["progressSpinnerRef"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #progressSpinnerRef>\n <mat-spinner [color]=\"color\" [diameter]=\"diameter\" [strokeWidth]=\"strokeWidth\">\n\t</mat-spinner>\n</ng-template>", styles: [""], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
2060
|
-
}
|
|
2061
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressSpinnerComponent, decorators: [{
|
|
2062
|
-
type: Component,
|
|
2063
|
-
args: [{ selector: 'metaqs2-progress-spinner', standalone: true, imports: [MatProgressSpinnerModule], template: "<ng-template #progressSpinnerRef>\n <mat-spinner [color]=\"color\" [diameter]=\"diameter\" [strokeWidth]=\"strokeWidth\">\n\t</mat-spinner>\n</ng-template>" }]
|
|
2064
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: OverlayService }, { type: i0.ElementRef }], propDecorators: { color: [{
|
|
2065
|
-
type: Input
|
|
2066
|
-
}], diameter: [{
|
|
2067
|
-
type: Input
|
|
2068
|
-
}], strokeWidth: [{
|
|
2069
|
-
type: Input
|
|
2070
|
-
}], backdropEnabled: [{
|
|
2071
|
-
type: Input
|
|
2072
|
-
}], positionGloballyCenter: [{
|
|
2073
|
-
type: Input
|
|
2074
|
-
}], displayProgressSpinner: [{
|
|
2075
|
-
type: Input
|
|
2076
|
-
}], progressSpinnerRef: [{
|
|
2077
|
-
type: ViewChild,
|
|
2078
|
-
args: ['progressSpinnerRef', { static: true }]
|
|
2079
|
-
}] } });
|
|
2080
|
-
|
|
2081
|
-
class ScrollMarkerDirective {
|
|
2082
|
-
constructor() {
|
|
2083
|
-
this.element = inject(ElementRef);
|
|
2084
|
-
}
|
|
2085
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2086
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ScrollMarkerDirective, isStandalone: true, selector: "[metaqs2ScrollMarker]", ngImport: i0 }); }
|
|
2087
|
-
}
|
|
2088
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, decorators: [{
|
|
2089
|
-
type: Directive,
|
|
2090
|
-
args: [{
|
|
2091
|
-
selector: '[metaqs2ScrollMarker]',
|
|
2092
|
-
standalone: true,
|
|
2093
|
-
}]
|
|
2094
|
-
}] });
|
|
2095
|
-
|
|
2096
|
-
/**
|
|
2097
|
-
* This class is a thin wrapper around the API services.
|
|
2098
|
-
*/
|
|
2099
|
-
class MetaApiService {
|
|
2100
|
-
constructor(collectionsAPI, replicationsAPI, filterAPI, editorsAPI) {
|
|
2101
|
-
this.collectionsAPI = collectionsAPI;
|
|
2102
|
-
this.replicationsAPI = replicationsAPI;
|
|
2103
|
-
this.filterAPI = filterAPI;
|
|
2104
|
-
this.editorsAPI = editorsAPI;
|
|
2105
|
-
}
|
|
2106
|
-
/**
|
|
2107
|
-
* Get the filters for the quality matrix.
|
|
2108
|
-
* It pipes the observable to take only one value.
|
|
2109
|
-
*/
|
|
2110
|
-
getSearchFilters() {
|
|
2111
|
-
return this.filterAPI.getQualitxMatrixFilters().pipe(take(1));
|
|
2112
|
-
}
|
|
2113
|
-
getCategoryFilters() {
|
|
2114
|
-
return this.getSearchFilters().pipe(map((filters) => filters.filter((filter) => filter.field !== 'timerange')));
|
|
2115
|
-
}
|
|
2116
|
-
getCollectionsFilter() {
|
|
2117
|
-
return this.collectionsAPI.getTopLevelCollection();
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* Get the timerange filter for the quality matrix.
|
|
2121
|
-
* Returns the first filter of the historical timerange filters.
|
|
2122
|
-
*/
|
|
2123
|
-
getTimerangeFilter() {
|
|
2124
|
-
return this.filterAPI.getHistoricalTimerange().pipe(take(1), map((filters) => filters[0]));
|
|
2125
|
-
}
|
|
2126
|
-
getMaterialCountMatrixPerCollection(nodeRef, oerOnly) {
|
|
2127
|
-
return this.collectionsAPI.getMaterialCountMatrixPerCollection(nodeRef, oerOnly);
|
|
2128
|
-
}
|
|
2129
|
-
getCollectionCompleteness(colId) {
|
|
2130
|
-
return this.collectionsAPI.getCompleteness(colId);
|
|
2131
|
-
}
|
|
2132
|
-
getQualityMatrixWithFiltersV2(body) {
|
|
2133
|
-
return this.replicationsAPI.getQualityMatrixV2(body);
|
|
2134
|
-
}
|
|
2135
|
-
getEditorialMaterialCounts(body) {
|
|
2136
|
-
return this.editorsAPI.getMaterialCount(body);
|
|
2137
|
-
}
|
|
2138
|
-
getMaterialTypeCountsByReplicationSource(body) {
|
|
2139
|
-
return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndType(body);
|
|
2140
|
-
}
|
|
2141
|
-
getLicenseCountsByReplicationSource(body) {
|
|
2142
|
-
return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndLicense(body);
|
|
2143
|
-
}
|
|
2144
|
-
getLicenseCountsByLicenseGroup(colId, filters) {
|
|
2145
|
-
return this.collectionsAPI.getMaterialCountMatrixByLicenseGroup1(colId, filters);
|
|
2146
|
-
}
|
|
2147
|
-
getMaterialCountMatrixByLicenseGroup(body) {
|
|
2148
|
-
return this.editorsAPI.getMaterialCountMatrixByLicenseGroup(body);
|
|
2149
|
-
}
|
|
2150
|
-
getCompletenessForDisciplinaryPortals(body) {
|
|
2151
|
-
return this.editorsAPI.getCompletenessForDisciplinaryPortals(body);
|
|
2152
|
-
}
|
|
2153
|
-
getCompletenessForReplicationSources(body) {
|
|
2154
|
-
return this.replicationsAPI.getCompletenessForReplicationSources(body);
|
|
2155
|
-
}
|
|
2156
|
-
getMaterialTypesMapping() {
|
|
2157
|
-
return this.filterAPI.getMaterialTypesMapping();
|
|
2158
|
-
}
|
|
2159
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, deps: [{ token: CollectionAPIService }, { token: ReplicationSourceAPIService }, { token: FilterAPIService }, { token: EditorsAPIService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2160
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, providedIn: 'root' }); }
|
|
2161
|
-
}
|
|
2162
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, decorators: [{
|
|
2163
|
-
type: Injectable,
|
|
2164
|
-
args: [{
|
|
2165
|
-
providedIn: 'root',
|
|
2166
|
-
}]
|
|
2167
|
-
}], ctorParameters: () => [{ type: CollectionAPIService }, { type: ReplicationSourceAPIService }, { type: FilterAPIService }, { type: EditorsAPIService }] });
|
|
2168
|
-
|
|
2169
|
-
/**
|
|
2170
|
-
* This service provides methods to create links to the editorial desk with specific filters.
|
|
2171
|
-
*/
|
|
2172
|
-
/* This map makes it easier for me to keep track which issues are mapped to which filters */
|
|
2173
|
-
const FilterNames2Issues = {
|
|
2174
|
-
//Lizenzen
|
|
2175
|
-
'virtual:editorial_license': ['oer', 'other_cc', 'copyright', 'without_license'],
|
|
2176
|
-
//Materialtypen werden im Constructor gesetzt
|
|
2177
|
-
'virtual:oeh_lrt': [],
|
|
2178
|
-
'virtual:editorial_exclusion': [
|
|
2179
|
-
'outdated',
|
|
2180
|
-
'without_preview',
|
|
2181
|
-
'without_title',
|
|
2182
|
-
'without_description',
|
|
2183
|
-
'without_url',
|
|
2184
|
-
'without_type',
|
|
2185
|
-
'without_taxonomy_id',
|
|
2186
|
-
'without_education_level',
|
|
2187
|
-
'without_target_group',
|
|
2188
|
-
'without_license',
|
|
2189
|
-
'without_publisher',
|
|
2190
|
-
],
|
|
2191
|
-
};
|
|
2192
|
-
// Here we map back the issues to the filter names in the editorial desk, so we can look up the filter name for a given issue
|
|
2193
|
-
const Issues2FilterNames = Object.entries(FilterNames2Issues).reduce((map, [key, value]) => {
|
|
2194
|
-
value.forEach((issue) => map.set(issue, key));
|
|
2195
|
-
return map;
|
|
2196
|
-
}, new Map());
|
|
2197
|
-
// maps our values to the values of the filter in the editorial desk
|
|
2198
|
-
const MapValuesForFilter = {
|
|
2199
|
-
'virtual:editorial_exclusion': {
|
|
2200
|
-
outdated: null,
|
|
2201
|
-
without_preview: null,
|
|
2202
|
-
without_title: ['missing_title'],
|
|
2203
|
-
without_description: ['missing_description'],
|
|
2204
|
-
without_url: ['links'],
|
|
2205
|
-
without_type: ['missing_oeh_lrt'],
|
|
2206
|
-
without_taxonomy_id: ['without_taxonomy_id'],
|
|
2207
|
-
without_education_level: ['missing_educationalcontext'],
|
|
2208
|
-
without_target_group: ['missing_educationalintendedenduserrole'],
|
|
2209
|
-
without_license: ['missing_license'],
|
|
2210
|
-
without_publisher: ['missing_replicationsource'],
|
|
2211
|
-
},
|
|
2212
|
-
'virtual:editorial_license': {
|
|
2213
|
-
oer: ['oer'],
|
|
2214
|
-
copyright: ['none_oer'],
|
|
2215
|
-
without_license: ['none'],
|
|
2216
|
-
},
|
|
2217
|
-
'virtual:oeh_lrt': {},
|
|
2218
|
-
};
|
|
2219
|
-
/*
|
|
2220
|
-
This is a map from properties of a document to filter names
|
|
2221
|
-
*/
|
|
2222
|
-
const PROPERTIES2FILTERS = new Map([
|
|
2223
|
-
['metadata.educationalContexts', 'ccm:educationalcontext'],
|
|
2224
|
-
['metadata.disciplines', 'virtual:taxonid'],
|
|
2225
|
-
//["responsibility", "virtual:collection_id_primary"] // das zeigt auf "sammlungszugehörigkeit" und ist falsch
|
|
2226
|
-
]);
|
|
2227
|
-
class EditorialLinkService {
|
|
2228
|
-
constructor() {
|
|
2229
|
-
this.env = inject(ConfigHelperService);
|
|
2230
|
-
this.api = inject(MetaApiService);
|
|
2231
|
-
this.typesLoaded$ = new BehaviorSubject(false);
|
|
2232
|
-
this.api
|
|
2233
|
-
.getMaterialTypesMapping()
|
|
2234
|
-
.pipe(take(1))
|
|
2235
|
-
.subscribe((types) => {
|
|
2236
|
-
for (const [key, value] of Object.entries(types)) {
|
|
2237
|
-
Issues2FilterNames.set(key, 'virtual:oeh_lrt');
|
|
2238
|
-
MapValuesForFilter['virtual:oeh_lrt'][key] = value;
|
|
2239
|
-
}
|
|
2240
|
-
this.typesLoaded$.next(true);
|
|
2241
|
-
});
|
|
2242
|
-
}
|
|
2243
|
-
openByReplicationsourceAndIssueTypeWithFilters(source, issue, selectedFilters) {
|
|
2244
|
-
const filters = {};
|
|
2245
|
-
filters['virtual:audit_filter'] = ['all'];
|
|
2246
|
-
filters['ccm:oeh_publisher_combined'] = [source];
|
|
2247
|
-
filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issue];
|
|
2248
|
-
for (const [field, values] of Object.entries(selectedFilters)) {
|
|
2249
|
-
if (values && values.length) {
|
|
2250
|
-
const editorialFiltername = PROPERTIES2FILTERS.get(field);
|
|
2251
|
-
filters[editorialFiltername] = values;
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2254
|
-
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
2255
|
-
const params = new URLSearchParams();
|
|
2256
|
-
params.set('mode', 'audit');
|
|
2257
|
-
params.set('filters', JSON.stringify(filters));
|
|
2258
|
-
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
2259
|
-
}
|
|
2260
|
-
openByCollectionAndIssueType(collectionId, issueType, pageTitle) {
|
|
2261
|
-
const filters = {};
|
|
2262
|
-
filters['virtual:audit_filter'] = ['all'];
|
|
2263
|
-
filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issueType];
|
|
2264
|
-
filters['virtual:collection_id_primary'] = [collectionId];
|
|
2265
|
-
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
2266
|
-
const params = new URLSearchParams();
|
|
2267
|
-
params.set('title', pageTitle);
|
|
2268
|
-
params.set('mode', 'audit');
|
|
2269
|
-
params.set('filters', JSON.stringify(filters));
|
|
2270
|
-
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
2271
|
-
}
|
|
2272
|
-
openByCollectionId(collectionId) {
|
|
2273
|
-
const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
|
|
2274
|
-
const params = new URLSearchParams();
|
|
2275
|
-
params.set('ids', collectionId);
|
|
2276
|
-
params.set('mode', 'render');
|
|
2277
|
-
window.open(`${theUrl}?${params}`, 'editor_frontend');
|
|
2278
|
-
}
|
|
2279
|
-
/**
|
|
2280
|
-
* This method creates a link to the editorial desk with specific filters.
|
|
2281
|
-
* It returns the URL to the editorial desk with the filters applied or null if the issueId is not mapped to a filter.
|
|
2282
|
-
* With this we can render a link with an href attribute to the editorial desk in the frontend.
|
|
2283
|
-
* @see the counts-with-history.component.scss how we style links only if their hrefs are not null
|
|
2284
|
-
*
|
|
2285
|
-
* @param sourceType The type of the source, e.g. "replicationSource" or "collection"
|
|
2286
|
-
* @param sourceId The id of the source. This is the first column in the table.
|
|
2287
|
-
* @param issueId The id of the issue. These are the other columns in the table.
|
|
2288
|
-
*/
|
|
2289
|
-
createLinkForCountsWithHistory(sourceType, sourceId, issueId) {
|
|
2290
|
-
const filters = {};
|
|
2291
|
-
filters['virtual:audit_filter'] = ['all'];
|
|
2292
|
-
// determine the "main" filter
|
|
2293
|
-
if (sourceType === 'replicationSource') {
|
|
2294
|
-
filters['ccm:oeh_publisher_combined'] = [sourceId];
|
|
2295
|
-
}
|
|
2296
|
-
else if (sourceType === 'collection') {
|
|
2297
|
-
filters['virtual:collection_id_primary'] = [sourceId];
|
|
2298
|
-
}
|
|
2299
|
-
if (!Issues2FilterNames.has(issueId)) {
|
|
2300
|
-
return null;
|
|
2301
|
-
}
|
|
2302
|
-
const filterName = Issues2FilterNames.get(issueId);
|
|
2303
|
-
if (!filterName) {
|
|
2304
|
-
// console.debug("No filter name found for issue id: " + issueId);
|
|
2305
|
-
return null;
|
|
2306
|
-
}
|
|
2307
|
-
const filterValue = MapValuesForFilter[filterName][issueId];
|
|
2308
|
-
if (!filterValue) {
|
|
2309
|
-
// console.debug("No filter value found for issue id: " + issueId);
|
|
2310
|
-
return null;
|
|
2279
|
+
https://reppners.github.io/ngx-cdk-dynamic-overlay-container/
|
|
2280
|
+
*/
|
|
2281
|
+
this.progressSpinnerOverlayConfig['positionStrategy'] = this.overlayService.positionFlexibleConnected(this.el);
|
|
2311
2282
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
const params = new URLSearchParams();
|
|
2315
|
-
params.set('mode', 'audit');
|
|
2316
|
-
params.set('filters', JSON.stringify(filters));
|
|
2317
|
-
return `${theUrl}?${params}`;
|
|
2283
|
+
// Create Overlay for progress spinner
|
|
2284
|
+
this.overlayRef = this.overlayService.createOverlay(this.progressSpinnerOverlayConfig);
|
|
2318
2285
|
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2286
|
+
ngOnChanges(changes) {
|
|
2287
|
+
changes.displayProgressSpinner.currentValue
|
|
2288
|
+
? this.overlayService.attachTemplatePortal(this.overlayRef, this.progressSpinnerRef, this.vcRef)
|
|
2289
|
+
: this.overlayRef.detach();
|
|
2290
|
+
}
|
|
2291
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressSpinnerComponent, deps: [{ token: i0.ViewContainerRef }, { token: OverlayService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2292
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProgressSpinnerComponent, isStandalone: true, selector: "metaqs2-progress-spinner", inputs: { color: "color", diameter: "diameter", strokeWidth: "strokeWidth", backdropEnabled: "backdropEnabled", positionGloballyCenter: "positionGloballyCenter", displayProgressSpinner: "displayProgressSpinner" }, viewQueries: [{ propertyName: "progressSpinnerRef", first: true, predicate: ["progressSpinnerRef"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #progressSpinnerRef>\n <mat-spinner [color]=\"color\" [diameter]=\"diameter\" [strokeWidth]=\"strokeWidth\">\n\t</mat-spinner>\n</ng-template>", styles: [""], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
2321
2293
|
}
|
|
2322
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type:
|
|
2323
|
-
type:
|
|
2294
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressSpinnerComponent, decorators: [{
|
|
2295
|
+
type: Component,
|
|
2296
|
+
args: [{ selector: 'metaqs2-progress-spinner', standalone: true, imports: [MatProgressSpinnerModule], template: "<ng-template #progressSpinnerRef>\n <mat-spinner [color]=\"color\" [diameter]=\"diameter\" [strokeWidth]=\"strokeWidth\">\n\t</mat-spinner>\n</ng-template>" }]
|
|
2297
|
+
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: OverlayService }, { type: i0.ElementRef }], propDecorators: { color: [{
|
|
2298
|
+
type: Input
|
|
2299
|
+
}], diameter: [{
|
|
2300
|
+
type: Input
|
|
2301
|
+
}], strokeWidth: [{
|
|
2302
|
+
type: Input
|
|
2303
|
+
}], backdropEnabled: [{
|
|
2304
|
+
type: Input
|
|
2305
|
+
}], positionGloballyCenter: [{
|
|
2306
|
+
type: Input
|
|
2307
|
+
}], displayProgressSpinner: [{
|
|
2308
|
+
type: Input
|
|
2309
|
+
}], progressSpinnerRef: [{
|
|
2310
|
+
type: ViewChild,
|
|
2311
|
+
args: ['progressSpinnerRef', { static: true }]
|
|
2312
|
+
}] } });
|
|
2313
|
+
|
|
2314
|
+
class ScrollMarkerDirective {
|
|
2315
|
+
constructor() {
|
|
2316
|
+
this.element = inject(ElementRef);
|
|
2317
|
+
}
|
|
2318
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2319
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ScrollMarkerDirective, isStandalone: true, selector: "[metaqs2ScrollMarker]", ngImport: i0 }); }
|
|
2320
|
+
}
|
|
2321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, decorators: [{
|
|
2322
|
+
type: Directive,
|
|
2324
2323
|
args: [{
|
|
2325
|
-
|
|
2324
|
+
selector: '[metaqs2ScrollMarker]',
|
|
2325
|
+
standalone: true,
|
|
2326
2326
|
}]
|
|
2327
|
-
}]
|
|
2327
|
+
}] });
|
|
2328
2328
|
|
|
2329
2329
|
const openCloseTimeout = 150;
|
|
2330
2330
|
class QualityMatrixComponent {
|
|
2331
|
-
constructor(
|
|
2332
|
-
this.metaApi = metaApi;
|
|
2333
|
-
this.linkService = linkService;
|
|
2334
|
-
this.overlay = overlay;
|
|
2335
|
-
this.tooltipService = tooltipService;
|
|
2331
|
+
constructor() {
|
|
2336
2332
|
this.ref = inject(ElementRef);
|
|
2333
|
+
this.destroyRef = inject(DestroyRef);
|
|
2334
|
+
this.metaApi = inject(MetaApiService);
|
|
2335
|
+
this.linkService = inject(EditorialLinkService);
|
|
2336
|
+
this.overlay = inject(Overlay);
|
|
2337
|
+
this.tooltipService = inject(TooltipService);
|
|
2337
2338
|
this.scrollLeft = signal(0);
|
|
2338
2339
|
this.scrollWidth = signal(0);
|
|
2339
2340
|
this.isLeftScrollable = computed(() => this.scrollLeft() > 0);
|
|
@@ -2345,13 +2346,34 @@ class QualityMatrixComponent {
|
|
|
2345
2346
|
const viewportWidth = viewport.width;
|
|
2346
2347
|
return this.scrollWidth() > viewportWidth && this.scrollLeft() + viewportWidth < this.scrollWidth();
|
|
2347
2348
|
});
|
|
2348
|
-
this.filteredColumns =
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2349
|
+
this.filteredColumns = computed(() => {
|
|
2350
|
+
const allColumns = this.allColumns();
|
|
2351
|
+
const isOnlySourcesWithMaterialEnabled = this.isOnlySourcesWithMaterialEnabled();
|
|
2352
|
+
if (isOnlySourcesWithMaterialEnabled) {
|
|
2353
|
+
return allColumns.filter((c) => c.total > 0);
|
|
2354
|
+
}
|
|
2355
|
+
else {
|
|
2356
|
+
return allColumns;
|
|
2357
|
+
}
|
|
2358
|
+
});
|
|
2359
|
+
this.datatableColumns = computed(() => {
|
|
2360
|
+
return this.filteredColumns()
|
|
2361
|
+
.filter((c) => c.level !== 0)
|
|
2362
|
+
.map((c) => c.id);
|
|
2363
|
+
});
|
|
2364
|
+
this.isHistoricalDataEnabledFormField = new FormControl({ value: false, disabled: true });
|
|
2365
|
+
this.isHistoricalDataEnabled = toSignal(this.isHistoricalDataEnabledFormField.valueChanges);
|
|
2366
|
+
this.isOnlySourcesWithMaterialEnabledFormField = new FormControl({ value: true, disabled: true });
|
|
2367
|
+
this.isOnlySourcesWithMaterialEnabled = toSignal(this.isOnlySourcesWithMaterialEnabledFormField.valueChanges);
|
|
2368
|
+
this.categoryControls = new FormRecord({});
|
|
2369
|
+
this.loadingCount = signal(0);
|
|
2370
|
+
this.isLoading = computed(() => this.loadingCount() > 0);
|
|
2353
2371
|
this.categoryFilterValues = new Map();
|
|
2372
|
+
this.refresh$ = new Subject();
|
|
2354
2373
|
this.recentQualityMatrix$ = new BehaviorSubject({ columns: [], rows: [] });
|
|
2374
|
+
this.recentQualityMatrix = toSignal(this.recentQualityMatrix$, {
|
|
2375
|
+
initialValue: { columns: [], rows: [] },
|
|
2376
|
+
});
|
|
2355
2377
|
this.pastQualityMatrix$ = new BehaviorSubject({ columns: [], rows: [] });
|
|
2356
2378
|
this.range = new FormGroup({
|
|
2357
2379
|
start: new FormControl(),
|
|
@@ -2360,17 +2382,18 @@ class QualityMatrixComponent {
|
|
|
2360
2382
|
this.tooltips = new Map();
|
|
2361
2383
|
this.DateTime = DateTime;
|
|
2362
2384
|
this.pageTitle = 'Quality Matrix';
|
|
2363
|
-
|
|
2364
|
-
this.
|
|
2365
|
-
this.
|
|
2366
|
-
this.
|
|
2367
|
-
this.
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
this.
|
|
2385
|
+
this.allColumns = computed(() => this.recentQualityMatrix()?.columns.toSorted((a, b) => a.label.localeCompare(b.label)));
|
|
2386
|
+
this.sourceColumns = computed(() => this.datatableColumns().map((c) => c + '_source'));
|
|
2387
|
+
this.currentColumns = computed(() => this.datatableColumns().map((c) => c + '_current'));
|
|
2388
|
+
this.pastColumns = computed(() => this.datatableColumns().map((c) => c + '_past'));
|
|
2389
|
+
this.allDataColumns = computed(() => {
|
|
2390
|
+
const pastColumns = this.pastColumns();
|
|
2391
|
+
const currentColumns = this.currentColumns();
|
|
2392
|
+
if (this.isHistoricalDataEnabled()) {
|
|
2393
|
+
return currentColumns.flatMap((e, i) => [pastColumns[i], e]);
|
|
2394
|
+
}
|
|
2395
|
+
return currentColumns;
|
|
2371
2396
|
});
|
|
2372
|
-
this.onLoadedDataChanges();
|
|
2373
|
-
//this.loadDataWithCurrentlySelectedFilters();
|
|
2374
2397
|
}
|
|
2375
2398
|
ngAfterViewChecked() {
|
|
2376
2399
|
this.onScroll();
|
|
@@ -2378,54 +2401,57 @@ class QualityMatrixComponent {
|
|
|
2378
2401
|
filterIdent(_index, item) {
|
|
2379
2402
|
return item.key;
|
|
2380
2403
|
}
|
|
2381
|
-
|
|
2382
|
-
return this.
|
|
2404
|
+
loadData(categories, date) {
|
|
2405
|
+
return of(undefined).pipe(tap(() => this.loadingCount.update((it) => it + 1)), switchMap(() => this.metaApi
|
|
2406
|
+
.getQualityMatrixWithFiltersV2([
|
|
2407
|
+
...this.transformCategoryFilters(categories),
|
|
2408
|
+
{
|
|
2409
|
+
field: 'asOf',
|
|
2410
|
+
values: [
|
|
2411
|
+
{
|
|
2412
|
+
id: date.toISO({
|
|
2413
|
+
includeOffset: false,
|
|
2414
|
+
}),
|
|
2415
|
+
label: '',
|
|
2416
|
+
},
|
|
2417
|
+
],
|
|
2418
|
+
},
|
|
2419
|
+
])
|
|
2420
|
+
.pipe(take(1))), finalize(() => this.loadingCount.update((it) => it - 1)));
|
|
2421
|
+
}
|
|
2422
|
+
transformCategoryFilters(categories) {
|
|
2423
|
+
return Object.entries(categories)
|
|
2424
|
+
.filter((pair) => !!pair[1]?.length)
|
|
2425
|
+
.map(([field, values]) => ({
|
|
2426
|
+
field,
|
|
2427
|
+
values: values.map((value) => ({ id: value, label: '' })),
|
|
2428
|
+
}));
|
|
2383
2429
|
}
|
|
2384
|
-
|
|
2385
|
-
return
|
|
2430
|
+
loadPastData(categories, date) {
|
|
2431
|
+
return of(undefined).pipe(switchMap(() => this.loadData(categories, date)));
|
|
2386
2432
|
}
|
|
2387
|
-
|
|
2388
|
-
return
|
|
2433
|
+
loadCurrentData(categories, date) {
|
|
2434
|
+
return of(undefined).pipe(switchMap(() => this.loadData(categories, date)));
|
|
2389
2435
|
}
|
|
2390
|
-
|
|
2391
|
-
return this.
|
|
2436
|
+
openEditLink(source, issue) {
|
|
2437
|
+
return this.linkService.openByReplicationsourceAndIssueTypeWithFilters(source, issue, this.categoryControls.value);
|
|
2392
2438
|
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
}
|
|
2397
|
-
return this.currentColumns;
|
|
2439
|
+
// see https://github.com/angular/components/issues/8361#issuecomment-345804954
|
|
2440
|
+
columnIdent(_index, col) {
|
|
2441
|
+
return col.id;
|
|
2398
2442
|
}
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
// avoid filtering when not necessary
|
|
2402
|
-
this.filteredColumns = onlyWith ? allColumns.filter((c) => c.total > 0) : allColumns;
|
|
2403
|
-
this.datatableColumns = this.filteredColumns.map((c) => c.id);
|
|
2443
|
+
refresh() {
|
|
2444
|
+
this.refresh$.next();
|
|
2404
2445
|
}
|
|
2405
|
-
|
|
2406
|
-
this.
|
|
2407
|
-
this.loadDataWithCurrentlySelectedFilters();
|
|
2408
|
-
});
|
|
2409
|
-
this.metaApi.getTimerangeFilter().subscribe((rangeFilter) => {
|
|
2410
|
-
if (rangeFilter) {
|
|
2411
|
-
const startDate = DateTime.fromISO(rangeFilter.values.find((v) => v.id === 'rangeStart')?.label, {
|
|
2412
|
-
zone: 'utc',
|
|
2413
|
-
});
|
|
2414
|
-
const endDate = DateTime.fromISO(rangeFilter.values.find((v) => v.id === 'rangeEnd')?.label, { zone: 'utc' });
|
|
2415
|
-
//toggle the emitEvent to initially load the data or not
|
|
2416
|
-
this.range.setControl('start', new FormControl(startDate, { nonNullable: true }), {
|
|
2417
|
-
emitEvent: false,
|
|
2418
|
-
});
|
|
2419
|
-
this.range.setControl('end', new FormControl(endDate, { nonNullable: true }), { emitEvent: true });
|
|
2420
|
-
}
|
|
2421
|
-
});
|
|
2446
|
+
getPastColumn(columnId) {
|
|
2447
|
+
return this.pastQualityMatrix$.value?.columns.find((c) => c.id === columnId);
|
|
2422
2448
|
}
|
|
2423
|
-
|
|
2449
|
+
ngOnInit() {
|
|
2424
2450
|
this.metaApi
|
|
2425
2451
|
.getCategoryFilters()
|
|
2426
|
-
.pipe(take(1))
|
|
2427
|
-
.subscribe((filters) => {
|
|
2452
|
+
.pipe(take(1), tap((filters) => {
|
|
2428
2453
|
filters.forEach((filter) => {
|
|
2454
|
+
// do not emit the event when setting the control to prevent unnecessary valueChanges events
|
|
2429
2455
|
this.categoryControls.addControl(filter.field, new FormControl([], { nonNullable: true }), {
|
|
2430
2456
|
emitEvent: false,
|
|
2431
2457
|
});
|
|
@@ -2433,99 +2459,73 @@ class QualityMatrixComponent {
|
|
|
2433
2459
|
return a.label.localeCompare(b.label);
|
|
2434
2460
|
}));
|
|
2435
2461
|
});
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
onLoadedDataChanges() {
|
|
2442
|
-
this.recentQualityMatrix$
|
|
2443
|
-
.pipe(takeUntilDestroyed(), filter((qm) => qm !== null), tap(() => this.filterTableBySourcesWithMaterial(this.onlySourcesWithMaterial.value)))
|
|
2462
|
+
// emit the current value of the form group once to trigger the valueChanges observable
|
|
2463
|
+
this.categoryControls.setValue(this.categoryControls.value, {
|
|
2464
|
+
emitEvent: true,
|
|
2465
|
+
});
|
|
2466
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
2444
2467
|
.subscribe();
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
const
|
|
2449
|
-
|
|
2450
|
-
field: 'asOf',
|
|
2451
|
-
values: [{ id: this.range.controls.start.value.toISO({ includeOffset: false }), label: '' }],
|
|
2468
|
+
this.metaApi
|
|
2469
|
+
.getTimerangeFilter()
|
|
2470
|
+
.pipe(filter((rangeFilter) => !!rangeFilter), tap((rangeFilter) => {
|
|
2471
|
+
const startDate = DateTime.fromISO(rangeFilter.values.find((v) => v.id === 'rangeStart')?.label, {
|
|
2472
|
+
zone: 'utc',
|
|
2452
2473
|
});
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
})
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
const body = [];
|
|
2467
|
-
for (const [field, values] of Object.entries(this.categoryControls.value)) {
|
|
2468
|
-
let requestValues = [];
|
|
2469
|
-
if (values && values.length) {
|
|
2470
|
-
requestValues = values.map((value) => ({ id: value, label: '' }));
|
|
2471
|
-
body.push({ field, values: requestValues });
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
return body;
|
|
2475
|
-
}
|
|
2476
|
-
loadDataWithCurrentlySelectedFilters() {
|
|
2477
|
-
/*
|
|
2478
|
-
consider using an intermediate Subject with a switchMap pipe
|
|
2479
|
-
to prevent that older ( longer running ) requests overwrite newer ones
|
|
2480
|
-
see https://stackoverflow.com/questions/64427629/how-to-use-rxjs-to-cancel-previous-http-requests-in-an-angular-service/64490155#64490155
|
|
2481
|
-
*/
|
|
2482
|
-
this.isLoading.set(true);
|
|
2483
|
-
forkJoin({
|
|
2484
|
-
pastQm: this.loadDataForStart(),
|
|
2485
|
-
currentQm: this.loadDataForEnd(),
|
|
2486
|
-
})
|
|
2487
|
-
.pipe(finalize(() => {
|
|
2488
|
-
this.isLoading.set(false);
|
|
2489
|
-
}), tap(({ pastQm: _, currentQm }) => {
|
|
2490
|
-
this.datatableColumns = currentQm.columns.filter((c) => c.level !== 0).map((c) => c.id);
|
|
2491
|
-
}))
|
|
2492
|
-
.subscribe(({ pastQm, currentQm }) => {
|
|
2474
|
+
const endDate = DateTime.fromISO(rangeFilter.values.find((v) => v.id === 'rangeEnd')?.label, {
|
|
2475
|
+
zone: 'utc',
|
|
2476
|
+
});
|
|
2477
|
+
this.range.setControl('start', new FormControl(startDate, { nonNullable: true }), {
|
|
2478
|
+
emitEvent: false,
|
|
2479
|
+
});
|
|
2480
|
+
this.range.setControl('end', new FormControl(endDate, { nonNullable: true }), {
|
|
2481
|
+
emitEvent: true,
|
|
2482
|
+
});
|
|
2483
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
2484
|
+
.subscribe();
|
|
2485
|
+
combineLatest([this.categoryControls.valueChanges, this.range.valueChanges, this.refresh$])
|
|
2486
|
+
.pipe(filter((data) => !!data[0] && !!data[1].end?.isValid), throttleTime(500), map(([categories, range]) => [categories, range.end]), switchMap(([categories, end]) => this.loadCurrentData(categories, end)), tap((currentQm) => {
|
|
2493
2487
|
this.recentQualityMatrix$.next(currentQm);
|
|
2488
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
2489
|
+
.subscribe();
|
|
2490
|
+
let pastDataSubscription;
|
|
2491
|
+
const pastData$ = combineLatest([this.categoryControls.valueChanges, this.range.valueChanges, this.refresh$]).pipe(filter((data) => !!data[0] && !!data[1].start?.isValid), throttleTime(500), map(([categories, range]) => [categories, range.start]), switchMap(([categories, start]) => this.loadPastData(categories, start)), tap((pastQm) => {
|
|
2494
2492
|
this.pastQualityMatrix$.next(pastQm);
|
|
2493
|
+
}), takeUntilDestroyed(this.destroyRef));
|
|
2494
|
+
this.isHistoricalDataEnabledFormField.valueChanges
|
|
2495
|
+
.pipe(tap((isEnabled) => {
|
|
2496
|
+
if (isEnabled) {
|
|
2497
|
+
pastDataSubscription = pastData$.subscribe();
|
|
2498
|
+
this.categoryControls.setValue(this.categoryControls.value, {
|
|
2499
|
+
emitEvent: true,
|
|
2500
|
+
});
|
|
2501
|
+
this.range.setValue(this.range.value, {
|
|
2502
|
+
emitEvent: true,
|
|
2503
|
+
});
|
|
2504
|
+
this.refresh$.next();
|
|
2505
|
+
}
|
|
2506
|
+
else {
|
|
2507
|
+
pastDataSubscription?.unsubscribe();
|
|
2508
|
+
}
|
|
2509
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
2510
|
+
.subscribe();
|
|
2511
|
+
this.refresh$.next();
|
|
2512
|
+
this.isOnlySourcesWithMaterialEnabledFormField.setValue(this.isOnlySourcesWithMaterialEnabledFormField.value, {
|
|
2513
|
+
emitEvent: true,
|
|
2495
2514
|
});
|
|
2496
2515
|
}
|
|
2497
|
-
openEditLink(source, issue) {
|
|
2498
|
-
return this.linkService.openByReplicationsourceAndIssueTypeWithFilters(source, issue, this.categoryControls.value);
|
|
2499
|
-
}
|
|
2500
|
-
// see https://github.com/angular/components/issues/8361#issuecomment-345804954
|
|
2501
|
-
columnIdent(_index, col) {
|
|
2502
|
-
return col.id;
|
|
2503
|
-
}
|
|
2504
|
-
async refresh() {
|
|
2505
|
-
//or should we reset all Filter?
|
|
2506
|
-
this.loadDataWithCurrentlySelectedFilters();
|
|
2507
|
-
}
|
|
2508
|
-
getPastColumn(columnId) {
|
|
2509
|
-
return this.pastQualityMatrix$.value?.columns.find((c) => c.id === columnId);
|
|
2510
|
-
}
|
|
2511
2516
|
getTrend(row, column) {
|
|
2512
|
-
if (this.pastQualityMatrix$.value === null) {
|
|
2517
|
+
if (this.pastQualityMatrix$.value === null || this.pastQualityMatrix$.value.columns.length === 0) {
|
|
2513
2518
|
return {};
|
|
2514
2519
|
}
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
if (!past_row || !past_column) {
|
|
2519
|
-
return {};
|
|
2520
|
-
}
|
|
2521
|
-
const delta = Math.floor((100 * row.counts[column.id].sufficient) / column.total -
|
|
2522
|
-
(100 * past_row.counts[column.id].sufficient) / past_column.total);
|
|
2523
|
-
const trend = delta === 0 ? 'trending_flat' : delta < 0 ? 'trending_down' : 'trending_up';
|
|
2524
|
-
return { delta, trend };
|
|
2525
|
-
}
|
|
2526
|
-
else {
|
|
2520
|
+
const past_row = this.pastQualityMatrix$?.value.rows.find((pr) => pr.meta.id == row.meta.id);
|
|
2521
|
+
const past_column = this.pastQualityMatrix$.value.columns.find((c) => c.id == column.id);
|
|
2522
|
+
if (!past_row || !past_column) {
|
|
2527
2523
|
return {};
|
|
2528
2524
|
}
|
|
2525
|
+
const delta = Math.floor((100 * row.counts[column.id].sufficient) / column.total -
|
|
2526
|
+
(100 * past_row.counts[column.id].sufficient) / past_column.total);
|
|
2527
|
+
const trend = delta === 0 ? 'trending_flat' : delta < 0 ? 'trending_down' : 'trending_up';
|
|
2528
|
+
return { delta, trend };
|
|
2529
2529
|
}
|
|
2530
2530
|
getDonutSlices(row, column) {
|
|
2531
2531
|
const sufficientTotal = row.counts[column.id].sufficient;
|
|
@@ -2654,8 +2654,8 @@ class QualityMatrixComponent {
|
|
|
2654
2654
|
this.scrollLeft.set(scrollingElement.scrollLeft);
|
|
2655
2655
|
this.scrollWidth.set(scrollingElement.scrollWidth);
|
|
2656
2656
|
}
|
|
2657
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, deps: [
|
|
2658
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: QualityMatrixComponent, isStandalone: true, selector: "metaqs2-quality-matrix-v2", inputs: { pageTitle: "pageTitle" }, host: { listeners: { "window:scroll": "onScroll()", "window:resize": "onScroll()" } }, providers: [TooltipService], viewQueries: [{ propertyName: "issueTypeHeader", first: true, predicate: ["issueType"], descendants: true, read: ElementRef, static: true }, { propertyName: "scrollMarkers", predicate: ScrollMarkerDirective, descendants: true }], ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title\n >\n </mat-card-header>\n <mat-card-content class=\"toolbar\">\n <metaqs2-qm-filter *ngFor=\"let filter of categoryControls.controls | keyvalue; trackBy: filterIdent\"\n [options]=\"categoryFilterValues.get(filter.key)\"\n [inputFormControl]=\"filter.value\"\n [label] = \"'filter.' + filter.key | translate\" />\n <div class=\"actionbar\">\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"onlySourcesWithMaterial\" id=\"onlySourcesWithMaterial\">\n show only sources with material\n </mat-slide-toggle>\n <div style=\"flex: 1 1 auto\"></div>\n <metaqs2-datepicker *ngIf=\"showHistoricalData.value\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" />\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"showHistoricalData\" id=\"showHistoricalData\">\n show historical data\n </mat-slide-toggle>\n <button\n mat-icon-button\n color=\"primary\"\n [disabled]=\"isLoading\"\n (click)=\"refresh()\"\n matTooltip=\"Aktualisiere den IST-Stand\"\n matTooltipShowDelay=\"500\"\n >\n <mat-icon>refresh</mat-icon>\n </button>\n <div style=\"flex: 0 0 {{scroller.getBoundingClientRect().width}}px\"></div>\n <div class=\"scroll-controller\" #scroller> <!-- put the whole toolbar in a fixed container (MQS- -->\n <button mat-raised-button (click)=\"scrollToLeft()\" [disabled]=\"!isLeftScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_left</mat-icon>\n </button>\n <button mat-raised-button (click)=\"scrollToRight()\" [disabled]=\"!isRightScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentQualityMatrix$.value.rows\" class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"row-header\" sticky>\n <th rowspan=\"2\" mat-header-cell *matHeaderCellDef #issueType>Issue Type</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n matTooltip=\"{{row.meta.alt_label}}\"\n class=\"row-header mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{\"quality_matrix.\" + row.meta.label | translate }}\n </td>\n </ng-container>\n <!-- one column for the source -->\n <ng-container *ngFor=\"let col of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"col.id + '_source'\">\n <th [attr.colspan]=\"showHistoricalData.value?2:1\" metaqs2ScrollMarker mat-header-cell *matHeaderCellDef matTooltip=\"{{col.altLabel}}\">{{col.label}}</th>\n </ng-container>\n <!-- /source -->\n <!-- current Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"column.id + '_current'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"{{column.altLabel}}\">{{ range.controls.end.value?.toLocaleString(DateTime.DATE_SHORT) }} <br>({{column.total}})</th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\" #cell (mouseover)=\"showTooltip(row, column, cell)\" (mouseleave)=\"hideTooltip(cell)\">\n <a *ngIf=\"column.total > 0 else emptyDiv\" class=\"chart-container\" (click)=\"openEditLink( column.label, row.meta.label)\">\n <div>\n <metaqs2-donut-chart [data]=\"getDonutSlices(row, column)\" [borderSize]=\"25\"></metaqs2-donut-chart>\n </div>\n </a>\n <ng-template #emptyDiv>\n <div>-</div>\n </ng-template>\n </td>\n </ng-container>\n <!-- /current Data Columns -->\n <!-- past Data Columns -->\n <ng-container *ngIf=\"showHistoricalData.value\">\n <ng-container *ngFor=\"let column of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"column.id + '_past'\">\n <th class=\"historic-data-cell\" mat-header-cell\n *matHeaderCellDef>{{ range.controls.start.value?.toLocaleString(DateTime.DATE_SHORT) }}\n <br>{{ getPastColumn(column.id)?.total }}\n </th>\n <td class=\"historic-data-cell\" mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getTrend(row, column) as trend\">\n <span [ngClass]=\"trend.trend\">\n <mat-icon aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" />\n {{ trend.delta }}\n </span>\n </ng-container>\n\n </td>\n </ng-container>\n </ng-container>\n <!-- /past Data Columns -->\n\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['row-header'].concat( sourceColumns); sticky: true;\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"allDataColumns; sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['row-header'].concat(allDataColumns)\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}mat-card-actions>mat-slide-toggle{margin-left:20px}.row{flex-grow:1;display:flex;align-items:center}table{width:100%;overflow-y:auto}table .scroll{flex-grow:1;overflow-y:auto}table th{vertical-align:top;padding:.375rem}table th:not(:last-child){border-right:1px solid #e4e4e4}table tr:first-child>th:first-child{text-align:left}table td:first-child{text-align:left}.cell{flex:1}.mat-mdc-cell{padding-top:5px}.mat-mdc-cell,.mat-mdc-header-cell{padding-left:5px;text-align:center}.mat-mdc-cell a.chart-container,.mat-mdc-header-cell a.chart-container{display:flex;justify-content:center}.mat-mdc-cell .trending_up,.mat-mdc-header-cell .trending_up{color:#4abeff}.mat-mdc-cell .trending_down,.mat-mdc-header-cell .trending_down{color:#c20808}.recent-data-cell,.mat-column-row-header{border-right:1px solid #e4e4e4}.mat-header-cell-label{color:#000;padding-left:30px;padding-right:30px;justify-content:left;border-bottom:1px solid #e4e4e4;font-style:normal;font-weight:500;font-size:110%;background:#ddf0fb;text-align:left}.mat-header-cell-label>div{display:flex;font-weight:700;font-style:normal;justify-content:left}.mat-header-cell-small{padding-left:5px;padding-right:5px;justify-content:left;font-style:normal;font-weight:400;font-size:105%;background:#ddf0fb;border-top:1px solid #e4e4e4;border-bottom:1px solid #e4e4e4}.mat-mdc-cell a{cursor:pointer;display:flex;align-items:center;justify-content:left}.mat-mdc-cell a>mat-icon{padding-right:5px;font-size:22px;height:20px;opacity:.75}.mat-mdc-cell a>mat-icon:hover,.mat-mdc-cell a>mat-icon:focus{text-decoration:none}.mat-mdc-cell .number{display:flex;height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header-sum{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;border-right:5px solid #bdbdbd}.mat-mdc-card{width:100%;box-shadow:none}.mat-mdc-card ::ng-deep mat-card-header{align-items:center}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.mat-mdc-card .source-header{font-style:normal;font-weight:400;font-size:20px;height:30px;width:60%}.mat-mdc-card .source-header .robot-explanation{font-size:15px}.mat-mdc-card .scroll{flex-grow:1;overflow-y:auto}.mat-header-cell-scope{color:#545454}.mat-mdc-header-row{height:70px;max-height:70px;min-height:56px}:host{overflow:auto}:host ::ng-deep thead{border:10px solid #ff0000;position:relative;z-index:1}.mat-cell-level-1{padding-left:20px!important}.mat-cell-level-2{padding-left:40px!important}.mat-cell-level-3{padding-left:60px!important}.mat-cell-level-4{padding-left:80px!important}.mat-cell-level-5{padding-left:100px!important}.mat-cell-level-6{padding-left:120px!important}.mat-cell-level-7{padding-left:140px!important}.mat-cell-level-8{padding-left:160px!important}.actionbar{flex:1 1 auto;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}.scroll-controller{position:fixed;right:.5rem;z-index:100;display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:.5rem}.scroll-button{min-width:0;padding-left:.25rem;padding-right:.25rem;text-align:center;height:1.75rem}.toolbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:stretch;gap:.5rem}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: QualityMatrixFilterComponent, selector: "metaqs2-qm-filter", inputs: ["options", "inputFormControl", "label", "multiple"], outputs: ["changedFilters"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: DonutChartComponent, selector: "metaqs2-donut-chart", inputs: ["radius", "viewBox", "borderSize", "strokeWidth", "data"] }, { kind: "directive", type: ScrollMarkerDirective, selector: "[metaqs2ScrollMarker]" }] }); }
|
|
2657
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2658
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: QualityMatrixComponent, isStandalone: true, selector: "metaqs2-quality-matrix-v2", inputs: { pageTitle: "pageTitle" }, host: { listeners: { "window:scroll": "onScroll()", "window:resize": "onScroll()" } }, providers: [TooltipService], viewQueries: [{ propertyName: "issueTypeHeader", first: true, predicate: ["issueType"], descendants: true, read: ElementRef, static: true }, { propertyName: "scrollMarkers", predicate: ScrollMarkerDirective, descendants: true }], ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"toolbar\">\n <metaqs2-qm-filter *ngFor=\"let filter of categoryControls.controls | keyvalue; trackBy: filterIdent\"\n [options]=\"categoryFilterValues.get(filter.key)\"\n [inputFormControl]=\"filter.value\"\n [label] = \"'filter.' + filter.key | translate\" />\n <div class=\"actionbar\">\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"isOnlySourcesWithMaterialEnabledFormField\" id=\"onlySourcesWithMaterial\">\n show only sources with material\n </mat-slide-toggle>\n <div style=\"flex: 1 1 auto\"></div>\n <metaqs2-datepicker *ngIf=\"isHistoricalDataEnabled()\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" />\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"isHistoricalDataEnabledFormField\" id=\"showHistoricalData\">\n show historical data\n </mat-slide-toggle>\n <button\n mat-icon-button\n color=\"primary\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh()\"\n matTooltip=\"Aktualisiere den IST-Stand\"\n matTooltipShowDelay=\"500\"\n >\n <mat-icon>refresh</mat-icon>\n </button>\n <div style=\"flex: 0 0 {{scroller.getBoundingClientRect().width}}px\"></div>\n <div class=\"scroll-controller\" #scroller> <!-- put the whole toolbar in a fixed container (MQS- -->\n <button mat-raised-button (click)=\"scrollToLeft()\" [disabled]=\"!isLeftScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_left</mat-icon>\n </button>\n <button mat-raised-button (click)=\"scrollToRight()\" [disabled]=\"!isRightScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentQualityMatrix().rows\" class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"row-header\" sticky>\n <th rowspan=\"2\" mat-header-cell *matHeaderCellDef #issueType>Issue Type</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n matTooltip=\"{{row.meta.alt_label}}\"\n class=\"row-header mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{\"quality_matrix.\" + row.meta.label | translate }}\n </td>\n </ng-container>\n <!-- one column for the source -->\n <ng-container *ngFor=\"let col of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"col.id + '_source'\">\n <th [attr.colspan]=\"isHistoricalDataEnabled() ? 2 : 1\" metaqs2ScrollMarker mat-header-cell *matHeaderCellDef matTooltip=\"{{col.altLabel}}\">{{col.label}}</th>\n </ng-container>\n <!-- /source -->\n <!-- current Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"column.id + '_current'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"{{column.altLabel}}\">{{ range.controls.end.value?.toLocaleString(DateTime.DATE_SHORT) }} <br>({{column.total}})</th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\" #cell (mouseover)=\"showTooltip(row, column, cell)\" (mouseleave)=\"hideTooltip(cell)\">\n <a *ngIf=\"column.total > 0 else emptyDiv\" class=\"chart-container\" (click)=\"openEditLink( column.label, row.meta.label)\">\n <div>\n <metaqs2-donut-chart [data]=\"getDonutSlices(row, column)\" [borderSize]=\"25\"></metaqs2-donut-chart>\n </div>\n </a>\n <ng-template #emptyDiv>\n <div>-</div>\n </ng-template>\n </td>\n </ng-container>\n <!-- /current Data Columns -->\n <!-- past Data Columns -->\n <ng-container *ngIf=\"isHistoricalDataEnabled()\">\n <ng-container *ngFor=\"let column of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"column.id + '_past'\">\n <th class=\"historic-data-cell\" mat-header-cell\n *matHeaderCellDef>{{ range.controls.start.value?.toLocaleString(DateTime.DATE_SHORT) }}\n <br>{{ getPastColumn(column.id)?.total }}\n </th>\n <td class=\"historic-data-cell\" mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getTrend(row, column) as trend\">\n <span [ngClass]=\"trend.trend\">\n <mat-icon aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" />\n {{ trend.delta }}\n </span>\n </ng-container>\n\n </td>\n </ng-container>\n </ng-container>\n <!-- /past Data Columns -->\n\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['row-header'].concat(sourceColumns()); sticky: true;\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"allDataColumns(); sticky: true;\" [hidden]=\"!isHistoricalDataEnabled()\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['row-header'].concat(allDataColumns())\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}mat-card-actions>mat-slide-toggle{margin-left:20px}.row{flex-grow:1;display:flex;align-items:center}table{width:100%;overflow-y:auto}table .scroll{flex-grow:1;overflow-y:auto}table th{vertical-align:top;padding:.375rem}table th:not(:last-child){border-right:1px solid #e4e4e4}table tr:first-child>th:first-child{text-align:left}table td:first-child{text-align:left}.cell{flex:1}.mat-mdc-cell{padding-top:5px}.mat-mdc-cell,.mat-mdc-header-cell{padding-left:5px;text-align:center}.mat-mdc-cell a.chart-container,.mat-mdc-header-cell a.chart-container{display:flex;justify-content:center}.mat-mdc-cell .trending_up,.mat-mdc-header-cell .trending_up{color:#4abeff}.mat-mdc-cell .trending_down,.mat-mdc-header-cell .trending_down{color:#c20808}.recent-data-cell,.mat-column-row-header{border-right:1px solid #e4e4e4}.mat-header-cell-label{color:#000;padding-left:30px;padding-right:30px;justify-content:left;border-bottom:1px solid #e4e4e4;font-style:normal;font-weight:500;font-size:110%;background:#ddf0fb;text-align:left}.mat-header-cell-label>div{display:flex;font-weight:700;font-style:normal;justify-content:left}.mat-header-cell-small{padding-left:5px;padding-right:5px;justify-content:left;font-style:normal;font-weight:400;font-size:105%;background:#ddf0fb;border-top:1px solid #e4e4e4;border-bottom:1px solid #e4e4e4}.mat-mdc-cell a{cursor:pointer;display:flex;align-items:center;justify-content:left}.mat-mdc-cell a>mat-icon{padding-right:5px;font-size:22px;height:20px;opacity:.75}.mat-mdc-cell a>mat-icon:hover,.mat-mdc-cell a>mat-icon:focus{text-decoration:none}.mat-mdc-cell .number{display:flex;height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header-sum{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;border-right:5px solid #bdbdbd}.mat-mdc-card{width:100%;box-shadow:none}.mat-mdc-card ::ng-deep mat-card-header{align-items:center}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.mat-mdc-card .source-header{font-style:normal;font-weight:400;font-size:20px;height:30px;width:60%}.mat-mdc-card .source-header .robot-explanation{font-size:15px}.mat-mdc-card .scroll{flex-grow:1;overflow-y:auto}.mat-header-cell-scope{color:#545454}.mat-mdc-header-row{height:70px;max-height:70px;min-height:56px}:host{overflow:auto}:host ::ng-deep thead{border:10px solid #ff0000;position:relative;z-index:1}.mat-cell-level-1{padding-left:20px!important}.mat-cell-level-2{padding-left:40px!important}.mat-cell-level-3{padding-left:60px!important}.mat-cell-level-4{padding-left:80px!important}.mat-cell-level-5{padding-left:100px!important}.mat-cell-level-6{padding-left:120px!important}.mat-cell-level-7{padding-left:140px!important}.mat-cell-level-8{padding-left:160px!important}.actionbar{flex:1 1 auto;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}.scroll-controller{position:fixed;right:.5rem;z-index:100;display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:.5rem}.scroll-button{min-width:0;padding-left:.25rem;padding-right:.25rem;text-align:center;height:1.75rem}.toolbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:stretch;gap:.5rem}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: QualityMatrixFilterComponent, selector: "metaqs2-qm-filter", inputs: ["options", "inputFormControl", "label", "multiple"], outputs: ["changedFilters"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: DonutChartComponent, selector: "metaqs2-donut-chart", inputs: ["radius", "viewBox", "borderSize", "strokeWidth", "data"] }, { kind: "directive", type: ScrollMarkerDirective, selector: "[metaqs2ScrollMarker]" }] }); }
|
|
2659
2659
|
}
|
|
2660
2660
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, decorators: [{
|
|
2661
2661
|
type: Component,
|
|
@@ -2690,8 +2690,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
2690
2690
|
MatIconButton,
|
|
2691
2691
|
DonutChartComponent,
|
|
2692
2692
|
ScrollMarkerDirective,
|
|
2693
|
-
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title
|
|
2694
|
-
}],
|
|
2693
|
+
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"toolbar\">\n <metaqs2-qm-filter *ngFor=\"let filter of categoryControls.controls | keyvalue; trackBy: filterIdent\"\n [options]=\"categoryFilterValues.get(filter.key)\"\n [inputFormControl]=\"filter.value\"\n [label] = \"'filter.' + filter.key | translate\" />\n <div class=\"actionbar\">\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"isOnlySourcesWithMaterialEnabledFormField\" id=\"onlySourcesWithMaterial\">\n show only sources with material\n </mat-slide-toggle>\n <div style=\"flex: 1 1 auto\"></div>\n <metaqs2-datepicker *ngIf=\"isHistoricalDataEnabled()\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" />\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"isHistoricalDataEnabledFormField\" id=\"showHistoricalData\">\n show historical data\n </mat-slide-toggle>\n <button\n mat-icon-button\n color=\"primary\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh()\"\n matTooltip=\"Aktualisiere den IST-Stand\"\n matTooltipShowDelay=\"500\"\n >\n <mat-icon>refresh</mat-icon>\n </button>\n <div style=\"flex: 0 0 {{scroller.getBoundingClientRect().width}}px\"></div>\n <div class=\"scroll-controller\" #scroller> <!-- put the whole toolbar in a fixed container (MQS- -->\n <button mat-raised-button (click)=\"scrollToLeft()\" [disabled]=\"!isLeftScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_left</mat-icon>\n </button>\n <button mat-raised-button (click)=\"scrollToRight()\" [disabled]=\"!isRightScrollable()\" class=\"scroll-button\">\n <mat-icon style=\"margin: 0\">chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentQualityMatrix().rows\" class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"row-header\" sticky>\n <th rowspan=\"2\" mat-header-cell *matHeaderCellDef #issueType>Issue Type</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n matTooltip=\"{{row.meta.alt_label}}\"\n class=\"row-header mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{\"quality_matrix.\" + row.meta.label | translate }}\n </td>\n </ng-container>\n <!-- one column for the source -->\n <ng-container *ngFor=\"let col of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"col.id + '_source'\">\n <th [attr.colspan]=\"isHistoricalDataEnabled() ? 2 : 1\" metaqs2ScrollMarker mat-header-cell *matHeaderCellDef matTooltip=\"{{col.altLabel}}\">{{col.label}}</th>\n </ng-container>\n <!-- /source -->\n <!-- current Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"column.id + '_current'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"{{column.altLabel}}\">{{ range.controls.end.value?.toLocaleString(DateTime.DATE_SHORT) }} <br>({{column.total}})</th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\" #cell (mouseover)=\"showTooltip(row, column, cell)\" (mouseleave)=\"hideTooltip(cell)\">\n <a *ngIf=\"column.total > 0 else emptyDiv\" class=\"chart-container\" (click)=\"openEditLink( column.label, row.meta.label)\">\n <div>\n <metaqs2-donut-chart [data]=\"getDonutSlices(row, column)\" [borderSize]=\"25\"></metaqs2-donut-chart>\n </div>\n </a>\n <ng-template #emptyDiv>\n <div>-</div>\n </ng-template>\n </td>\n </ng-container>\n <!-- /current Data Columns -->\n <!-- past Data Columns -->\n <ng-container *ngIf=\"isHistoricalDataEnabled()\">\n <ng-container *ngFor=\"let column of filteredColumns(); trackBy:columnIdent\" [matColumnDef]=\"column.id + '_past'\">\n <th class=\"historic-data-cell\" mat-header-cell\n *matHeaderCellDef>{{ range.controls.start.value?.toLocaleString(DateTime.DATE_SHORT) }}\n <br>{{ getPastColumn(column.id)?.total }}\n </th>\n <td class=\"historic-data-cell\" mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getTrend(row, column) as trend\">\n <span [ngClass]=\"trend.trend\">\n <mat-icon aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" />\n {{ trend.delta }}\n </span>\n </ng-container>\n\n </td>\n </ng-container>\n </ng-container>\n <!-- /past Data Columns -->\n\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['row-header'].concat(sourceColumns()); sticky: true;\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"allDataColumns(); sticky: true;\" [hidden]=\"!isHistoricalDataEnabled()\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['row-header'].concat(allDataColumns())\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}mat-card-actions>mat-slide-toggle{margin-left:20px}.row{flex-grow:1;display:flex;align-items:center}table{width:100%;overflow-y:auto}table .scroll{flex-grow:1;overflow-y:auto}table th{vertical-align:top;padding:.375rem}table th:not(:last-child){border-right:1px solid #e4e4e4}table tr:first-child>th:first-child{text-align:left}table td:first-child{text-align:left}.cell{flex:1}.mat-mdc-cell{padding-top:5px}.mat-mdc-cell,.mat-mdc-header-cell{padding-left:5px;text-align:center}.mat-mdc-cell a.chart-container,.mat-mdc-header-cell a.chart-container{display:flex;justify-content:center}.mat-mdc-cell .trending_up,.mat-mdc-header-cell .trending_up{color:#4abeff}.mat-mdc-cell .trending_down,.mat-mdc-header-cell .trending_down{color:#c20808}.recent-data-cell,.mat-column-row-header{border-right:1px solid #e4e4e4}.mat-header-cell-label{color:#000;padding-left:30px;padding-right:30px;justify-content:left;border-bottom:1px solid #e4e4e4;font-style:normal;font-weight:500;font-size:110%;background:#ddf0fb;text-align:left}.mat-header-cell-label>div{display:flex;font-weight:700;font-style:normal;justify-content:left}.mat-header-cell-small{padding-left:5px;padding-right:5px;justify-content:left;font-style:normal;font-weight:400;font-size:105%;background:#ddf0fb;border-top:1px solid #e4e4e4;border-bottom:1px solid #e4e4e4}.mat-mdc-cell a{cursor:pointer;display:flex;align-items:center;justify-content:left}.mat-mdc-cell a>mat-icon{padding-right:5px;font-size:22px;height:20px;opacity:.75}.mat-mdc-cell a>mat-icon:hover,.mat-mdc-cell a>mat-icon:focus{text-decoration:none}.mat-mdc-cell .number{display:flex;height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;padding-left:15px}.mat-mdc-cell .row-header-sum{display:flex;height:47px;max-height:47px;justify-content:left;align-items:center;border-right:5px solid #bdbdbd}.mat-mdc-card{width:100%;box-shadow:none}.mat-mdc-card ::ng-deep mat-card-header{align-items:center}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.mat-mdc-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.mat-mdc-card .source-header{font-style:normal;font-weight:400;font-size:20px;height:30px;width:60%}.mat-mdc-card .source-header .robot-explanation{font-size:15px}.mat-mdc-card .scroll{flex-grow:1;overflow-y:auto}.mat-header-cell-scope{color:#545454}.mat-mdc-header-row{height:70px;max-height:70px;min-height:56px}:host{overflow:auto}:host ::ng-deep thead{border:10px solid #ff0000;position:relative;z-index:1}.mat-cell-level-1{padding-left:20px!important}.mat-cell-level-2{padding-left:40px!important}.mat-cell-level-3{padding-left:60px!important}.mat-cell-level-4{padding-left:80px!important}.mat-cell-level-5{padding-left:100px!important}.mat-cell-level-6{padding-left:120px!important}.mat-cell-level-7{padding-left:140px!important}.mat-cell-level-8{padding-left:160px!important}.actionbar{flex:1 1 auto;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}.scroll-controller{position:fixed;right:.5rem;z-index:100;display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:.5rem}.scroll-button{min-width:0;padding-left:.25rem;padding-right:.25rem;text-align:center;height:1.75rem}.toolbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:stretch;gap:.5rem}\n"] }]
|
|
2694
|
+
}], propDecorators: { issueTypeHeader: [{
|
|
2695
2695
|
type: ViewChild,
|
|
2696
2696
|
args: ['issueType', {
|
|
2697
2697
|
read: ElementRef,
|
|
@@ -3140,7 +3140,7 @@ class TreeCollectionDetailsComponent {
|
|
|
3140
3140
|
return this.linkService.openByCollectionAndIssueType(collectionId, issueType, title);
|
|
3141
3141
|
}
|
|
3142
3142
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeCollectionDetailsComponent, deps: [{ token: MetaApiService }, { token: i2$3.TranslateService }, { token: EditorialLinkService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3143
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeCollectionDetailsComponent, isStandalone: true, selector: "metaqs2-tree-collection-details", inputs: { collectionId: "collectionId", pageTitle: "pageTitle" }, ngImport: i0, template: "<mat-card>\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n Qualit\u00E4tsmetrik: {{pageTitle | translate}}{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title\n >\n </mat-card-header>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table *ngIf=\"!isLoading()\" [ngClass]=\"{'while-loading': isLoading()}\" mat-table [dataSource]=\"recentQualityMatrix$.value.rows\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"row-header\" sticky>\n <th mat-header-cell *matHeaderCellDef>Sammlung</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"row-header {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"'level-' + Math.min(3, row.meta.level+1)\"></mat-icon>\n {{row.meta.label}}\n </a>\n </td>\n </ng-container>\n\n <!-- Data Columns -->\n <ng-container *ngFor=\"let column of dataColumns\" [matColumnDef]=\"column.id\">\n <th mat-header-cell *matHeaderCellDef>{{ \"quality_matrix.\" + column.label | translate }}</th>\n <td mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\" column.id === 'collection_issues' else countsWithLinks\">\n {{ translateCollectionIssues(row.counts[column.id]) | async }}\n </ng-container>\n <ng-template #countsWithLinks>\n <a *ngIf=\"row.counts[column.id]\" (click)=\"showMaterialWithIssue(row.meta.id, row.meta.label, column.id)\">\n {{ row.counts[column.id] }}\n </a>\n </ng-template>\n\n\n </td>\n </ng-container>\n\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['row-header'].concat(columnIds); sticky:true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['row-header'].concat(columnIds)\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>.mat-column-row-header,tr:nth-child(2n) .mat-mdc-cell{border-right-color:#fff}.mat-mdc-cell,.mat-mdc-header-cell,.mat-column-row-header{border-right:1px solid #e4e4e4}.mat-mdc-cell mat-icon,.mat-mdc-header-cell mat-icon,.mat-column-row-header mat-icon{color:var(--mat-table-row-item-label-text-color);height:16px;padding-right:5px;font-size:16px}.mat-mdc-header-cell,.mat-mdc-cell{padding-left:5px;text-align:left}.mat-mdc-header-cell a,.mat-mdc-cell a{cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a:hover,.mat-mdc-cell a:hover{text-decoration:underline}.row-header a{text-decoration:none;align-items:center;display:flex}.mat-column-totals_collection.noMaterial{background-color:#fad6da}.mat-column-totals_collection.fewMaterials{background-color:#fff1d6}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-8{padding-left:160px!important;text-align:left}mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20px}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i3$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type:
|
|
3143
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeCollectionDetailsComponent, isStandalone: true, selector: "metaqs2-tree-collection-details", inputs: { collectionId: "collectionId", pageTitle: "pageTitle" }, ngImport: i0, template: "<mat-card>\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n Qualit\u00E4tsmetrik: {{pageTitle | translate}}{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title\n >\n </mat-card-header>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table *ngIf=\"!isLoading()\" [ngClass]=\"{'while-loading': isLoading()}\" mat-table [dataSource]=\"recentQualityMatrix$.value.rows\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"row-header\" sticky>\n <th mat-header-cell *matHeaderCellDef>Sammlung</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"row-header {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"'level-' + Math.min(3, row.meta.level+1)\"></mat-icon>\n {{row.meta.label}}\n </a>\n </td>\n </ng-container>\n\n <!-- Data Columns -->\n <ng-container *ngFor=\"let column of dataColumns\" [matColumnDef]=\"column.id\">\n <th mat-header-cell *matHeaderCellDef>{{ \"quality_matrix.\" + column.label | translate }}</th>\n <td mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\" column.id === 'collection_issues' else countsWithLinks\">\n {{ translateCollectionIssues(row.counts[column.id]) | async }}\n </ng-container>\n <ng-template #countsWithLinks>\n <a *ngIf=\"row.counts[column.id]\" (click)=\"showMaterialWithIssue(row.meta.id, row.meta.label, column.id)\">\n {{ row.counts[column.id] }}\n </a>\n </ng-template>\n\n\n </td>\n </ng-container>\n\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['row-header'].concat(columnIds); sticky:true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['row-header'].concat(columnIds)\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>.mat-column-row-header,tr:nth-child(2n) .mat-mdc-cell{border-right-color:#fff}.mat-mdc-cell,.mat-mdc-header-cell,.mat-column-row-header{border-right:1px solid #e4e4e4}.mat-mdc-cell mat-icon,.mat-mdc-header-cell mat-icon,.mat-column-row-header mat-icon{color:var(--mat-table-row-item-label-text-color);height:16px;padding-right:5px;font-size:16px}.mat-mdc-header-cell,.mat-mdc-cell{padding-left:5px;text-align:left}.mat-mdc-header-cell a,.mat-mdc-cell a{cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a:hover,.mat-mdc-cell a:hover{text-decoration:underline}.row-header a{text-decoration:none;align-items:center;display:flex}.mat-column-totals_collection.noMaterial{background-color:#fad6da}.mat-column-totals_collection.fewMaterials{background-color:#fff1d6}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-8{padding-left:160px!important;text-align:left}mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20px}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i3$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i5$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i5$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i5$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i5$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
|
|
3144
3144
|
}
|
|
3145
3145
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeCollectionDetailsComponent, decorators: [{
|
|
3146
3146
|
type: Component,
|
|
@@ -3428,7 +3428,7 @@ class TreeSearchCountsComponent {
|
|
|
3428
3428
|
return this.collectionColumns.flatMap((e, i) => [e, this.searchColumns[i]]);
|
|
3429
3429
|
}
|
|
3430
3430
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeSearchCountsComponent, deps: [{ token: MetaApiService }, { token: ConfigHelperService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3431
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeSearchCountsComponent, isStandalone: true, selector: "metaqs2-tree-search-counts", inputs: { pageTitle: "pageTitle", collectionId: "collectionId" }, ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>Material in Sammlungen{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"toolbar\">\n <div style=\"flex: 1 1 auto;\"></div>\n <div class=\"actionbar\">\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showOERonly\">\n zeige nur OER\n </mat-slide-toggle>\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showAllColumns\">\n zeige alle Typen\n </mat-slide-toggle>\n </div>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table *ngIf=\"columns\" [ngClass]=\"{'while-loading': isLoading()}\" mat-table [dataSource]=\"materialCounts.rows\" class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Label Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th rowspan=\"2\" mat-header-cell *matHeaderCellDef>Sammlung</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"label-col {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"'level-' + Math.min(3, row.meta.level+1)\"></mat-icon>\n {{ row.meta.label }}\n </a>\n </td>\n </ng-container>\n <!-- one column for the MaterialType spanning the collection and search columns-->\n <ng-container *ngFor=\"let col of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"2\" mat-header-cell *matHeaderCellDef class=\"mat-cell-level-{{col.level}}\">{{col.label}}</th>\n </ng-container>\n <!-- /source -->\n <!-- collection Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"column.id + COLLECTION_POSTFIX\">\n <th mat-header-cell *matHeaderCellDef>in Sammlung</th>\n <td [class.noMaterial]=\"!row.counts[column.id]?.sufficient || row.counts[column.id]?.sufficient <= 1\"\n [class.fewMaterials]=\"1 < row.counts[column.id]?.sufficient && row.counts[column.id]?.sufficient <= 3\"\n class=\"collection-data-cell\"\n mat-cell *matCellDef=\"let row\">\n <a (click)=\"showCollectionItems(row.meta.id, row.meta.label, column.id)\">\n {{ row.counts[column.id]?.sufficient || '0' }}\n </a>\n </td>\n </ng-container>\n <!-- /collection Data Columns -->\n <!-- search Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns let index = index; trackBy:columnIdent\" [matColumnDef]=\"column.id + SEARCH_POSTFIX\">\n <th mat-header-cell *matHeaderCellDef>Suche</th>\n <td class=\"search-data-cell\" mat-cell *matCellDef=\"let row\">\n <a (click)=\"searchInEditor(column.id, row.meta.label)\">\n <ng-container *ngIf=\"(( searchCounts | async)?.has(column.id + '_' + row.meta.id) ) else zeroOrLoading\">\n {{ (searchCounts | async)?.get(column.id + '_' + row.meta.id) }}\n </ng-container>\n <ng-template #zeroOrLoading>\n <ng-container *ngIf=\"rowsLoaded.has(row.meta.id) else loadingBlock\"> 0 </ng-container>\n </ng-template>\n <ng-template #loadingBlock>\n loading\u2026\n </ng-template>\n </a>\n </td>\n </ng-container>\n <!-- /search Data Columns -->\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat( typeColumns ); sticky: true;\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"alternatingDataColumns; sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(alternatingDataColumns)\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>.mat-column-label-col,tr:nth-child(2n) .search-data-cell{border-right-color:#fff}.search-data-cell,.mat-mdc-header-cell,.mat-column-label-col{border-right:1px solid #e4e4e4}.search-data-cell mat-icon,.mat-mdc-header-cell mat-icon,.mat-column-label-col mat-icon{color:var(--mat-table-row-item-label-text-color);height:16px;padding-right:5px;font-size:16px}.mat-mdc-header-cell,.mat-mdc-cell{padding-left:5px;text-align:center}.mat-mdc-header-cell a,.mat-mdc-cell a{cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a:hover,.mat-mdc-cell a:hover{text-decoration:underline}.label-col a{text-decoration:none;align-items:center;display:flex}.mat-column-totals_collection.noMaterial{background-color:#fad6da}.mat-column-totals_collection.fewMaterials{background-color:#fff1d6}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-8{padding-left:160px!important;text-align:left}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:stretch;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i3$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type:
|
|
3431
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeSearchCountsComponent, isStandalone: true, selector: "metaqs2-tree-search-counts", inputs: { pageTitle: "pageTitle", collectionId: "collectionId" }, ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>Material in Sammlungen{{isLoading() ? \": Lade neue Daten.\" : \"\"}}</mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"toolbar\">\n <div style=\"flex: 1 1 auto;\"></div>\n <div class=\"actionbar\">\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showOERonly\">\n zeige nur OER\n </mat-slide-toggle>\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showAllColumns\">\n zeige alle Typen\n </mat-slide-toggle>\n </div>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table *ngIf=\"columns\" [ngClass]=\"{'while-loading': isLoading()}\" mat-table [dataSource]=\"materialCounts.rows\" class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Label Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th rowspan=\"2\" mat-header-cell *matHeaderCellDef>Sammlung</th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"label-col {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"'level-' + Math.min(3, row.meta.level+1)\"></mat-icon>\n {{ row.meta.label }}\n </a>\n </td>\n </ng-container>\n <!-- one column for the MaterialType spanning the collection and search columns-->\n <ng-container *ngFor=\"let col of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"2\" mat-header-cell *matHeaderCellDef class=\"mat-cell-level-{{col.level}}\">{{col.label}}</th>\n </ng-container>\n <!-- /source -->\n <!-- collection Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns; trackBy:columnIdent\" [matColumnDef]=\"column.id + COLLECTION_POSTFIX\">\n <th mat-header-cell *matHeaderCellDef>in Sammlung</th>\n <td [class.noMaterial]=\"!row.counts[column.id]?.sufficient || row.counts[column.id]?.sufficient <= 1\"\n [class.fewMaterials]=\"1 < row.counts[column.id]?.sufficient && row.counts[column.id]?.sufficient <= 3\"\n class=\"collection-data-cell\"\n mat-cell *matCellDef=\"let row\">\n <a (click)=\"showCollectionItems(row.meta.id, row.meta.label, column.id)\">\n {{ row.counts[column.id]?.sufficient || '0' }}\n </a>\n </td>\n </ng-container>\n <!-- /collection Data Columns -->\n <!-- search Data Columns -->\n <ng-container *ngFor=\"let column of filteredColumns let index = index; trackBy:columnIdent\" [matColumnDef]=\"column.id + SEARCH_POSTFIX\">\n <th mat-header-cell *matHeaderCellDef>Suche</th>\n <td class=\"search-data-cell\" mat-cell *matCellDef=\"let row\">\n <a (click)=\"searchInEditor(column.id, row.meta.label)\">\n <ng-container *ngIf=\"(( searchCounts | async)?.has(column.id + '_' + row.meta.id) ) else zeroOrLoading\">\n {{ (searchCounts | async)?.get(column.id + '_' + row.meta.id) }}\n </ng-container>\n <ng-template #zeroOrLoading>\n <ng-container *ngIf=\"rowsLoaded.has(row.meta.id) else loadingBlock\"> 0 </ng-container>\n </ng-template>\n <ng-template #loadingBlock>\n loading\u2026\n </ng-template>\n </a>\n </td>\n </ng-container>\n <!-- /search Data Columns -->\n <!-- Generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat( typeColumns ); sticky: true;\"></tr>\n <tr mat-header-row *matHeaderRowDef=\"alternatingDataColumns; sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(alternatingDataColumns)\"></tr>\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>.mat-column-label-col,tr:nth-child(2n) .search-data-cell{border-right-color:#fff}.search-data-cell,.mat-mdc-header-cell,.mat-column-label-col{border-right:1px solid #e4e4e4}.search-data-cell mat-icon,.mat-mdc-header-cell mat-icon,.mat-column-label-col mat-icon{color:var(--mat-table-row-item-label-text-color);height:16px;padding-right:5px;font-size:16px}.mat-mdc-header-cell,.mat-mdc-cell{padding-left:5px;text-align:center}.mat-mdc-header-cell a,.mat-mdc-cell a{cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a:hover,.mat-mdc-cell a:hover{text-decoration:underline}.label-col a{text-decoration:none;align-items:center;display:flex}.mat-column-totals_collection.noMaterial{background-color:#fad6da}.mat-column-totals_collection.fewMaterials{background-color:#fff1d6}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-8{padding-left:160px!important;text-align:left}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:stretch;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i3$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i5$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i5$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i5$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i5$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
|
|
3432
3432
|
}
|
|
3433
3433
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeSearchCountsComponent, decorators: [{
|
|
3434
3434
|
type: Component,
|
|
@@ -3512,7 +3512,7 @@ class MonthpickerComponent {
|
|
|
3512
3512
|
{ provide: LOCALE_ID, useValue: 'de-DE' },
|
|
3513
3513
|
{ provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
|
|
3514
3514
|
{ provide: MAT_LUXON_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true, firstDayOfWeek: 1 } },
|
|
3515
|
-
], viewQueries: [{ propertyName: "start", first: true, predicate: ["start"], descendants: true, read: ElementRef, static: true }, { propertyName: "ripple", first: true, predicate: ["ripple"], descendants: true, read: MatRipple, static: true }], ngImport: i0, template: "<!--\n<mat-card>\n <mat-card-header>\n <mat-card-title> Monatlicher Vergleich </mat-card-title>\n </mat-card-header>\n <mat-card-content [formGroup]=\"inputGroup\">\n </!-- start date --/>\n -->\n<div [formGroup]=\"inputGroup\" matRipple #ripple=\"matRipple\" [matRippleDisabled]=\"true\">\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\n #start\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker1\" formControlName=\"start\"\n placeholder=\"Starts date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker1\n [startAt]=\"inputGroup.controls.start.defaultValue\"\n [startView]=\"startView\"\n (monthSelected)=\"setStart($event, picker1)\"\n\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /start date -->\n <!-- end date -->\n <mat-form-field>\n <mat-label>Zeitpunkt2</mat-label>\n <input matInput\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker2\"\n formControlName=\"end\"\n placeholder=\"End date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker2\n [startAt]=\"inputGroup.controls.end.value\"\n [startView]=\"startView\"\n (monthSelected)=\"setEnd($event, picker2)\"\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n</div>\n<!--\n </mat-card-content>\n</mat-card>\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }] }); }
|
|
3515
|
+
], viewQueries: [{ propertyName: "start", first: true, predicate: ["start"], descendants: true, read: (ElementRef), static: true }, { propertyName: "ripple", first: true, predicate: ["ripple"], descendants: true, read: MatRipple, static: true }], ngImport: i0, template: "<!--\n<mat-card>\n <mat-card-header>\n <mat-card-title> Monatlicher Vergleich </mat-card-title>\n </mat-card-header>\n <mat-card-content [formGroup]=\"inputGroup\">\n </!-- start date --/>\n -->\n<div [formGroup]=\"inputGroup\" matRipple #ripple=\"matRipple\" [matRippleDisabled]=\"true\">\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\n #start\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker1\" formControlName=\"start\"\n placeholder=\"Starts date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker1\n [startAt]=\"inputGroup.controls.start.defaultValue\"\n [startView]=\"startView\"\n (monthSelected)=\"setStart($event, picker1)\"\n\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /start date -->\n <!-- end date -->\n <mat-form-field>\n <mat-label>Zeitpunkt2</mat-label>\n <input matInput\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker2\"\n formControlName=\"end\"\n placeholder=\"End date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker2\n [startAt]=\"inputGroup.controls.end.value\"\n [startView]=\"startView\"\n (monthSelected)=\"setEnd($event, picker2)\"\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n</div>\n<!--\n </mat-card-content>\n</mat-card>\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }] }); }
|
|
3516
3516
|
}
|
|
3517
3517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MonthpickerComponent, decorators: [{
|
|
3518
3518
|
type: Component,
|
|
@@ -3539,7 +3539,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3539
3539
|
{ provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
|
|
3540
3540
|
{ provide: MAT_LUXON_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true, firstDayOfWeek: 1 } },
|
|
3541
3541
|
], template: "<!--\n<mat-card>\n <mat-card-header>\n <mat-card-title> Monatlicher Vergleich </mat-card-title>\n </mat-card-header>\n <mat-card-content [formGroup]=\"inputGroup\">\n </!-- start date --/>\n -->\n<div [formGroup]=\"inputGroup\" matRipple #ripple=\"matRipple\" [matRippleDisabled]=\"true\">\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\n #start\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker1\" formControlName=\"start\"\n placeholder=\"Starts date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker1\n [startAt]=\"inputGroup.controls.start.defaultValue\"\n [startView]=\"startView\"\n (monthSelected)=\"setStart($event, picker1)\"\n\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /start date -->\n <!-- end date -->\n <mat-form-field>\n <mat-label>Zeitpunkt2</mat-label>\n <input matInput\n [disabled]=\"disabled\"\n [min]=\"inputGroup.controls.start.defaultValue\"\n [max]=\"inputGroup.controls.end.defaultValue\"\n [matDatepicker]=\"picker2\"\n formControlName=\"end\"\n placeholder=\"End date\"\n >\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker\n [disabled]=\"disabled\"\n #picker2\n [startAt]=\"inputGroup.controls.end.value\"\n [startView]=\"startView\"\n (monthSelected)=\"setEnd($event, picker2)\"\n >\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n</div>\n<!--\n </mat-card-content>\n</mat-card>\n-->\n" }]
|
|
3542
|
-
}],
|
|
3542
|
+
}], propDecorators: { startView: [{
|
|
3543
3543
|
type: Input
|
|
3544
3544
|
}], inputGroup: [{
|
|
3545
3545
|
type: Input,
|
|
@@ -3549,7 +3549,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3549
3549
|
}], start: [{
|
|
3550
3550
|
type: ViewChild,
|
|
3551
3551
|
args: ['start', {
|
|
3552
|
-
read: ElementRef,
|
|
3552
|
+
read: (ElementRef),
|
|
3553
3553
|
static: true,
|
|
3554
3554
|
}]
|
|
3555
3555
|
}], ripple: [{
|
|
@@ -3676,20 +3676,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3676
3676
|
type: Input
|
|
3677
3677
|
}] } });
|
|
3678
3678
|
|
|
3679
|
-
class
|
|
3680
|
-
constructor(
|
|
3681
|
-
this.metaApi =
|
|
3682
|
-
this.destroyRef =
|
|
3683
|
-
this.linkService =
|
|
3679
|
+
class BaseHistoricDataTableDirective {
|
|
3680
|
+
constructor() {
|
|
3681
|
+
this.metaApi = inject(MetaApiService);
|
|
3682
|
+
this.destroyRef = inject(DestroyRef);
|
|
3683
|
+
this.linkService = inject(EditorialLinkService);
|
|
3684
|
+
this.columnTranslationkey = null;
|
|
3684
3685
|
this.loadingCount = signal(0);
|
|
3685
3686
|
this.isLoading = computed(() => this.loadingCount() > 0);
|
|
3687
|
+
this.isHistoryEnabled = signal(false);
|
|
3688
|
+
this.isHistoryEnabled$ = toObservable(this.isHistoryEnabled);
|
|
3686
3689
|
this.timeFilterLoaded = signal(false);
|
|
3687
3690
|
this.recentTypeCount$ = new BehaviorSubject({ columns: [], rows: [] });
|
|
3688
3691
|
this.pastTypeCount$ = new BehaviorSubject({ columns: [], rows: [] });
|
|
3689
3692
|
this.DateTime = DateTime;
|
|
3690
3693
|
this.columns = signal([]);
|
|
3691
|
-
this.
|
|
3692
|
-
this.
|
|
3694
|
+
this.dataForPastData$ = new Subject();
|
|
3695
|
+
this.dataForRecentData$ = new Subject();
|
|
3696
|
+
this.startValues$ = this.dataForPastData$.pipe(filter((data) => this.validateLoadingData(data)), distinctUntilChanged((a, b) => this.compareLoadingDataEqual(a, b)), throttleTime(500), switchMap((start) => this.getCountByDate(start)), tap((it) => this.pastTypeCount$.next(it)), takeUntilDestroyed(this.destroyRef));
|
|
3697
|
+
this.endValues$ = this.dataForRecentData$.pipe(filter((data) => this.validateLoadingData(data)), distinctUntilChanged((a, b) => this.compareLoadingDataEqual(a, b)), throttleTime(500), switchMap((end) => this.getCountByDate(end)), tap((it) => this.recentTypeCount$.next(it)), tap((it) => this.columns.set(it.columns.slice())), takeUntilDestroyed(this.destroyRef));
|
|
3693
3698
|
/* In this widget's backend we do have data for today
|
|
3694
3699
|
* therefore we set the end date to today and use the timerange() endpoint to only set the start date
|
|
3695
3700
|
*/
|
|
@@ -3697,7 +3702,11 @@ class CountsWithHistoryComponent {
|
|
|
3697
3702
|
start: new FormControl(),
|
|
3698
3703
|
end: new FormControl(DateTime.utc().startOf('day'), { nonNullable: true }),
|
|
3699
3704
|
});
|
|
3700
|
-
this.
|
|
3705
|
+
this.timerangeStart$ = of(undefined).pipe(switchMap(() => this.getAvailableDateRange()), take(1), map((rangeFilter) => this.getStartDateOfRange(rangeFilter)), tap((startDate) => {
|
|
3706
|
+
//this is to have a default value for the start date => the min date of the range
|
|
3707
|
+
this.range.setControl('start', new FormControl(startDate, { nonNullable: true }));
|
|
3708
|
+
this.timeFilterLoaded.set(true);
|
|
3709
|
+
}), takeUntilDestroyed(this.destroyRef));
|
|
3701
3710
|
this.allColumns = computed(() => {
|
|
3702
3711
|
if (!this.isHistoryEnabled()) {
|
|
3703
3712
|
return this.recentColumns();
|
|
@@ -3713,39 +3722,9 @@ class CountsWithHistoryComponent {
|
|
|
3713
3722
|
this.pastColumns = computed(() => {
|
|
3714
3723
|
return this.columns().map((c) => c.id + '_past');
|
|
3715
3724
|
});
|
|
3716
|
-
effect(() => {
|
|
3717
|
-
this.range.controls.end.reset();
|
|
3718
|
-
if (!this.isHistoryEnabled()) {
|
|
3719
|
-
this.range.controls.start.setValue(this.range.controls.end.value.startOf('day'));
|
|
3720
|
-
}
|
|
3721
|
-
else {
|
|
3722
|
-
this.range.controls.start.reset();
|
|
3723
|
-
}
|
|
3724
|
-
});
|
|
3725
3725
|
}
|
|
3726
|
-
|
|
3727
|
-
this.
|
|
3728
|
-
.pipe(tap((rangeFilter) => {
|
|
3729
|
-
const startDate = this.getStartDateOfRange(rangeFilter);
|
|
3730
|
-
//this is to have a default value for the start date => the min date of the range
|
|
3731
|
-
this.range.setControl('start', new FormControl(startDate, { nonNullable: true }));
|
|
3732
|
-
}), finalize(() => {
|
|
3733
|
-
this.timeFilterLoaded.set(true);
|
|
3734
|
-
this.range.controls.start.reset();
|
|
3735
|
-
}), takeUntilDestroyed(this.destroyRef))
|
|
3736
|
-
.subscribe();
|
|
3737
|
-
this.getCountByDate(this.range.controls.end.value)
|
|
3738
|
-
.pipe(tap((response) => {
|
|
3739
|
-
this.columns.set(response.columns.slice());
|
|
3740
|
-
this.recentTypeCount$.next(response);
|
|
3741
|
-
}), takeUntilDestroyed(this.destroyRef))
|
|
3742
|
-
.subscribe();
|
|
3743
|
-
this.getValuesInDateRange()
|
|
3744
|
-
.pipe(tap(([past, recent]) => {
|
|
3745
|
-
this.pastTypeCount$.next(past);
|
|
3746
|
-
this.recentTypeCount$.next(recent);
|
|
3747
|
-
}), takeUntilDestroyed(this.destroyRef))
|
|
3748
|
-
.subscribe();
|
|
3726
|
+
getAvailableDateRange() {
|
|
3727
|
+
return of(undefined).pipe(tap(() => this.loadingCount.update((it) => it + 1)), switchMap(() => this.metaApi.getTimerangeFilter()), filter((filter) => filter != null), tap(() => this.loadingCount.update((it) => it - 1)));
|
|
3749
3728
|
}
|
|
3750
3729
|
getStartDateOfRange(rangeFilter) {
|
|
3751
3730
|
return DateTime.fromISO(rangeFilter.values.find((v) => v.id === 'rangeStart')?.label, {
|
|
@@ -3755,26 +3734,6 @@ class CountsWithHistoryComponent {
|
|
|
3755
3734
|
columnIdent(_index, col) {
|
|
3756
3735
|
return col.id;
|
|
3757
3736
|
}
|
|
3758
|
-
getAvailableDateRange() {
|
|
3759
|
-
this.loadingCount.update((it) => it + 1);
|
|
3760
|
-
return this.metaApi.getTimerangeFilter().pipe(filter((filter) => filter != null), finalize(() => this.loadingCount.update((it) => it - 1)));
|
|
3761
|
-
}
|
|
3762
|
-
getValuesInDateRange() {
|
|
3763
|
-
return this.range.valueChanges.pipe(filter((range) => !!range.start?.isValid && !!range.end?.isValid), switchMap((range) => {
|
|
3764
|
-
return zip(this.getCountByDate(range.start), this.getCountByDate(range.end));
|
|
3765
|
-
}));
|
|
3766
|
-
}
|
|
3767
|
-
getCountByDate(date) {
|
|
3768
|
-
this.loadingCount.update((it) => it + 1);
|
|
3769
|
-
const filter = {
|
|
3770
|
-
field: 'asOf',
|
|
3771
|
-
values: [{ id: date.toISO({ includeOffset: false }), label: '' }],
|
|
3772
|
-
};
|
|
3773
|
-
return this.metaApi[this.apiMethod]([filter]).pipe(finalize(() => this.loadingCount.update((it) => it - 1)), map((response) => ({
|
|
3774
|
-
...response,
|
|
3775
|
-
rows: response.rows.toSorted((a, b) => a.meta.label.localeCompare(b.meta.label)),
|
|
3776
|
-
})));
|
|
3777
|
-
}
|
|
3778
3737
|
pastTypeCount(row, columnid) {
|
|
3779
3738
|
if (!this.pastTypeCount$.value.rows.length) {
|
|
3780
3739
|
return {};
|
|
@@ -3799,8 +3758,75 @@ class CountsWithHistoryComponent {
|
|
|
3799
3758
|
return this.linkService.createLinkForCountsWithHistory(this.sourceType, sourceId, issueId);
|
|
3800
3759
|
}));
|
|
3801
3760
|
}
|
|
3802
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type:
|
|
3803
|
-
static { this.ɵ
|
|
3761
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BaseHistoricDataTableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3762
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: BaseHistoricDataTableDirective, inputs: { apiMethod: "apiMethod", columnTranslationkey: "columnTranslationkey", pageTitle: "pageTitle", sourceType: "sourceType" }, ngImport: i0 }); }
|
|
3763
|
+
}
|
|
3764
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BaseHistoricDataTableDirective, decorators: [{
|
|
3765
|
+
type: Directive
|
|
3766
|
+
}], propDecorators: { apiMethod: [{
|
|
3767
|
+
type: Input
|
|
3768
|
+
}], columnTranslationkey: [{
|
|
3769
|
+
type: Input
|
|
3770
|
+
}], pageTitle: [{
|
|
3771
|
+
type: Input
|
|
3772
|
+
}], sourceType: [{
|
|
3773
|
+
type: Input,
|
|
3774
|
+
args: [{ required: true }]
|
|
3775
|
+
}] } });
|
|
3776
|
+
class CountsWithHistoryComponent extends BaseHistoricDataTableDirective {
|
|
3777
|
+
ngOnInit() {
|
|
3778
|
+
this.apiMethod ??= 'getMaterialTypeCountsByReplicationSource';
|
|
3779
|
+
this.range.valueChanges
|
|
3780
|
+
.pipe(tap((data) => {
|
|
3781
|
+
this.dataForPastData$.next({ date: data.start });
|
|
3782
|
+
this.dataForRecentData$.next({ date: data.end });
|
|
3783
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
3784
|
+
.subscribe();
|
|
3785
|
+
this.isHistoryEnabled$
|
|
3786
|
+
.pipe(tap((enabled) => {
|
|
3787
|
+
this.range.controls.end.reset();
|
|
3788
|
+
if (!enabled) {
|
|
3789
|
+
this.startDateSubscription?.unsubscribe();
|
|
3790
|
+
this.startValuesSubscription?.unsubscribe();
|
|
3791
|
+
return;
|
|
3792
|
+
}
|
|
3793
|
+
this.range.controls.start.reset();
|
|
3794
|
+
if (!this.timeFilterLoaded()) {
|
|
3795
|
+
this.startDateSubscription = this.timerangeStart$
|
|
3796
|
+
.pipe(take(1), tap(() => {
|
|
3797
|
+
this.startValuesSubscription = this.startValues$.subscribe();
|
|
3798
|
+
this.range.controls.start.reset();
|
|
3799
|
+
}))
|
|
3800
|
+
.subscribe();
|
|
3801
|
+
}
|
|
3802
|
+
else {
|
|
3803
|
+
this.startValuesSubscription = this.startValues$.subscribe();
|
|
3804
|
+
this.range.controls.start.reset();
|
|
3805
|
+
}
|
|
3806
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
3807
|
+
.subscribe();
|
|
3808
|
+
this.endValues$.subscribe();
|
|
3809
|
+
}
|
|
3810
|
+
getCountByDate(data) {
|
|
3811
|
+
const filter = {
|
|
3812
|
+
field: 'asOf',
|
|
3813
|
+
values: [{ id: data.date.toISO({ includeOffset: false }), label: '' }],
|
|
3814
|
+
};
|
|
3815
|
+
return of(undefined).pipe(tap(() => this.loadingCount.update((it) => it + 1)), switchMap(() => {
|
|
3816
|
+
return this.metaApi[this.apiMethod]([filter]).pipe(finalize(() => this.loadingCount.update((it) => it - 1)));
|
|
3817
|
+
}), map((response) => ({
|
|
3818
|
+
...response,
|
|
3819
|
+
rows: response.rows.toSorted((a, b) => a.meta.label.localeCompare(b.meta.label)),
|
|
3820
|
+
})));
|
|
3821
|
+
}
|
|
3822
|
+
validateLoadingData(data) {
|
|
3823
|
+
return data.date?.isValid ?? false;
|
|
3824
|
+
}
|
|
3825
|
+
compareLoadingDataEqual(a, b) {
|
|
3826
|
+
return a.date.equals(b.date);
|
|
3827
|
+
}
|
|
3828
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CountsWithHistoryComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3829
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CountsWithHistoryComponent, isStandalone: true, selector: "metaqs2-counts-with-history", usesInheritance: true, ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <metaqs2-datepicker style=\"display: inline-block\" matRipple [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <div style=\"flex: 1 1 auto\"></div>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell{border-right:1px solid white}tr:nth-child(odd){background-color:#fff}tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}td.label-col{text-align:left}.mat-mdc-header-cell,.mat-mdc-cell{text-align:center}.mat-mdc-header-cell a[href],.mat-mdc-cell a[href]{color:var(--mat-table-row-item-label-text-color);cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a[href]:hover,.mat-mdc-cell a[href]:hover{text-decoration:underline}.mat-mdc-header-cell mat-icon,.mat-mdc-cell mat-icon{margin-left:5px;vertical-align:middle}.trending_down{color:#4abeff}.trending_up{color:#c20808}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i3$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i5$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i5$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i5$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i5$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }] }); }
|
|
3804
3830
|
}
|
|
3805
3831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CountsWithHistoryComponent, decorators: [{
|
|
3806
3832
|
type: Component,
|
|
@@ -3827,18 +3853,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3827
3853
|
AsyncPipe,
|
|
3828
3854
|
ProgressSpinnerComponent,
|
|
3829
3855
|
MatRipple,
|
|
3830
|
-
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <
|
|
3831
|
-
}]
|
|
3832
|
-
type: Input,
|
|
3833
|
-
args: [{ required: true }]
|
|
3834
|
-
}], columnTranslationkey: [{
|
|
3835
|
-
type: Input
|
|
3836
|
-
}], pageTitle: [{
|
|
3837
|
-
type: Input
|
|
3838
|
-
}], sourceType: [{
|
|
3839
|
-
type: Input,
|
|
3840
|
-
args: [{ required: true }]
|
|
3841
|
-
}] } });
|
|
3856
|
+
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <metaqs2-datepicker style=\"display: inline-block\" matRipple [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <div style=\"flex: 1 1 auto\"></div>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell{border-right:1px solid white}tr:nth-child(odd){background-color:#fff}tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}td.label-col{text-align:left}.mat-mdc-header-cell,.mat-mdc-cell{text-align:center}.mat-mdc-header-cell a[href],.mat-mdc-cell a[href]{color:var(--mat-table-row-item-label-text-color);cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a[href]:hover,.mat-mdc-cell a[href]:hover{text-decoration:underline}.mat-mdc-header-cell mat-icon,.mat-mdc-cell mat-icon{margin-left:5px;vertical-align:middle}.trending_down{color:#4abeff}.trending_up{color:#c20808}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}\n"] }]
|
|
3857
|
+
}] });
|
|
3842
3858
|
|
|
3843
3859
|
async function createRegister(environment) {
|
|
3844
3860
|
if (environment.production) {
|
|
@@ -3868,32 +3884,29 @@ async function createRegister(environment) {
|
|
|
3868
3884
|
};
|
|
3869
3885
|
}
|
|
3870
3886
|
|
|
3871
|
-
class TreeLicenseComponent extends
|
|
3887
|
+
class TreeLicenseComponent extends BaseHistoricDataTableDirective {
|
|
3872
3888
|
constructor() {
|
|
3873
3889
|
super(...arguments);
|
|
3874
3890
|
this.colId$ = new BehaviorSubject('defaultCollection');
|
|
3875
3891
|
this.sourceType = 'collection';
|
|
3876
|
-
this.apiMethod = 'getLicenseCountsByLicenseGroup';
|
|
3877
3892
|
}
|
|
3878
3893
|
set collectionId(id) {
|
|
3879
3894
|
this.colId$.next(id);
|
|
3880
3895
|
}
|
|
3881
|
-
getCountByDate(
|
|
3882
|
-
this.loadingCount.update((it) => it + 1);
|
|
3896
|
+
getCountByDate(data) {
|
|
3883
3897
|
const filter = {
|
|
3884
3898
|
field: 'asOf',
|
|
3885
|
-
values: [{ id: date.toISO({ includeOffset: false }), label: '' }],
|
|
3899
|
+
values: [{ id: data.date.toISO({ includeOffset: false }), label: '' }],
|
|
3886
3900
|
};
|
|
3887
|
-
return
|
|
3901
|
+
return of(undefined).pipe(tap(() => this.loadingCount.update((it) => it + 1)), switchMap(() => {
|
|
3902
|
+
return this.metaApi[this.apiMethod](this.colId$.getValue(), [filter]).pipe(finalize(() => this.loadingCount.update((it) => it - 1)));
|
|
3903
|
+
}), map((response) => {
|
|
3888
3904
|
const castedRows = response.rows.map((row) => row);
|
|
3889
3905
|
return {
|
|
3890
3906
|
...response,
|
|
3891
3907
|
// return the sufficient part of the counts, because the api return a QualityMatrix not a MatrixWithCounts
|
|
3892
3908
|
rows: castedRows.map((row) => {
|
|
3893
|
-
const counts = Object.entries(row.counts).
|
|
3894
|
-
acc[key] = count.sufficient;
|
|
3895
|
-
return acc;
|
|
3896
|
-
}, {});
|
|
3909
|
+
const counts = Object.fromEntries(Object.entries(row.counts).map(([key, value]) => [key, value.sufficient]));
|
|
3897
3910
|
return {
|
|
3898
3911
|
...row,
|
|
3899
3912
|
counts,
|
|
@@ -3903,20 +3916,52 @@ class TreeLicenseComponent extends CountsWithHistoryComponent {
|
|
|
3903
3916
|
}));
|
|
3904
3917
|
}
|
|
3905
3918
|
ngOnInit() {
|
|
3906
|
-
this.
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
this.
|
|
3919
|
+
this.apiMethod ??= 'getLicenseCountsByLicenseGroup';
|
|
3920
|
+
combineLatest([this.colId$, this.range.valueChanges])
|
|
3921
|
+
.pipe(tap(([collectionId, range]) => {
|
|
3922
|
+
this.dataForPastData$.next({
|
|
3923
|
+
date: range.start,
|
|
3924
|
+
collectionId: collectionId,
|
|
3925
|
+
});
|
|
3926
|
+
this.dataForRecentData$.next({
|
|
3927
|
+
date: range.end,
|
|
3928
|
+
collectionId: collectionId,
|
|
3929
|
+
});
|
|
3930
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
3931
|
+
.subscribe();
|
|
3932
|
+
this.isHistoryEnabled$
|
|
3933
|
+
.pipe(tap((enabled) => {
|
|
3934
|
+
this.range.controls.end.reset();
|
|
3935
|
+
if (!enabled) {
|
|
3936
|
+
this.startDateSubscription?.unsubscribe();
|
|
3937
|
+
this.startValuesSubscription?.unsubscribe();
|
|
3938
|
+
return;
|
|
3939
|
+
}
|
|
3940
|
+
this.range.controls.start.reset();
|
|
3941
|
+
if (!this.timeFilterLoaded()) {
|
|
3942
|
+
this.startDateSubscription = this.timerangeStart$
|
|
3943
|
+
.pipe(take(1), tap(() => {
|
|
3944
|
+
this.startValuesSubscription = this.startValues$.subscribe();
|
|
3945
|
+
this.range.controls.start.reset();
|
|
3946
|
+
}))
|
|
3947
|
+
.subscribe();
|
|
3948
|
+
}
|
|
3949
|
+
else {
|
|
3950
|
+
this.startValuesSubscription = this.startValues$.subscribe();
|
|
3951
|
+
this.range.controls.start.reset();
|
|
3952
|
+
}
|
|
3914
3953
|
}), takeUntilDestroyed(this.destroyRef))
|
|
3915
3954
|
.subscribe();
|
|
3916
|
-
|
|
3955
|
+
this.endValues$.subscribe();
|
|
3956
|
+
}
|
|
3957
|
+
validateLoadingData(data) {
|
|
3958
|
+
return !!data?.collectionId && (data.date?.isValid ?? false);
|
|
3959
|
+
}
|
|
3960
|
+
compareLoadingDataEqual(a, b) {
|
|
3961
|
+
return a.collectionId === b.collectionId && a.date.equals(b.date);
|
|
3917
3962
|
}
|
|
3918
3963
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeLicenseComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3919
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeLicenseComponent, isStandalone: true, selector: "metaqs2-tree-license", inputs: { collectionId: "collectionId", sourceType: "sourceType", apiMethod: "apiMethod" }, usesInheritance: true, ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <div style=\"flex: 1 1 auto\"></div>\n <metaqs2-datepicker style=\"display: inline-block\" matRipple #datepickerRipple=\"matRipple\" [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\" *ngIf=\"timeFilterLoaded()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-3:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-4:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-5:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-6:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-7:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-8{padding-left:160px!important;text-align:left}.mat-cell-level-8:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkgMTAuM0wxMiAxNi4zTDUgMTAuM0wxMiA0LjE5OTk1TDE5IDEwLjNaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+)}.mat-cell-level-0:before,.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNCAxMi45TDMgMTMuOEwxMSAyMC43QzExLjYgMjEuMiAxMi40IDIxLjIgMTMgMjAuN0wyMSAxMy44TDIwIDEyLjlMMTIgMTkuOEw0IDEyLjlaTTExIDMuNDAwMDJMNCA5LjQwMDAyQzMuNCA5LjkwMDAyIDMuNCAxMC43IDQgMTEuMUwxMSAxNy4yQzExLjYgMTcuNyAxMi40IDE3LjcgMTMgMTcuMkwyMCAxMS4xQzIwLjUgMTAuNiAyMC41IDkuODAwMDIgMjAgOS40MDAwMkwxMyAzLjMwMDAyQzEyLjQgMi45MDAwMiAxMS42IDIuOTAwMDIgMTEgMy40MDAwMloiIGZpbGw9IiMwMDNCN0MiLz48L3N2Zz4=)}.trending_down{color:#4abeff}.trending_up{color:#c20808}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "component", type: i4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i4.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
|
|
3964
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TreeLicenseComponent, isStandalone: true, selector: "metaqs2-tree-license", inputs: { collectionId: "collectionId", sourceType: "sourceType" }, usesInheritance: true, ngImport: i0, template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <metaqs2-datepicker style=\"display: inline-block\" matRipple [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <div style=\"flex: 1 1 auto\"></div>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell{border-right:1px solid white}tr:nth-child(odd){background-color:#fff}tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}td.label-col{text-align:left}.mat-mdc-header-cell,.mat-mdc-cell{text-align:center}.mat-mdc-header-cell a[href],.mat-mdc-cell a[href]{color:var(--mat-table-row-item-label-text-color);cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a[href]:hover,.mat-mdc-cell a[href]:hover{text-decoration:underline}.mat-mdc-header-cell mat-icon,.mat-mdc-cell mat-icon{margin-left:5px;vertical-align:middle}.trending_down{color:#4abeff}.trending_up{color:#c20808}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}\n", ".while-loading{filter:blur(2px)}tr:nth-child(2n),tr:nth-child(odd){background-color:#fff}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell,tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-3:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-4:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-5:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-6:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-7:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-8{padding-left:160px!important;text-align:left}.mat-cell-level-8:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkgMTAuM0wxMiAxNi4zTDUgMTAuM0wxMiA0LjE5OTk1TDE5IDEwLjNaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+)}.mat-cell-level-0:before,.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNCAxMi45TDMgMTMuOEwxMSAyMC43QzExLjYgMjEuMiAxMi40IDIxLjIgMTMgMjAuN0wyMSAxMy44TDIwIDEyLjlMMTIgMTkuOEw0IDEyLjlaTTExIDMuNDAwMDJMNCA5LjQwMDAyQzMuNCA5LjkwMDAyIDMuNCAxMC43IDQgMTEuMUwxMSAxNy4yQzExLjYgMTcuNyAxMi40IDE3LjcgMTMgMTcuMkwyMCAxMS4xQzIwLjUgMTAuNiAyMC41IDkuODAwMDIgMjAgOS40MDAwMkwxMyAzLjMwMDAyQzEyLjQgMi45MDAwMiAxMS42IDIuOTAwMDIgMTEgMy40MDAwMloiIGZpbGw9IiMwMDNCN0MiLz48L3N2Zz4=)}.trending_down{color:#4abeff}.trending_up{color:#c20808}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i5$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i5$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i5$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i5$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i5$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i5$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i5$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "component", type: i5$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i5$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
|
|
3920
3965
|
}
|
|
3921
3966
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeLicenseComponent, decorators: [{
|
|
3922
3967
|
type: Component,
|
|
@@ -3946,16 +3991,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3946
3991
|
ProgressSpinnerComponent,
|
|
3947
3992
|
TranslateModule,
|
|
3948
3993
|
FormsModule,
|
|
3949
|
-
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <div style=\"flex: 1 1 auto\"></div>\n <metaqs2-datepicker style=\"display: inline-block\" matRipple #datepickerRipple=\"matRipple\" [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\" *ngIf=\"timeFilterLoaded()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-3:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-4:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-5:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-6:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-7:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-8{padding-left:160px!important;text-align:left}.mat-cell-level-8:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkgMTAuM0wxMiAxNi4zTDUgMTAuM0wxMiA0LjE5OTk1TDE5IDEwLjNaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+)}.mat-cell-level-0:before,.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNCAxMi45TDMgMTMuOEwxMSAyMC43QzExLjYgMjEuMiAxMi40IDIxLjIgMTMgMjAuN0wyMSAxMy44TDIwIDEyLjlMMTIgMTkuOEw0IDEyLjlaTTExIDMuNDAwMDJMNCA5LjQwMDAyQzMuNCA5LjkwMDAyIDMuNCAxMC43IDQgMTEuMUwxMSAxNy4yQzExLjYgMTcuNyAxMi40IDE3LjcgMTMgMTcuMkwyMCAxMS4xQzIwLjUgMTAuNiAyMC41IDkuODAwMDIgMjAgOS40MDAwMkwxMyAzLjMwMDAyQzEyLjQgMi45MDAwMiAxMS42IDIuOTAwMDIgMTEgMy40MDAwMloiIGZpbGw9IiMwMDNCN0MiLz48L3N2Zz4=)}.trending_down{color:#4abeff}.trending_up{color:#c20808}\n"] }]
|
|
3994
|
+
], template: "<mat-card appearance=\"raised\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title data-test-id=\"page-title\">\n Qualit\u00E4tsmetrik: {{ pageTitle | translate }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <!-- consider to put the filter in the table header to avoid that it is scrolled out of view-->\n <!-- show the filter after the values are loaded to avoid loading current data twice -->\n <mat-card-content class=\"toolbar\">\n <metaqs2-datepicker style=\"display: inline-block\" matRipple [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded() && isHistoryEnabled()\"></metaqs2-datepicker>\n <div style=\"flex: 1 1 auto\"></div>\n <mat-slide-toggle [ngModel]=\"isHistoryEnabled()\" (ngModelChange)=\"isHistoryEnabled.set($event)\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </mat-card-content>\n</mat-card>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [class.while-loading]=\"isLoading()\" mat-table [dataSource]=\"recentTypeCount$.value.rows\"\n class=\"quality-matrix\">\n <!-- Define columns of table -->\n <!-- Row Header Column -->\n <ng-container matColumnDef=\"label-col\" sticky>\n <th [attr.rowspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef>\n <div>Quelle</div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col mat-cell-level-{{row.meta.level + 1}}\"\n >\n {{ row.meta.label }}\n </td>\n </ng-container>\n <!-- one column for each type -->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_type'\">\n <th [attr.colspan]=\"isHistoryEnabled() ? '2' : '1'\" mat-header-cell *matHeaderCellDef [matTooltip]=\"col.label\">\n {{ columnTranslationkey ? (columnTranslationkey + col.label | translate) : col.label }}\n </th>\n </ng-container>\n <!-- one column for each type for the most current date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_recent'\">\n <th class=\"recent-data-cell\" mat-header-cell *matHeaderCellDef\n matTooltip=\"no tooltip\">{{ range.controls.end.value.toLocaleString(DateTime.DATE_SHORT) }}\n </th>\n <td class=\"recent-data-cell\" mat-cell *matCellDef=\"let row\">\n <a [attr.href]=\"openInEditor(row.meta.id, col.id) | async\" target=\"editor_frontend\">{{ row.counts[col.id] ?? '\u2013' }}</a>\n </td>\n </ng-container>\n <!-- one column for each type for the older date-->\n <ng-container *ngFor=\"let col of (recentTypeCount$ | async)?.columns; trackBy:columnIdent\"\n [matColumnDef]=\"col.id + '_past'\">\n <th class=\"past-data-cell\" mat-header-cell *matHeaderCellDef matTooltip=\"no tooltip\">\n {{ (pastTypeCount$ | async)?.rows?.length ? range.controls.start.value.toLocaleString(DateTime.DATE_SHORT) : 'no past data' }}\n </th>\n <td class=\"past-data-cell\" mat-cell *matCellDef=\"let row;\" >\n <ng-container *ngIf=\"(pastTypeCount$ | async)?.rows?.length && pastTypeCount(row, col.id) as trend\">\n <span [class]=\"trend.trend\"> {{ trend.value ?? '\u2013' }}\n <mat-icon *ngIf=\"trend.value\" aria-hidden=\"false\" [attr.aria-label]=\"trend.trend\" [fontIcon]=\"trend.trend!\" /></span>\n <span class=\"cdk-visually-hidden\">{{ trend.trend }}</span>\n </ng-container>\n </td>\n </ng-container>\n <!-- generate actual table -->\n <tr mat-header-row *matHeaderRowDef=\"['label-col'].concat(typeColumns()); sticky:true;\"></tr>\n <tr [hidden]=\"!isHistoryEnabled()\" mat-header-row *matHeaderRowDef=\"allColumns(); sticky: true;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: ['label-col'].concat(allColumns())\"></tr>\n\n </table>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}tr:nth-child(2n){background-color:#e4e4e4}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell{border-right:1px solid white}tr:nth-child(odd){background-color:#fff}tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}td.label-col{text-align:left}.mat-mdc-header-cell,.mat-mdc-cell{text-align:center}.mat-mdc-header-cell a[href],.mat-mdc-cell a[href]{color:var(--mat-table-row-item-label-text-color);cursor:pointer;text-decoration:underline}.mat-mdc-header-cell a[href]:hover,.mat-mdc-cell a[href]:hover{text-decoration:underline}.mat-mdc-header-cell mat-icon,.mat-mdc-cell mat-icon{margin-left:5px;vertical-align:middle}.trending_down{color:#4abeff}.trending_up{color:#c20808}.toolbar,.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}\n", ".while-loading{filter:blur(2px)}tr:nth-child(2n),tr:nth-child(odd){background-color:#fff}tr:nth-child(2n)>td.label-col,tr:nth-child(2n) td.recent-data-cell,tr:nth-child(odd)>td.label-col,tr:nth-child(odd) td.recent-data-cell{border-right:1px solid #e4e4e4}.mat-cell-level-1{padding-left:20px!important;text-align:left}.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2{padding-left:40px!important;text-align:left}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-3{padding-left:60px!important;text-align:left}.mat-cell-level-3:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-4{padding-left:80px!important;text-align:left}.mat-cell-level-4:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-5{padding-left:100px!important;text-align:left}.mat-cell-level-5:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-6{padding-left:120px!important;text-align:left}.mat-cell-level-6:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-7{padding-left:140px!important;text-align:left}.mat-cell-level-7:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-8{padding-left:160px!important;text-align:left}.mat-cell-level-8:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+);padding-right:5px}.mat-cell-level-2:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuMyA5LjkwMDA1QzIwLjIgOS43MDAwNSAyMC4xIDkuNjAwMDUgMjAgOS40MDAwNUwxMyAzLjMwMDA1QzEyLjUgMi44MDAwNSAxMS41IDIuODAwMDUgMTEgMy4zMDAwNUw0IDkuNDAwMDVDMy41IDkuOTAwMDUgMy41IDEwLjcgNCAxMS4xTDExIDE3LjJDMTEuNSAxNy43IDEyLjUgMTcuNyAxMyAxNy4yTDIwIDExLjFDMjAuMyAxMC44IDIwLjQgMTAuNSAyMC40IDEwLjJDMjAuNCAxMC4xIDIwLjQgMTAgMjAuMyA5LjkwMDA1Wk01IDEwLjNMMTIgNC4yMDAwNUwxOSAxMC4zTDEyIDE2LjRMNSAxMC4zWk0yMCAxMi45TDEyIDE5LjhMNCAxMi45TDMgMTMuOEwxMSAyMC43MDAxQzExLjUgMjEuMjAwMSAxMi41IDIxLjIwMDEgMTMgMjAuNzAwMUwyMSAxMy44TDIwIDEyLjlaIiBmaWxsPSIjMDAzQjdDIi8+PHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkgMTAuM0wxMiAxNi4zTDUgMTAuM0wxMiA0LjE5OTk1TDE5IDEwLjNaIiBmaWxsPSIjMDAzQjdDIi8+PC9zdmc+)}.mat-cell-level-0:before,.mat-cell-level-1:before{content:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNCAxMi45TDMgMTMuOEwxMSAyMC43QzExLjYgMjEuMiAxMi40IDIxLjIgMTMgMjAuN0wyMSAxMy44TDIwIDEyLjlMMTIgMTkuOEw0IDEyLjlaTTExIDMuNDAwMDJMNCA5LjQwMDAyQzMuNCA5LjkwMDAyIDMuNCAxMC43IDQgMTEuMUwxMSAxNy4yQzExLjYgMTcuNyAxMi40IDE3LjcgMTMgMTcuMkwyMCAxMS4xQzIwLjUgMTAuNiAyMC41IDkuODAwMDIgMjAgOS40MDAwMkwxMyAzLjMwMDAyQzEyLjQgMi45MDAwMiAxMS42IDIuOTAwMDIgMTEgMy40MDAwMloiIGZpbGw9IiMwMDNCN0MiLz48L3N2Zz4=)}.trending_down{color:#4abeff}.trending_up{color:#c20808}\n"] }]
|
|
3950
3995
|
}], propDecorators: { collectionId: [{
|
|
3951
3996
|
type: Input,
|
|
3952
3997
|
args: [{ required: true }]
|
|
3953
3998
|
}], sourceType: [{
|
|
3954
3999
|
type: Input,
|
|
3955
4000
|
args: [{ required: false }]
|
|
3956
|
-
}], apiMethod: [{
|
|
3957
|
-
type: Input,
|
|
3958
|
-
args: [{ required: false }]
|
|
3959
4001
|
}] } });
|
|
3960
4002
|
|
|
3961
4003
|
/*
|
|
@@ -3966,5 +4008,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3966
4008
|
* Generated bundle index. Do not edit.
|
|
3967
4009
|
*/
|
|
3968
4010
|
|
|
3969
|
-
export { CollectionCountHistoryComponent, CollectionIssuesComponent, ConfigHelperService, CountsWithHistoryComponent, DonutChartTooltipComponent, MaterialIssuesComponent, NG_META_WIDGETS_LIB_CONFIGURATION, NgMetaWidgetsLibConfiguration, NgMetaWidgetsLibModule, NodeListComponent, QualityMatrixComponent, TOOLTIP_DATA, TOOLTIP_REF, TooltipRefImpl, TooltipService, TreeCollectionDetailsComponent, TreeLicenseComponent, TreeSearchCountsComponent, borderPositionStrategy, centerPositionStrategy, createRegister, transformDonutChartData };
|
|
4011
|
+
export { BaseHistoricDataTableDirective, CollectionCountHistoryComponent, CollectionIssuesComponent, ConfigHelperService, CountsWithHistoryComponent, DonutChartTooltipComponent, MaterialIssuesComponent, NG_META_WIDGETS_LIB_CONFIGURATION, NgMetaWidgetsLibConfiguration, NgMetaWidgetsLibModule, NodeListComponent, QualityMatrixComponent, TOOLTIP_DATA, TOOLTIP_REF, TooltipRefImpl, TooltipService, TreeCollectionDetailsComponent, TreeLicenseComponent, TreeSearchCountsComponent, borderPositionStrategy, centerPositionStrategy, createRegister, transformDonutChartData };
|
|
3970
4012
|
//# sourceMappingURL=ngx-edu-sharing-metaqs2.mjs.map
|