ngx-edu-sharing-metaqs2 0.9.33 → 0.9.35

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.
Files changed (52) hide show
  1. package/README.md +31 -0
  2. package/_index.scss +8 -0
  3. package/esm2022/lib/collection-count-history/collection-count-history.component.mjs +3 -3
  4. package/esm2022/lib/components/donut-chart/donut-chart.component.mjs +6 -6
  5. package/esm2022/lib/components/donut-chart/donut-chart.model.mjs +1 -1
  6. package/esm2022/lib/components/donut-chart/donut-chart.pipe.mjs +6 -5
  7. package/esm2022/lib/components/donut-chart-tooltip/donut-chart-tooltip.component.mjs +79 -0
  8. package/esm2022/lib/components/filter/datepicker/datepicker.component.mjs +3 -8
  9. package/esm2022/lib/components/node-list/node-list.component.mjs +13 -9
  10. package/esm2022/lib/components/quality-matrix/quality_matrix.mjs +195 -36
  11. package/esm2022/lib/components/quality-matrix/scroll-marker.directive.mjs +17 -0
  12. package/esm2022/lib/config-helper.service.mjs +5 -4
  13. package/esm2022/lib/core/tooltip.service.mjs +146 -0
  14. package/esm2022/lib/counts-with-history/counts-with-history.component.mjs +4 -4
  15. package/esm2022/lib/java-api/api/authProxyController.service.mjs +12 -93
  16. package/esm2022/lib/java-api/api/collectionAPI.service.mjs +91 -178
  17. package/esm2022/lib/java-api/api/editorsAPI.service.mjs +14 -102
  18. package/esm2022/lib/java-api/api/filterAPI.service.mjs +50 -129
  19. package/esm2022/lib/java-api/api/replicationSourceAPI.service.mjs +20 -130
  20. package/esm2022/lib/java-api/api.base.service.mjs +66 -0
  21. package/esm2022/lib/java-api/configuration.mjs +9 -1
  22. package/esm2022/lib/java-api/model/missingAttributeResult.mjs +2 -0
  23. package/esm2022/lib/java-api/model/models.mjs +2 -1
  24. package/esm2022/lib/ng-meta-widgets-lib.module.mjs +18 -11
  25. package/esm2022/lib/tree-collection-details/tree-collection-details.component.mjs +3 -7
  26. package/esm2022/lib/tree-search-counts/tree-search-counts.component.mjs +4 -6
  27. package/esm2022/public-api.mjs +6 -3
  28. package/esm2022/web-components.mjs +36 -0
  29. package/fesm2022/ngx-edu-sharing-metaqs2.mjs +1051 -1003
  30. package/fesm2022/ngx-edu-sharing-metaqs2.mjs.map +1 -1
  31. package/lib/components/donut-chart/donut-chart.component.d.ts +1 -1
  32. package/lib/components/donut-chart/donut-chart.model.d.ts +1 -0
  33. package/lib/components/donut-chart/donut-chart.pipe.d.ts +1 -1
  34. package/lib/components/donut-chart-tooltip/donut-chart-tooltip.component.d.ts +14 -0
  35. package/lib/components/node-list/node-list.component.d.ts +9 -5
  36. package/lib/components/quality-matrix/quality_matrix.d.ts +25 -6
  37. package/lib/components/quality-matrix/scroll-marker.directive.d.ts +7 -0
  38. package/lib/config-helper.service.d.ts +2 -0
  39. package/lib/core/tooltip.service.d.ts +61 -0
  40. package/lib/java-api/api/authProxyController.service.d.ts +4 -9
  41. package/lib/java-api/api/collectionAPI.service.d.ts +47 -25
  42. package/lib/java-api/api/editorsAPI.service.d.ts +5 -10
  43. package/lib/java-api/api/filterAPI.service.d.ts +27 -9
  44. package/lib/java-api/api/replicationSourceAPI.service.d.ts +4 -9
  45. package/lib/java-api/api.base.service.d.ts +12 -0
  46. package/lib/java-api/configuration.d.ts +3 -1
  47. package/lib/java-api/model/missingAttributeResult.d.ts +16 -0
  48. package/lib/java-api/model/models.d.ts +1 -0
  49. package/lib/ng-meta-widgets-lib.module.d.ts +34 -32
  50. package/package.json +4 -1
  51. package/public-api.d.ts +5 -2
  52. package/web-components.d.ts +7 -0
@@ -1,21 +1,20 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Pipe, Component, Input, Output, inject, LOCALE_ID, ViewChild, ChangeDetectionStrategy, signal, EventEmitter, effect, computed } from '@angular/core';
2
+ import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Pipe, Component, Input, Output, inject, Renderer2, Injector, ChangeDetectionStrategy, HostBinding, LOCALE_ID, ViewChild, ElementRef, Directive, signal, computed, viewChild, viewChildren, HostListener, EventEmitter, effect, enableProdMode, importProvidersFrom } from '@angular/core';
3
3
  import * as i3$1 from '@angular/material/card';
4
- import { MatCard, MatCardContent, MatCardHeader, MatCardTitle, MatCardModule } from '@angular/material/card';
4
+ import { MatCard, MatCardHeader, MatCardTitle, MatCardContent, MatCardModule } from '@angular/material/card';
5
5
  import { MatTreeModule } from '@angular/material/tree';
6
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
6
+ import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations';
7
7
  import * as i1$4 from '@angular/material/icon';
8
- import { MatIconModule, MatIcon } from '@angular/material/icon';
8
+ import { MatIcon, MatIconModule } from '@angular/material/icon';
9
9
  import * as i5 from '@angular/material/slider';
10
10
  import { MatSliderModule } from '@angular/material/slider';
11
- import * as i6 from '@angular/material/slide-toggle';
12
- import { MatSlideToggleModule, MatSlideToggle } from '@angular/material/slide-toggle';
13
- import * as i6$1 from '@angular/material/button';
14
- import { MatButtonModule } from '@angular/material/button';
15
- import * as i2$1 from '@angular/material/progress-spinner';
16
- import { MatProgressSpinnerModule, MatProgressSpinner } from '@angular/material/progress-spinner';
11
+ import { MatSlideToggle, MatSlideToggleModule } from '@angular/material/slide-toggle';
12
+ import * as i6 from '@angular/material/button';
13
+ import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
14
+ import * as i2$2 from '@angular/material/progress-spinner';
15
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
17
16
  import * as i4 from '@angular/material/table';
18
- import { MatTableModule, MatTable, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef } from '@angular/material/table';
17
+ import { MatTable, MatCell, MatColumnDef, MatHeaderCell, MatHeaderRow, MatRow, MatHeaderRowDef, MatRowDef, MatHeaderCellDef, MatCellDef, MatTableModule } from '@angular/material/table';
19
18
  import { MatGridListModule } from '@angular/material/grid-list';
20
19
  import * as i1$1 from '@angular/material/form-field';
21
20
  import { MatFormFieldModule, MatFormField, MatLabel, MatSuffix } from '@angular/material/form-field';
@@ -25,30 +24,41 @@ import * as i1$2 from '@angular/forms';
25
24
  import { FormControl, ReactiveFormsModule, FormsModule, FormGroup, FormRecord } from '@angular/forms';
26
25
  import * as i2 from '@angular/material/select';
27
26
  import { MatSelectModule } from '@angular/material/select';
28
- import * as i10 from '@angular/material/tooltip';
29
- import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
27
+ import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
30
28
  import * as i1 from '@angular/common/http';
31
- import { HttpHeaders, HttpContext, HttpParams, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
29
+ import { HttpHeaders, HttpContext, HttpParams, provideHttpClient, withInterceptorsFromDi, HttpClient } from '@angular/common/http';
32
30
  import { pipe, of, BehaviorSubject, forkJoin, Subject, zip } from 'rxjs';
33
31
  import { map, catchError, startWith, take, filter, tap, finalize, takeUntil, shareReplay, distinctUntilChanged, switchMap, skipWhile } from 'rxjs/operators';
34
32
  import * as i2$4 from '@angular/platform-browser';
35
- import { BrowserModule } from '@angular/platform-browser';
33
+ import { BrowserModule, createApplication } from '@angular/platform-browser';
36
34
  import { MatListModule } from '@angular/material/list';
37
35
  import { MatSort, MatSortModule } from '@angular/material/sort';
38
36
  import { MatCheckbox } from '@angular/material/checkbox';
39
- import * as i2$2 from '@angular/common';
40
- import { NgForOf, AsyncPipe, NgClass, NgIf, DOCUMENT } from '@angular/common';
37
+ import * as i2$1 from '@angular/common';
38
+ import { NgForOf, NgIf, KeyValuePipe, NgClass, AsyncPipe, DOCUMENT } from '@angular/common';
41
39
  import * as i3 from '@angular/material/core';
42
40
  import { DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS } from '@angular/material/core';
43
41
  import * as i2$3 from '@ngx-translate/core';
44
- import { TranslateModule } from '@ngx-translate/core';
42
+ import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
45
43
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
46
44
  import { DateTime } from 'luxon';
45
+ import * as i1$3 from '@angular/cdk/overlay';
46
+ import { Overlay, OverlayRef } from '@angular/cdk/overlay';
47
+ import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
48
+ import { trigger, transition, style, animate } from '@angular/animations';
47
49
  import { MatDatepicker, MatDatepickerInput, MatDatepickerToggle, MatDateRangeInput, MatDatepickerModule, MatDateRangePicker } from '@angular/material/datepicker';
48
50
  import { LuxonDateAdapter, MAT_LUXON_DATE_ADAPTER_OPTIONS } from '@angular/material-luxon-adapter';
49
- import { TemplatePortal } from '@angular/cdk/portal';
50
- import * as i1$3 from '@angular/cdk/overlay';
51
51
  import { provideCharts, withDefaultRegisterables, BaseChartDirective } from 'ng2-charts';
52
+ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
53
+ import { createCustomElement } from '@angular/elements';
54
+
55
+ const BASE_PATH = new InjectionToken('basePath');
56
+ const COLLECTION_FORMATS = {
57
+ 'csv': ',',
58
+ 'tsv': ' ',
59
+ 'ssv': ' ',
60
+ 'pipes': '|'
61
+ };
52
62
 
53
63
  /**
54
64
  * Custom HttpParameterCodec
@@ -69,14 +79,6 @@ class CustomHttpParameterCodec {
69
79
  }
70
80
  }
71
81
 
72
- const BASE_PATH = new InjectionToken('basePath');
73
- const COLLECTION_FORMATS = {
74
- 'csv': ',',
75
- 'tsv': ' ',
76
- 'ssv': ' ',
77
- 'pipes': '|'
78
- };
79
-
80
82
  class Configuration {
81
83
  constructor(configurationParameters = {}) {
82
84
  this.apiKeys = configurationParameters.apiKeys;
@@ -157,6 +159,14 @@ class Configuration {
157
159
  const value = this.credentials[key];
158
160
  return typeof value === 'function' ? value() : value;
159
161
  }
162
+ addCredentialToHeaders(credentialKey, headerName, headers, prefix) {
163
+ const value = this.lookupCredential(credentialKey);
164
+ return value ? headers.set(headerName, (prefix ?? '') + value) : headers;
165
+ }
166
+ addCredentialToQuery(credentialKey, paramName, query) {
167
+ const value = this.lookupCredential(credentialKey);
168
+ return value ? query.set(paramName, value) : query;
169
+ }
160
170
  defaultEncodeParam(param) {
161
171
  // This implementation exists as fallback for missing configuration
162
172
  // and for backwards compatibility to older typescript-angular generator versions.
@@ -172,25 +182,11 @@ class Configuration {
172
182
  }
173
183
  }
174
184
 
175
- /**
176
- * OpenAPI definition
177
- *
178
- *
179
- *
180
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
181
- * https://openapi-generator.tech
182
- * Do not edit the class manually.
183
- */
184
- /* tslint:disable:no-unused-variable member-ordering */
185
- class AuthProxyControllerService {
186
- constructor(httpClient, basePath, configuration) {
187
- this.httpClient = httpClient;
188
- this.basePath = 'https://repository.staging.openeduhub.net/edu-sharing/services/metaqs-2';
185
+ class BaseService {
186
+ constructor(basePath, configuration) {
187
+ this.basePath = '';
189
188
  this.defaultHeaders = new HttpHeaders();
190
- this.configuration = new Configuration();
191
- if (configuration) {
192
- this.configuration = configuration;
193
- }
189
+ this.configuration = configuration || new Configuration();
194
190
  if (typeof this.configuration.basePath !== 'string') {
195
191
  const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
196
192
  if (firstBasePath != undefined) {
@@ -203,63 +199,75 @@ class AuthProxyControllerService {
203
199
  }
204
200
  this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
205
201
  }
206
- // @ts-ignore
202
+ canConsumeForm(consumes) {
203
+ return consumes.indexOf('multipart/form-data') !== -1;
204
+ }
207
205
  addToHttpParams(httpParams, value, key) {
208
- if (typeof value === 'object' && value instanceof Date === false) {
209
- httpParams = this.addToHttpParamsRecursive(httpParams, value);
210
- }
211
- else {
212
- httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
206
+ // If the value is an object (but not a Date), recursively add its keys.
207
+ if (typeof value === 'object' && !(value instanceof Date)) {
208
+ return this.addToHttpParamsRecursive(httpParams, value, key);
213
209
  }
214
- return httpParams;
210
+ return this.addToHttpParamsRecursive(httpParams, value, key);
215
211
  }
216
212
  addToHttpParamsRecursive(httpParams, value, key) {
217
- if (value == null) {
213
+ if (value === null || value === undefined) {
218
214
  return httpParams;
219
215
  }
220
216
  if (typeof value === 'object') {
217
+ // If JSON format is preferred, key must be provided.
218
+ if (key != null) {
219
+ return httpParams.append(key, JSON.stringify(value));
220
+ }
221
+ // Otherwise, if it's an array, add each element.
221
222
  if (Array.isArray(value)) {
222
223
  value.forEach((elem) => (httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)));
223
224
  }
224
225
  else if (value instanceof Date) {
225
226
  if (key != null) {
226
- httpParams = httpParams.append(key, value.toISOString().substring(0, 10));
227
+ httpParams = httpParams.append(key, value.toISOString());
227
228
  }
228
229
  else {
229
230
  throw Error('key may not be null if value is Date');
230
231
  }
231
232
  }
232
233
  else {
233
- Object.keys(value).forEach((k) => (httpParams = this.addToHttpParamsRecursive(httpParams, value[k], key != null ? `${key}.${k}` : k)));
234
+ Object.keys(value).forEach((k) => {
235
+ const paramKey = key ? `${key}.${k}` : k;
236
+ httpParams = this.addToHttpParamsRecursive(httpParams, value[k], paramKey);
237
+ });
234
238
  }
239
+ return httpParams;
235
240
  }
236
241
  else if (key != null) {
237
- httpParams = httpParams.append(key, value);
238
- }
239
- else {
240
- throw Error('key may not be null if value is not object or array');
242
+ return httpParams.append(key, value);
241
243
  }
242
- return httpParams;
244
+ throw Error('key may not be null if value is not object or array');
245
+ }
246
+ }
247
+
248
+ /**
249
+ * OpenAPI definition
250
+ *
251
+ *
252
+ *
253
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
254
+ * https://openapi-generator.tech
255
+ * Do not edit the class manually.
256
+ */
257
+ /* tslint:disable:no-unused-variable member-ordering */
258
+ class AuthProxyControllerService extends BaseService {
259
+ constructor(httpClient, basePath, configuration) {
260
+ super(basePath, configuration);
261
+ this.httpClient = httpClient;
243
262
  }
244
263
  destroySession(jSESSIONID, observe = 'body', reportProgress = false, options) {
245
264
  let localVarHeaders = this.defaultHeaders;
246
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
247
- if (localVarHttpHeaderAcceptSelected === undefined) {
248
- // to determine the Accept header
249
- const httpHeaderAccepts = [];
250
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
251
- }
265
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([]);
252
266
  if (localVarHttpHeaderAcceptSelected !== undefined) {
253
267
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
254
268
  }
255
- let localVarHttpContext = options && options.context;
256
- if (localVarHttpContext === undefined) {
257
- localVarHttpContext = new HttpContext();
258
- }
259
- let localVarTransferCache = options && options.transferCache;
260
- if (localVarTransferCache === undefined) {
261
- localVarTransferCache = true;
262
- }
269
+ const localVarHttpContext = options?.context ?? new HttpContext();
270
+ const localVarTransferCache = options?.transferCache ?? true;
263
271
  let responseType_ = 'json';
264
272
  if (localVarHttpHeaderAcceptSelected) {
265
273
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -288,29 +296,14 @@ class AuthProxyControllerService {
288
296
  if (authorization !== undefined && authorization !== null) {
289
297
  localVarHeaders = localVarHeaders.set('Authorization', String(authorization));
290
298
  }
291
- let localVarCredential;
292
299
  // authentication (basicAuth) required
293
- localVarCredential = this.configuration.lookupCredential('basicAuth');
294
- if (localVarCredential) {
295
- localVarHeaders = localVarHeaders.set('Authorization', 'Basic ' + localVarCredential);
296
- }
297
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
298
- if (localVarHttpHeaderAcceptSelected === undefined) {
299
- // to determine the Accept header
300
- const httpHeaderAccepts = ['application/json'];
301
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
302
- }
300
+ localVarHeaders = this.configuration.addCredentialToHeaders('basicAuth', 'Authorization', localVarHeaders, 'Basic ');
301
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
303
302
  if (localVarHttpHeaderAcceptSelected !== undefined) {
304
303
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
305
304
  }
306
- let localVarHttpContext = options && options.context;
307
- if (localVarHttpContext === undefined) {
308
- localVarHttpContext = new HttpContext();
309
- }
310
- let localVarTransferCache = options && options.transferCache;
311
- if (localVarTransferCache === undefined) {
312
- localVarTransferCache = true;
313
- }
305
+ const localVarHttpContext = options?.context ?? new HttpContext();
306
+ const localVarTransferCache = options?.transferCache ?? true;
314
307
  let responseType_ = 'json';
315
308
  if (localVarHttpHeaderAcceptSelected) {
316
309
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -361,90 +354,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
361
354
  * Do not edit the class manually.
362
355
  */
363
356
  /* tslint:disable:no-unused-variable member-ordering */
364
- class CollectionAPIService {
357
+ class CollectionAPIService extends BaseService {
365
358
  constructor(httpClient, basePath, configuration) {
359
+ super(basePath, configuration);
366
360
  this.httpClient = httpClient;
367
- this.basePath = 'https://repository.staging.openeduhub.net/edu-sharing/services/metaqs-2';
368
- this.defaultHeaders = new HttpHeaders();
369
- this.configuration = new Configuration();
370
- if (configuration) {
371
- this.configuration = configuration;
372
- }
373
- if (typeof this.configuration.basePath !== 'string') {
374
- const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
375
- if (firstBasePath != undefined) {
376
- basePath = firstBasePath;
377
- }
378
- if (typeof basePath !== 'string') {
379
- basePath = this.basePath;
380
- }
381
- this.configuration.basePath = basePath;
382
- }
383
- this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
384
- }
385
- // @ts-ignore
386
- addToHttpParams(httpParams, value, key) {
387
- if (typeof value === 'object' && value instanceof Date === false) {
388
- httpParams = this.addToHttpParamsRecursive(httpParams, value);
389
- }
390
- else {
391
- httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
392
- }
393
- return httpParams;
394
- }
395
- addToHttpParamsRecursive(httpParams, value, key) {
396
- if (value == null) {
397
- return httpParams;
398
- }
399
- if (typeof value === 'object') {
400
- if (Array.isArray(value)) {
401
- value.forEach((elem) => (httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)));
402
- }
403
- else if (value instanceof Date) {
404
- if (key != null) {
405
- httpParams = httpParams.append(key, value.toISOString().substring(0, 10));
406
- }
407
- else {
408
- throw Error('key may not be null if value is Date');
409
- }
410
- }
411
- else {
412
- Object.keys(value).forEach((k) => (httpParams = this.addToHttpParamsRecursive(httpParams, value[k], key != null ? `${key}.${k}` : k)));
413
- }
414
- }
415
- else if (key != null) {
416
- httpParams = httpParams.append(key, value);
417
- }
418
- else {
419
- throw Error('key may not be null if value is not object or array');
420
- }
421
- return httpParams;
422
361
  }
423
- getCollectionsWithMissingAttribute(collectionId, missingAttr, observe = 'body', reportProgress = false, options) {
362
+ getCollectionsWithMissingAttribute(collectionId, missingAttr, from, size, observe = 'body', reportProgress = false, options) {
424
363
  if (collectionId === null || collectionId === undefined) {
425
364
  throw new Error('Required parameter collectionId was null or undefined when calling getCollectionsWithMissingAttribute.');
426
365
  }
427
366
  if (missingAttr === null || missingAttr === undefined) {
428
367
  throw new Error('Required parameter missingAttr was null or undefined when calling getCollectionsWithMissingAttribute.');
429
368
  }
369
+ let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
370
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, from, 'from');
371
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, size, 'size');
430
372
  let localVarHeaders = this.defaultHeaders;
431
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
432
- if (localVarHttpHeaderAcceptSelected === undefined) {
433
- // to determine the Accept header
434
- const httpHeaderAccepts = ['application/json'];
435
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
436
- }
373
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
437
374
  if (localVarHttpHeaderAcceptSelected !== undefined) {
438
375
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
439
376
  }
440
- let localVarHttpContext = options && options.context;
441
- if (localVarHttpContext === undefined) {
442
- localVarHttpContext = new HttpContext();
443
- }
444
- let localVarTransferCache = options && options.transferCache;
445
- if (localVarTransferCache === undefined) {
446
- localVarTransferCache = true;
447
- }
377
+ const localVarHttpContext = options?.context ?? new HttpContext();
378
+ const localVarTransferCache = options?.transferCache ?? true;
448
379
  let responseType_ = 'json';
449
380
  if (localVarHttpHeaderAcceptSelected) {
450
381
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -476,6 +407,7 @@ class CollectionAPIService {
476
407
  })}`;
477
408
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
478
409
  context: localVarHttpContext,
410
+ params: localVarQueryParameters,
479
411
  responseType: responseType_,
480
412
  withCredentials: this.configuration.withCredentials,
481
413
  headers: localVarHeaders,
@@ -489,23 +421,12 @@ class CollectionAPIService {
489
421
  throw new Error('Required parameter collectionId was null or undefined when calling getCompleteness.');
490
422
  }
491
423
  let localVarHeaders = this.defaultHeaders;
492
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
493
- if (localVarHttpHeaderAcceptSelected === undefined) {
494
- // to determine the Accept header
495
- const httpHeaderAccepts = ['application/json'];
496
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
497
- }
424
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
498
425
  if (localVarHttpHeaderAcceptSelected !== undefined) {
499
426
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
500
427
  }
501
- let localVarHttpContext = options && options.context;
502
- if (localVarHttpContext === undefined) {
503
- localVarHttpContext = new HttpContext();
504
- }
505
- let localVarTransferCache = options && options.transferCache;
506
- if (localVarTransferCache === undefined) {
507
- localVarTransferCache = true;
508
- }
428
+ const localVarHttpContext = options?.context ?? new HttpContext();
429
+ const localVarTransferCache = options?.transferCache ?? true;
509
430
  let responseType_ = 'json';
510
431
  if (localVarHttpHeaderAcceptSelected) {
511
432
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -542,33 +463,16 @@ class CollectionAPIService {
542
463
  throw new Error('Required parameter term was null or undefined when calling getCountBySearchTerm.');
543
464
  }
544
465
  let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
545
- if (term !== undefined && term !== null) {
546
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, term, 'term');
547
- }
548
- if (oerOnly !== undefined && oerOnly !== null) {
549
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
550
- }
551
- if (type !== undefined && type !== null) {
552
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, type, 'type');
553
- }
466
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, term, 'term');
467
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
468
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, type, 'type');
554
469
  let localVarHeaders = this.defaultHeaders;
555
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
556
- if (localVarHttpHeaderAcceptSelected === undefined) {
557
- // to determine the Accept header
558
- const httpHeaderAccepts = ['application/json'];
559
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
560
- }
470
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
561
471
  if (localVarHttpHeaderAcceptSelected !== undefined) {
562
472
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
563
473
  }
564
- let localVarHttpContext = options && options.context;
565
- if (localVarHttpContext === undefined) {
566
- localVarHttpContext = new HttpContext();
567
- }
568
- let localVarTransferCache = options && options.transferCache;
569
- if (localVarTransferCache === undefined) {
570
- localVarTransferCache = true;
571
- }
474
+ const localVarHttpContext = options?.context ?? new HttpContext();
475
+ const localVarTransferCache = options?.transferCache ?? true;
572
476
  let responseType_ = 'json';
573
477
  if (localVarHttpHeaderAcceptSelected) {
574
478
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -598,30 +502,15 @@ class CollectionAPIService {
598
502
  throw new Error('Required parameter term was null or undefined when calling getCountBySearchTermAggregatedByType.');
599
503
  }
600
504
  let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
601
- if (term !== undefined && term !== null) {
602
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, term, 'term');
603
- }
604
- if (oerOnly !== undefined && oerOnly !== null) {
605
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
606
- }
505
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, term, 'term');
506
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
607
507
  let localVarHeaders = this.defaultHeaders;
608
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
609
- if (localVarHttpHeaderAcceptSelected === undefined) {
610
- // to determine the Accept header
611
- const httpHeaderAccepts = ['application/json'];
612
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
613
- }
508
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
614
509
  if (localVarHttpHeaderAcceptSelected !== undefined) {
615
510
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
616
511
  }
617
- let localVarHttpContext = options && options.context;
618
- if (localVarHttpContext === undefined) {
619
- localVarHttpContext = new HttpContext();
620
- }
621
- let localVarTransferCache = options && options.transferCache;
622
- if (localVarTransferCache === undefined) {
623
- localVarTransferCache = true;
624
- }
512
+ const localVarHttpContext = options?.context ?? new HttpContext();
513
+ const localVarTransferCache = options?.transferCache ?? true;
625
514
  let responseType_ = 'json';
626
515
  if (localVarHttpHeaderAcceptSelected) {
627
516
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -646,32 +535,68 @@ class CollectionAPIService {
646
535
  reportProgress: reportProgress,
647
536
  });
648
537
  }
538
+ getMaterialCountMatrixByLicenseGroup1(collectionId, filter, observe = 'body', reportProgress = false, options) {
539
+ if (collectionId === null || collectionId === undefined) {
540
+ throw new Error('Required parameter collectionId was null or undefined when calling getMaterialCountMatrixByLicenseGroup1.');
541
+ }
542
+ let localVarHeaders = this.defaultHeaders;
543
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
544
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
545
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
546
+ }
547
+ const localVarHttpContext = options?.context ?? new HttpContext();
548
+ const localVarTransferCache = options?.transferCache ?? true;
549
+ // to determine the Content-Type header
550
+ const consumes = ['application/json'];
551
+ const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
552
+ if (httpContentTypeSelected !== undefined) {
553
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
554
+ }
555
+ let responseType_ = 'json';
556
+ if (localVarHttpHeaderAcceptSelected) {
557
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
558
+ responseType_ = 'text';
559
+ }
560
+ else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
561
+ responseType_ = 'json';
562
+ }
563
+ else {
564
+ responseType_ = 'blob';
565
+ }
566
+ }
567
+ let localVarPath = `/collections/${this.configuration.encodeParam({
568
+ name: 'collectionId',
569
+ value: collectionId,
570
+ in: 'path',
571
+ style: 'simple',
572
+ explode: false,
573
+ dataType: 'string',
574
+ dataFormat: undefined,
575
+ })}/licenses/materialCount`;
576
+ return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, {
577
+ context: localVarHttpContext,
578
+ body: filter,
579
+ responseType: responseType_,
580
+ withCredentials: this.configuration.withCredentials,
581
+ headers: localVarHeaders,
582
+ observe: observe,
583
+ transferCache: localVarTransferCache,
584
+ reportProgress: reportProgress,
585
+ });
586
+ }
649
587
  getMaterialCountMatrixPerCollection(collectionId, oerOnly, observe = 'body', reportProgress = false, options) {
650
588
  if (collectionId === null || collectionId === undefined) {
651
589
  throw new Error('Required parameter collectionId was null or undefined when calling getMaterialCountMatrixPerCollection.');
652
590
  }
653
591
  let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
654
- if (oerOnly !== undefined && oerOnly !== null) {
655
- localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
656
- }
592
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, oerOnly, 'oerOnly');
657
593
  let localVarHeaders = this.defaultHeaders;
658
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
659
- if (localVarHttpHeaderAcceptSelected === undefined) {
660
- // to determine the Accept header
661
- const httpHeaderAccepts = ['application/json'];
662
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
663
- }
594
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
664
595
  if (localVarHttpHeaderAcceptSelected !== undefined) {
665
596
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
666
597
  }
667
- let localVarHttpContext = options && options.context;
668
- if (localVarHttpContext === undefined) {
669
- localVarHttpContext = new HttpContext();
670
- }
671
- let localVarTransferCache = options && options.transferCache;
672
- if (localVarTransferCache === undefined) {
673
- localVarTransferCache = true;
674
- }
598
+ const localVarHttpContext = options?.context ?? new HttpContext();
599
+ const localVarTransferCache = options?.transferCache ?? true;
675
600
  let responseType_ = 'json';
676
601
  if (localVarHttpHeaderAcceptSelected) {
677
602
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -704,31 +629,23 @@ class CollectionAPIService {
704
629
  reportProgress: reportProgress,
705
630
  });
706
631
  }
707
- getMaterialsWithMissingAttribute(nodeId, missingAttr, observe = 'body', reportProgress = false, options) {
632
+ getMaterialsWithMissingAttribute(nodeId, missingAttr, from, size, observe = 'body', reportProgress = false, options) {
708
633
  if (nodeId === null || nodeId === undefined) {
709
634
  throw new Error('Required parameter nodeId was null or undefined when calling getMaterialsWithMissingAttribute.');
710
635
  }
711
636
  if (missingAttr === null || missingAttr === undefined) {
712
637
  throw new Error('Required parameter missingAttr was null or undefined when calling getMaterialsWithMissingAttribute.');
713
638
  }
639
+ let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
640
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, from, 'from');
641
+ localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, size, 'size');
714
642
  let localVarHeaders = this.defaultHeaders;
715
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
716
- if (localVarHttpHeaderAcceptSelected === undefined) {
717
- // to determine the Accept header
718
- const httpHeaderAccepts = ['application/json'];
719
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
720
- }
643
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
721
644
  if (localVarHttpHeaderAcceptSelected !== undefined) {
722
645
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
723
646
  }
724
- let localVarHttpContext = options && options.context;
725
- if (localVarHttpContext === undefined) {
726
- localVarHttpContext = new HttpContext();
727
- }
728
- let localVarTransferCache = options && options.transferCache;
729
- if (localVarTransferCache === undefined) {
730
- localVarTransferCache = true;
731
- }
647
+ const localVarHttpContext = options?.context ?? new HttpContext();
648
+ const localVarTransferCache = options?.transferCache ?? true;
732
649
  let responseType_ = 'json';
733
650
  if (localVarHttpHeaderAcceptSelected) {
734
651
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -760,6 +677,7 @@ class CollectionAPIService {
760
677
  })}`;
761
678
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
762
679
  context: localVarHttpContext,
680
+ params: localVarQueryParameters,
763
681
  responseType: responseType_,
764
682
  withCredentials: this.configuration.withCredentials,
765
683
  headers: localVarHeaders,
@@ -770,23 +688,12 @@ class CollectionAPIService {
770
688
  }
771
689
  getTopLevelCollection(observe = 'body', reportProgress = false, options) {
772
690
  let localVarHeaders = this.defaultHeaders;
773
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
774
- if (localVarHttpHeaderAcceptSelected === undefined) {
775
- // to determine the Accept header
776
- const httpHeaderAccepts = ['application/json'];
777
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
778
- }
691
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
779
692
  if (localVarHttpHeaderAcceptSelected !== undefined) {
780
693
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
781
694
  }
782
- let localVarHttpContext = options && options.context;
783
- if (localVarHttpContext === undefined) {
784
- localVarHttpContext = new HttpContext();
785
- }
786
- let localVarTransferCache = options && options.transferCache;
787
- if (localVarTransferCache === undefined) {
788
- localVarTransferCache = true;
789
- }
695
+ const localVarHttpContext = options?.context ?? new HttpContext();
696
+ const localVarTransferCache = options?.transferCache ?? true;
790
697
  let responseType_ = 'json';
791
698
  if (localVarHttpHeaderAcceptSelected) {
792
699
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -837,84 +744,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
837
744
  * Do not edit the class manually.
838
745
  */
839
746
  /* tslint:disable:no-unused-variable member-ordering */
840
- class EditorsAPIService {
747
+ class EditorsAPIService extends BaseService {
841
748
  constructor(httpClient, basePath, configuration) {
749
+ super(basePath, configuration);
842
750
  this.httpClient = httpClient;
843
- this.basePath = 'https://repository.staging.openeduhub.net/edu-sharing/services/metaqs-2';
844
- this.defaultHeaders = new HttpHeaders();
845
- this.configuration = new Configuration();
846
- if (configuration) {
847
- this.configuration = configuration;
848
- }
849
- if (typeof this.configuration.basePath !== 'string') {
850
- const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
851
- if (firstBasePath != undefined) {
852
- basePath = firstBasePath;
853
- }
854
- if (typeof basePath !== 'string') {
855
- basePath = this.basePath;
856
- }
857
- this.configuration.basePath = basePath;
858
- }
859
- this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
860
- }
861
- // @ts-ignore
862
- addToHttpParams(httpParams, value, key) {
863
- if (typeof value === 'object' && value instanceof Date === false) {
864
- httpParams = this.addToHttpParamsRecursive(httpParams, value);
865
- }
866
- else {
867
- httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
868
- }
869
- return httpParams;
870
- }
871
- addToHttpParamsRecursive(httpParams, value, key) {
872
- if (value == null) {
873
- return httpParams;
874
- }
875
- if (typeof value === 'object') {
876
- if (Array.isArray(value)) {
877
- value.forEach((elem) => (httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)));
878
- }
879
- else if (value instanceof Date) {
880
- if (key != null) {
881
- httpParams = httpParams.append(key, value.toISOString().substring(0, 10));
882
- }
883
- else {
884
- throw Error('key may not be null if value is Date');
885
- }
886
- }
887
- else {
888
- Object.keys(value).forEach((k) => (httpParams = this.addToHttpParamsRecursive(httpParams, value[k], key != null ? `${key}.${k}` : k)));
889
- }
890
- }
891
- else if (key != null) {
892
- httpParams = httpParams.append(key, value);
893
- }
894
- else {
895
- throw Error('key may not be null if value is not object or array');
896
- }
897
- return httpParams;
898
751
  }
899
752
  getCompletenessForDisciplinaryPortals(filter, observe = 'body', reportProgress = false, options) {
900
753
  let localVarHeaders = this.defaultHeaders;
901
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
902
- if (localVarHttpHeaderAcceptSelected === undefined) {
903
- // to determine the Accept header
904
- const httpHeaderAccepts = ['application/json'];
905
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
906
- }
754
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
907
755
  if (localVarHttpHeaderAcceptSelected !== undefined) {
908
756
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
909
757
  }
910
- let localVarHttpContext = options && options.context;
911
- if (localVarHttpContext === undefined) {
912
- localVarHttpContext = new HttpContext();
913
- }
914
- let localVarTransferCache = options && options.transferCache;
915
- if (localVarTransferCache === undefined) {
916
- localVarTransferCache = true;
917
- }
758
+ const localVarHttpContext = options?.context ?? new HttpContext();
759
+ const localVarTransferCache = options?.transferCache ?? true;
918
760
  // to determine the Content-Type header
919
761
  const consumes = ['application/json'];
920
762
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -950,23 +792,12 @@ class EditorsAPIService {
950
792
  throw new Error('Required parameter materialCountFilter was null or undefined when calling getMaterialCount.');
951
793
  }
952
794
  let localVarHeaders = this.defaultHeaders;
953
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
954
- if (localVarHttpHeaderAcceptSelected === undefined) {
955
- // to determine the Accept header
956
- const httpHeaderAccepts = ['application/json'];
957
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
958
- }
795
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
959
796
  if (localVarHttpHeaderAcceptSelected !== undefined) {
960
797
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
961
798
  }
962
- let localVarHttpContext = options && options.context;
963
- if (localVarHttpContext === undefined) {
964
- localVarHttpContext = new HttpContext();
965
- }
966
- let localVarTransferCache = options && options.transferCache;
967
- if (localVarTransferCache === undefined) {
968
- localVarTransferCache = true;
969
- }
799
+ const localVarHttpContext = options?.context ?? new HttpContext();
800
+ const localVarTransferCache = options?.transferCache ?? true;
970
801
  // to determine the Content-Type header
971
802
  const consumes = ['application/json'];
972
803
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -999,23 +830,12 @@ class EditorsAPIService {
999
830
  }
1000
831
  getMaterialCountMatrixByLicenseGroup(filter, observe = 'body', reportProgress = false, options) {
1001
832
  let localVarHeaders = this.defaultHeaders;
1002
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1003
- if (localVarHttpHeaderAcceptSelected === undefined) {
1004
- // to determine the Accept header
1005
- const httpHeaderAccepts = ['application/json'];
1006
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1007
- }
833
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1008
834
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1009
835
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1010
836
  }
1011
- let localVarHttpContext = options && options.context;
1012
- if (localVarHttpContext === undefined) {
1013
- localVarHttpContext = new HttpContext();
1014
- }
1015
- let localVarTransferCache = options && options.transferCache;
1016
- if (localVarTransferCache === undefined) {
1017
- localVarTransferCache = true;
1018
- }
837
+ const localVarHttpContext = options?.context ?? new HttpContext();
838
+ const localVarTransferCache = options?.transferCache ?? true;
1019
839
  // to determine the Content-Type header
1020
840
  const consumes = ['application/json'];
1021
841
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1073,84 +893,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1073
893
  * Do not edit the class manually.
1074
894
  */
1075
895
  /* tslint:disable:no-unused-variable member-ordering */
1076
- class FilterAPIService {
896
+ class FilterAPIService extends BaseService {
1077
897
  constructor(httpClient, basePath, configuration) {
898
+ super(basePath, configuration);
1078
899
  this.httpClient = httpClient;
1079
- this.basePath = 'https://repository.staging.openeduhub.net/edu-sharing/services/metaqs-2';
1080
- this.defaultHeaders = new HttpHeaders();
1081
- this.configuration = new Configuration();
1082
- if (configuration) {
1083
- this.configuration = configuration;
900
+ }
901
+ getCollectionIssueFieldNames(observe = 'body', reportProgress = false, options) {
902
+ let localVarHeaders = this.defaultHeaders;
903
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
904
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
905
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1084
906
  }
1085
- if (typeof this.configuration.basePath !== 'string') {
1086
- const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
1087
- if (firstBasePath != undefined) {
1088
- basePath = firstBasePath;
907
+ const localVarHttpContext = options?.context ?? new HttpContext();
908
+ const localVarTransferCache = options?.transferCache ?? true;
909
+ let responseType_ = 'json';
910
+ if (localVarHttpHeaderAcceptSelected) {
911
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
912
+ responseType_ = 'text';
1089
913
  }
1090
- if (typeof basePath !== 'string') {
1091
- basePath = this.basePath;
914
+ else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
915
+ responseType_ = 'json';
916
+ }
917
+ else {
918
+ responseType_ = 'blob';
1092
919
  }
1093
- this.configuration.basePath = basePath;
1094
- }
1095
- this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
1096
- }
1097
- // @ts-ignore
1098
- addToHttpParams(httpParams, value, key) {
1099
- if (typeof value === 'object' && value instanceof Date === false) {
1100
- httpParams = this.addToHttpParamsRecursive(httpParams, value);
1101
- }
1102
- else {
1103
- httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
1104
920
  }
1105
- return httpParams;
1106
- }
1107
- addToHttpParamsRecursive(httpParams, value, key) {
1108
- if (value == null) {
1109
- return httpParams;
1110
- }
1111
- if (typeof value === 'object') {
1112
- if (Array.isArray(value)) {
1113
- value.forEach((elem) => (httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)));
1114
- }
1115
- else if (value instanceof Date) {
1116
- if (key != null) {
1117
- httpParams = httpParams.append(key, value.toISOString().substring(0, 10));
1118
- }
1119
- else {
1120
- throw Error('key may not be null if value is Date');
1121
- }
1122
- }
1123
- else {
1124
- Object.keys(value).forEach((k) => (httpParams = this.addToHttpParamsRecursive(httpParams, value[k], key != null ? `${key}.${k}` : k)));
1125
- }
1126
- }
1127
- else if (key != null) {
1128
- httpParams = httpParams.append(key, value);
1129
- }
1130
- else {
1131
- throw Error('key may not be null if value is not object or array');
1132
- }
1133
- return httpParams;
921
+ let localVarPath = `/filters/collection/issues`;
922
+ return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
923
+ context: localVarHttpContext,
924
+ responseType: responseType_,
925
+ withCredentials: this.configuration.withCredentials,
926
+ headers: localVarHeaders,
927
+ observe: observe,
928
+ transferCache: localVarTransferCache,
929
+ reportProgress: reportProgress,
930
+ });
1134
931
  }
1135
- getCollectionIssueFieldNames(observe = 'body', reportProgress = false, options) {
932
+ getHistoricalTimerange(observe = 'body', reportProgress = false, options) {
1136
933
  let localVarHeaders = this.defaultHeaders;
1137
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1138
- if (localVarHttpHeaderAcceptSelected === undefined) {
1139
- // to determine the Accept header
1140
- const httpHeaderAccepts = ['application/json'];
1141
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1142
- }
934
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1143
935
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1144
936
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1145
937
  }
1146
- let localVarHttpContext = options && options.context;
1147
- if (localVarHttpContext === undefined) {
1148
- localVarHttpContext = new HttpContext();
1149
- }
1150
- let localVarTransferCache = options && options.transferCache;
1151
- if (localVarTransferCache === undefined) {
1152
- localVarTransferCache = true;
1153
- }
938
+ const localVarHttpContext = options?.context ?? new HttpContext();
939
+ const localVarTransferCache = options?.transferCache ?? true;
1154
940
  let responseType_ = 'json';
1155
941
  if (localVarHttpHeaderAcceptSelected) {
1156
942
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -1163,7 +949,7 @@ class FilterAPIService {
1163
949
  responseType_ = 'blob';
1164
950
  }
1165
951
  }
1166
- let localVarPath = `/filters/collection/issues`;
952
+ let localVarPath = `/filters/timerange`;
1167
953
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
1168
954
  context: localVarHttpContext,
1169
955
  responseType: responseType_,
@@ -1174,25 +960,14 @@ class FilterAPIService {
1174
960
  reportProgress: reportProgress,
1175
961
  });
1176
962
  }
1177
- getHistoricalTimerange(observe = 'body', reportProgress = false, options) {
963
+ getMaterialIssueFieldNames(observe = 'body', reportProgress = false, options) {
1178
964
  let localVarHeaders = this.defaultHeaders;
1179
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1180
- if (localVarHttpHeaderAcceptSelected === undefined) {
1181
- // to determine the Accept header
1182
- const httpHeaderAccepts = ['application/json'];
1183
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1184
- }
965
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1185
966
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1186
967
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1187
968
  }
1188
- let localVarHttpContext = options && options.context;
1189
- if (localVarHttpContext === undefined) {
1190
- localVarHttpContext = new HttpContext();
1191
- }
1192
- let localVarTransferCache = options && options.transferCache;
1193
- if (localVarTransferCache === undefined) {
1194
- localVarTransferCache = true;
1195
- }
969
+ const localVarHttpContext = options?.context ?? new HttpContext();
970
+ const localVarTransferCache = options?.transferCache ?? true;
1196
971
  let responseType_ = 'json';
1197
972
  if (localVarHttpHeaderAcceptSelected) {
1198
973
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -1205,7 +980,7 @@ class FilterAPIService {
1205
980
  responseType_ = 'blob';
1206
981
  }
1207
982
  }
1208
- let localVarPath = `/filters/timerange`;
983
+ let localVarPath = `/filters/material/issues`;
1209
984
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
1210
985
  context: localVarHttpContext,
1211
986
  responseType: responseType_,
@@ -1216,25 +991,14 @@ class FilterAPIService {
1216
991
  reportProgress: reportProgress,
1217
992
  });
1218
993
  }
1219
- getMaterialIssueFieldNames(observe = 'body', reportProgress = false, options) {
994
+ getMaterialTypesMapping(observe = 'body', reportProgress = false, options) {
1220
995
  let localVarHeaders = this.defaultHeaders;
1221
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1222
- if (localVarHttpHeaderAcceptSelected === undefined) {
1223
- // to determine the Accept header
1224
- const httpHeaderAccepts = ['application/json'];
1225
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1226
- }
996
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1227
997
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1228
998
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1229
999
  }
1230
- let localVarHttpContext = options && options.context;
1231
- if (localVarHttpContext === undefined) {
1232
- localVarHttpContext = new HttpContext();
1233
- }
1234
- let localVarTransferCache = options && options.transferCache;
1235
- if (localVarTransferCache === undefined) {
1236
- localVarTransferCache = true;
1237
- }
1000
+ const localVarHttpContext = options?.context ?? new HttpContext();
1001
+ const localVarTransferCache = options?.transferCache ?? true;
1238
1002
  let responseType_ = 'json';
1239
1003
  if (localVarHttpHeaderAcceptSelected) {
1240
1004
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -1247,7 +1011,7 @@ class FilterAPIService {
1247
1011
  responseType_ = 'blob';
1248
1012
  }
1249
1013
  }
1250
- let localVarPath = `/filters/material/issues`;
1014
+ let localVarPath = `/filters/material/types`;
1251
1015
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
1252
1016
  context: localVarHttpContext,
1253
1017
  responseType: responseType_,
@@ -1258,25 +1022,14 @@ class FilterAPIService {
1258
1022
  reportProgress: reportProgress,
1259
1023
  });
1260
1024
  }
1261
- getMaterialTypesMapping(observe = 'body', reportProgress = false, options) {
1025
+ getPublicEndpoints(observe = 'body', reportProgress = false, options) {
1262
1026
  let localVarHeaders = this.defaultHeaders;
1263
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1264
- if (localVarHttpHeaderAcceptSelected === undefined) {
1265
- // to determine the Accept header
1266
- const httpHeaderAccepts = ['application/json'];
1267
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1268
- }
1027
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1269
1028
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1270
1029
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1271
1030
  }
1272
- let localVarHttpContext = options && options.context;
1273
- if (localVarHttpContext === undefined) {
1274
- localVarHttpContext = new HttpContext();
1275
- }
1276
- let localVarTransferCache = options && options.transferCache;
1277
- if (localVarTransferCache === undefined) {
1278
- localVarTransferCache = true;
1279
- }
1031
+ const localVarHttpContext = options?.context ?? new HttpContext();
1032
+ const localVarTransferCache = options?.transferCache ?? true;
1280
1033
  let responseType_ = 'json';
1281
1034
  if (localVarHttpHeaderAcceptSelected) {
1282
1035
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -1289,7 +1042,7 @@ class FilterAPIService {
1289
1042
  responseType_ = 'blob';
1290
1043
  }
1291
1044
  }
1292
- let localVarPath = `/filters/material/types`;
1045
+ let localVarPath = `/filters/public_endpoints`;
1293
1046
  return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, {
1294
1047
  context: localVarHttpContext,
1295
1048
  responseType: responseType_,
@@ -1302,23 +1055,12 @@ class FilterAPIService {
1302
1055
  }
1303
1056
  getQualitxMatrixFilters(observe = 'body', reportProgress = false, options) {
1304
1057
  let localVarHeaders = this.defaultHeaders;
1305
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1306
- if (localVarHttpHeaderAcceptSelected === undefined) {
1307
- // to determine the Accept header
1308
- const httpHeaderAccepts = ['application/json'];
1309
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1310
- }
1058
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1311
1059
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1312
1060
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1313
1061
  }
1314
- let localVarHttpContext = options && options.context;
1315
- if (localVarHttpContext === undefined) {
1316
- localVarHttpContext = new HttpContext();
1317
- }
1318
- let localVarTransferCache = options && options.transferCache;
1319
- if (localVarTransferCache === undefined) {
1320
- localVarTransferCache = true;
1321
- }
1062
+ const localVarHttpContext = options?.context ?? new HttpContext();
1063
+ const localVarTransferCache = options?.transferCache ?? true;
1322
1064
  let responseType_ = 'json';
1323
1065
  if (localVarHttpHeaderAcceptSelected) {
1324
1066
  if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
@@ -1369,84 +1111,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1369
1111
  * Do not edit the class manually.
1370
1112
  */
1371
1113
  /* tslint:disable:no-unused-variable member-ordering */
1372
- class ReplicationSourceAPIService {
1114
+ class ReplicationSourceAPIService extends BaseService {
1373
1115
  constructor(httpClient, basePath, configuration) {
1116
+ super(basePath, configuration);
1374
1117
  this.httpClient = httpClient;
1375
- this.basePath = 'https://repository.staging.openeduhub.net/edu-sharing/services/metaqs-2';
1376
- this.defaultHeaders = new HttpHeaders();
1377
- this.configuration = new Configuration();
1378
- if (configuration) {
1379
- this.configuration = configuration;
1380
- }
1381
- if (typeof this.configuration.basePath !== 'string') {
1382
- const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
1383
- if (firstBasePath != undefined) {
1384
- basePath = firstBasePath;
1385
- }
1386
- if (typeof basePath !== 'string') {
1387
- basePath = this.basePath;
1388
- }
1389
- this.configuration.basePath = basePath;
1390
- }
1391
- this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
1392
- }
1393
- // @ts-ignore
1394
- addToHttpParams(httpParams, value, key) {
1395
- if (typeof value === 'object' && value instanceof Date === false) {
1396
- httpParams = this.addToHttpParamsRecursive(httpParams, value);
1397
- }
1398
- else {
1399
- httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
1400
- }
1401
- return httpParams;
1402
- }
1403
- addToHttpParamsRecursive(httpParams, value, key) {
1404
- if (value == null) {
1405
- return httpParams;
1406
- }
1407
- if (typeof value === 'object') {
1408
- if (Array.isArray(value)) {
1409
- value.forEach((elem) => (httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)));
1410
- }
1411
- else if (value instanceof Date) {
1412
- if (key != null) {
1413
- httpParams = httpParams.append(key, value.toISOString().substring(0, 10));
1414
- }
1415
- else {
1416
- throw Error('key may not be null if value is Date');
1417
- }
1418
- }
1419
- else {
1420
- Object.keys(value).forEach((k) => (httpParams = this.addToHttpParamsRecursive(httpParams, value[k], key != null ? `${key}.${k}` : k)));
1421
- }
1422
- }
1423
- else if (key != null) {
1424
- httpParams = httpParams.append(key, value);
1425
- }
1426
- else {
1427
- throw Error('key may not be null if value is not object or array');
1428
- }
1429
- return httpParams;
1430
1118
  }
1431
1119
  getCompletenessForReplicationSources(filter, observe = 'body', reportProgress = false, options) {
1432
1120
  let localVarHeaders = this.defaultHeaders;
1433
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1434
- if (localVarHttpHeaderAcceptSelected === undefined) {
1435
- // to determine the Accept header
1436
- const httpHeaderAccepts = ['application/json'];
1437
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1438
- }
1121
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1439
1122
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1440
1123
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1441
1124
  }
1442
- let localVarHttpContext = options && options.context;
1443
- if (localVarHttpContext === undefined) {
1444
- localVarHttpContext = new HttpContext();
1445
- }
1446
- let localVarTransferCache = options && options.transferCache;
1447
- if (localVarTransferCache === undefined) {
1448
- localVarTransferCache = true;
1449
- }
1125
+ const localVarHttpContext = options?.context ?? new HttpContext();
1126
+ const localVarTransferCache = options?.transferCache ?? true;
1450
1127
  // to determine the Content-Type header
1451
1128
  const consumes = ['application/json'];
1452
1129
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1479,23 +1156,12 @@ class ReplicationSourceAPIService {
1479
1156
  }
1480
1157
  getMaterialCountMatrixByReplicationSourceAndLicense(filter, observe = 'body', reportProgress = false, options) {
1481
1158
  let localVarHeaders = this.defaultHeaders;
1482
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1483
- if (localVarHttpHeaderAcceptSelected === undefined) {
1484
- // to determine the Accept header
1485
- const httpHeaderAccepts = ['application/json'];
1486
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1487
- }
1159
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1488
1160
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1489
1161
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1490
1162
  }
1491
- let localVarHttpContext = options && options.context;
1492
- if (localVarHttpContext === undefined) {
1493
- localVarHttpContext = new HttpContext();
1494
- }
1495
- let localVarTransferCache = options && options.transferCache;
1496
- if (localVarTransferCache === undefined) {
1497
- localVarTransferCache = true;
1498
- }
1163
+ const localVarHttpContext = options?.context ?? new HttpContext();
1164
+ const localVarTransferCache = options?.transferCache ?? true;
1499
1165
  // to determine the Content-Type header
1500
1166
  const consumes = ['application/json'];
1501
1167
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1528,23 +1194,12 @@ class ReplicationSourceAPIService {
1528
1194
  }
1529
1195
  getMaterialCountMatrixByReplicationSourceAndType(filter, observe = 'body', reportProgress = false, options) {
1530
1196
  let localVarHeaders = this.defaultHeaders;
1531
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1532
- if (localVarHttpHeaderAcceptSelected === undefined) {
1533
- // to determine the Accept header
1534
- const httpHeaderAccepts = ['application/json'];
1535
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1536
- }
1197
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1537
1198
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1538
1199
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1539
1200
  }
1540
- let localVarHttpContext = options && options.context;
1541
- if (localVarHttpContext === undefined) {
1542
- localVarHttpContext = new HttpContext();
1543
- }
1544
- let localVarTransferCache = options && options.transferCache;
1545
- if (localVarTransferCache === undefined) {
1546
- localVarTransferCache = true;
1547
- }
1201
+ const localVarHttpContext = options?.context ?? new HttpContext();
1202
+ const localVarTransferCache = options?.transferCache ?? true;
1548
1203
  // to determine the Content-Type header
1549
1204
  const consumes = ['application/json'];
1550
1205
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1577,23 +1232,12 @@ class ReplicationSourceAPIService {
1577
1232
  }
1578
1233
  getQualityMatrixTimestampsV2(filter, observe = 'body', reportProgress = false, options) {
1579
1234
  let localVarHeaders = this.defaultHeaders;
1580
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1581
- if (localVarHttpHeaderAcceptSelected === undefined) {
1582
- // to determine the Accept header
1583
- const httpHeaderAccepts = ['application/json'];
1584
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1585
- }
1235
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1586
1236
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1587
1237
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1588
1238
  }
1589
- let localVarHttpContext = options && options.context;
1590
- if (localVarHttpContext === undefined) {
1591
- localVarHttpContext = new HttpContext();
1592
- }
1593
- let localVarTransferCache = options && options.transferCache;
1594
- if (localVarTransferCache === undefined) {
1595
- localVarTransferCache = true;
1596
- }
1239
+ const localVarHttpContext = options?.context ?? new HttpContext();
1240
+ const localVarTransferCache = options?.transferCache ?? true;
1597
1241
  // to determine the Content-Type header
1598
1242
  const consumes = ['application/json'];
1599
1243
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1626,23 +1270,12 @@ class ReplicationSourceAPIService {
1626
1270
  }
1627
1271
  getQualityMatrixV2(filter, observe = 'body', reportProgress = false, options) {
1628
1272
  let localVarHeaders = this.defaultHeaders;
1629
- let localVarHttpHeaderAcceptSelected = options && options.httpHeaderAccept;
1630
- if (localVarHttpHeaderAcceptSelected === undefined) {
1631
- // to determine the Accept header
1632
- const httpHeaderAccepts = ['application/json'];
1633
- localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
1634
- }
1273
+ const localVarHttpHeaderAcceptSelected = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept(['application/json']);
1635
1274
  if (localVarHttpHeaderAcceptSelected !== undefined) {
1636
1275
  localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
1637
1276
  }
1638
- let localVarHttpContext = options && options.context;
1639
- if (localVarHttpContext === undefined) {
1640
- localVarHttpContext = new HttpContext();
1641
- }
1642
- let localVarTransferCache = options && options.transferCache;
1643
- if (localVarTransferCache === undefined) {
1644
- localVarTransferCache = true;
1645
- }
1277
+ const localVarHttpContext = options?.context ?? new HttpContext();
1278
+ const localVarTransferCache = options?.transferCache ?? true;
1646
1279
  // to determine the Content-Type header
1647
1280
  const consumes = ['application/json'];
1648
1281
  const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
@@ -1827,6 +1460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1827
1460
 
1828
1461
  class NgMetaWidgetsLibConfiguration {
1829
1462
  }
1463
+ const NG_META_WIDGETS_LIB_CONFIGURATION = new InjectionToken('NG_META_WIDGETS_LIB_CONFIGURATION');
1830
1464
  /**
1831
1465
  * helper class to provide configuration values
1832
1466
  */
@@ -1844,14 +1478,14 @@ class ConfigHelperService {
1844
1478
  get eduSharingPath() {
1845
1479
  return this.config.eduSharingPath;
1846
1480
  }
1847
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfigHelperService, deps: [{ token: 'config' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1481
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfigHelperService, deps: [{ token: NG_META_WIDGETS_LIB_CONFIGURATION }], target: i0.ɵɵFactoryTarget.Injectable }); }
1848
1482
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfigHelperService }); }
1849
1483
  }
1850
1484
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfigHelperService, decorators: [{
1851
1485
  type: Injectable
1852
1486
  }], ctorParameters: () => [{ type: NgMetaWidgetsLibConfiguration, decorators: [{
1853
1487
  type: Inject,
1854
- args: ['config']
1488
+ args: [NG_META_WIDGETS_LIB_CONFIGURATION]
1855
1489
  }] }] });
1856
1490
 
1857
1491
  /**
@@ -1891,235 +1525,349 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1891
1525
  type: Output
1892
1526
  }] } });
1893
1527
 
1528
+ const TOOLTIP_DATA = new InjectionToken('TOOLTIP_DATA');
1529
+ const TOOLTIP_REF = new InjectionToken('TOOLTIP_REF');
1530
+ const noop = Object.freeze(() => { });
1894
1531
  /**
1895
- * This class is a thin wrapper around the API services.
1532
+ * @internal
1896
1533
  */
1897
- class MetaApiService {
1898
- constructor(collectionsAPI, replicationsAPI, filterAPI, editorsAPI) {
1899
- this.collectionsAPI = collectionsAPI;
1900
- this.replicationsAPI = replicationsAPI;
1901
- this.filterAPI = filterAPI;
1902
- this.editorsAPI = editorsAPI;
1903
- }
1904
- /**
1905
- * Get the filters for the quality matrix.
1906
- * It pipes the observable to take only one value.
1907
- */
1908
- getSearchFilters() {
1909
- return this.filterAPI.getQualitxMatrixFilters().pipe(take(1));
1910
- }
1911
- getCategoryFilters() {
1912
- return this.getSearchFilters().pipe(map((filters) => filters.filter((filter) => filter.field !== 'timerange')));
1913
- }
1914
- getCollectionsFilter() {
1915
- return this.collectionsAPI.getTopLevelCollection();
1916
- }
1917
- /**
1918
- * Get the timerange filter for the quality matrix.
1919
- * Returns the first filter of the historical timerange filters.
1920
- */
1921
- getTimerangeFilter() {
1922
- return this.filterAPI.getHistoricalTimerange().pipe(take(1), map((filters) => filters[0]));
1923
- }
1924
- getMaterialCountMatrixPerCollection(nodeRef, oerOnly) {
1925
- return this.collectionsAPI.getMaterialCountMatrixPerCollection(nodeRef, oerOnly);
1926
- }
1927
- getCollectionCompleteness(colId) {
1928
- return this.collectionsAPI.getCompleteness(colId);
1929
- }
1930
- getQualityMatrixWithFiltersV2(body) {
1931
- return this.replicationsAPI.getQualityMatrixV2(body);
1534
+ class TooltipRefImpl {
1535
+ constructor(renderer, overlay, openTimeout = 0, closeTimeout = 0, onOpen = noop, onClose = noop) {
1536
+ this.renderer = renderer;
1537
+ this.overlay = overlay;
1538
+ this.openTimeout = openTimeout;
1539
+ this.closeTimeout = closeTimeout;
1540
+ this.onOpen = onOpen;
1541
+ this.onClose = onClose;
1542
+ }
1543
+ cancelCloseAction() {
1544
+ clearTimeout(this.closeTimeoutRef);
1545
+ this.closeTimeoutRef = undefined;
1546
+ }
1547
+ open() {
1548
+ this.openTimeoutRef = setTimeout(this.openTooltip.bind(this), this.openTimeout); // typescript bug (typescript mistakenly uses NodeJS.Timeout instead of number as return type of setTimeout)
1549
+ }
1550
+ openTooltip() {
1551
+ this.openTimeoutRef = undefined;
1552
+ this.component = this.overlay.attach(this.portal);
1553
+ this.unlistenMouseEnter = this.renderer.listen(this.overlay.overlayElement, 'mouseenter', this.cancelCloseAction.bind(this));
1554
+ this.unlistenMouseLeave = this.renderer.listen(this.overlay.overlayElement, 'mouseleave', this.markForClose.bind(this));
1555
+ this.onOpen();
1556
+ }
1557
+ markForClose() {
1558
+ if (this.openTimeoutRef) {
1559
+ // not yet opened, cancel open action
1560
+ clearTimeout(this.openTimeoutRef);
1561
+ this.openTimeoutRef = undefined;
1562
+ return;
1563
+ }
1564
+ if (this.closeTimeoutRef) {
1565
+ // already marked for close
1566
+ return;
1567
+ }
1568
+ this.closeTimeoutRef = setTimeout(this.closeTooltip.bind(this), this.closeTimeout); // typescript bug (typescript mistakenly uses NodeJS.Timeout instead of number as return type of setTimeout)
1932
1569
  }
1933
- getEditorialMaterialCounts(body) {
1934
- return this.editorsAPI.getMaterialCount(body);
1570
+ closeTooltip() {
1571
+ this.overlay.detach();
1572
+ this.onClose();
1573
+ this.closeTimeoutRef = undefined;
1574
+ this.unlistenMouseEnter?.();
1575
+ this.unlistenMouseLeave?.();
1935
1576
  }
1936
- getMaterialTypeCountsByReplicationSource(body) {
1937
- return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndType(body);
1577
+ }
1578
+ const centerPositionStrategy = [
1579
+ {
1580
+ originX: 'center',
1581
+ originY: 'center',
1582
+ overlayX: 'start',
1583
+ overlayY: 'top',
1584
+ },
1585
+ {
1586
+ originX: 'center',
1587
+ originY: 'center',
1588
+ overlayX: 'start',
1589
+ overlayY: 'bottom',
1590
+ },
1591
+ {
1592
+ originX: 'center',
1593
+ originY: 'center',
1594
+ overlayX: 'end',
1595
+ overlayY: 'top',
1596
+ },
1597
+ {
1598
+ originX: 'center',
1599
+ originY: 'center',
1600
+ overlayX: 'end',
1601
+ overlayY: 'bottom',
1602
+ },
1603
+ ];
1604
+ const borderPositionStrategy = [
1605
+ {
1606
+ originX: 'center',
1607
+ originY: 'bottom',
1608
+ overlayX: 'start',
1609
+ overlayY: 'top',
1610
+ },
1611
+ {
1612
+ originX: 'center',
1613
+ originY: 'bottom',
1614
+ overlayX: 'end',
1615
+ overlayY: 'top',
1616
+ },
1617
+ {
1618
+ originX: 'center',
1619
+ originY: 'top',
1620
+ overlayX: 'start',
1621
+ overlayY: 'bottom',
1622
+ },
1623
+ {
1624
+ originX: 'center',
1625
+ originY: 'top',
1626
+ overlayX: 'end',
1627
+ overlayY: 'bottom',
1628
+ },
1629
+ ];
1630
+ class TooltipService {
1631
+ constructor() {
1632
+ this.overlay = inject(Overlay);
1633
+ this.renderer = inject(Renderer2);
1938
1634
  }
1939
- getLicenseCountsByReplicationSource(body) {
1940
- return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndLicense(body);
1635
+ create(component, config) {
1636
+ const overlayRef = this.overlay.create(config.overlayConfig ?? {
1637
+ hasBackdrop: false,
1638
+ disposeOnNavigation: true,
1639
+ });
1640
+ const tooltipRef = new TooltipRefImpl(this.renderer, overlayRef, config.openTimeout ?? 0, config.closeTimeout ?? 0, config.onOpen ?? noop, config.onClose ?? noop);
1641
+ tooltipRef.portal = new ComponentPortal(component, null, Injector.create({
1642
+ providers: [
1643
+ {
1644
+ provide: OverlayRef,
1645
+ useValue: overlayRef,
1646
+ },
1647
+ {
1648
+ provide: TOOLTIP_DATA,
1649
+ useValue: config.data,
1650
+ },
1651
+ {
1652
+ provide: TOOLTIP_REF,
1653
+ useValue: tooltipRef,
1654
+ },
1655
+ ],
1656
+ parent: config.injector,
1657
+ }));
1658
+ return tooltipRef;
1941
1659
  }
1942
- getMaterialCountMatrixByLicenseGroup(body) {
1943
- return this.editorsAPI.getMaterialCountMatrixByLicenseGroup(body);
1660
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1661
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipService, providedIn: 'root' }); }
1662
+ }
1663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipService, decorators: [{
1664
+ type: Injectable,
1665
+ args: [{
1666
+ providedIn: 'root',
1667
+ }]
1668
+ }] });
1669
+
1670
+ class DonutChartPipe {
1671
+ transform(donutSlices, radius, svgSize, borderSize) {
1672
+ let previousPercent = 0;
1673
+ return donutSlices.map((slice) => {
1674
+ // this is a hack to that the circle is rendered when the percent is 100
1675
+ slice.percent = slice.percent === 100 ? 99.999 : slice.percent;
1676
+ const sliceWithCommands = {
1677
+ ...slice,
1678
+ commands: `${this.getSliceCommands(slice, radius, svgSize, borderSize)} z`,
1679
+ offset: previousPercent * 3.6 * -1,
1680
+ };
1681
+ previousPercent += slice.percent;
1682
+ return sliceWithCommands;
1683
+ });
1944
1684
  }
1945
- getCompletenessForDisciplinaryPortals(body) {
1946
- return this.editorsAPI.getCompletenessForDisciplinaryPortals(body);
1685
+ getSliceCommands(donutSlice, radius, svgSize, borderSize) {
1686
+ const degrees = this.percentToDegrees(donutSlice.percent);
1687
+ const longPathFlag = degrees > 180 ? 1 : 0;
1688
+ const innerRadius = radius - borderSize;
1689
+ const commands = [];
1690
+ commands.push(`M ${svgSize / 2 + radius} ${svgSize / 2}`);
1691
+ commands.push(`A ${radius} ${radius} 0 ${longPathFlag} 0 ${this.getCoordFromDegrees(degrees, radius, svgSize)}`);
1692
+ commands.push(`L ${this.getCoordFromDegrees(degrees, innerRadius, svgSize)}`);
1693
+ commands.push(`A ${innerRadius} ${innerRadius} 0 ${longPathFlag} 1 ${svgSize / 2 + innerRadius} ${svgSize / 2}`);
1694
+ return commands.join(' ');
1947
1695
  }
1948
- getCompletenessForReplicationSources(body) {
1949
- return this.replicationsAPI.getCompletenessForReplicationSources(body);
1696
+ getCoordFromDegrees(angle, radius, svgSize) {
1697
+ const x = Math.cos((angle * Math.PI) / 180);
1698
+ const y = Math.sin((angle * Math.PI) / 180);
1699
+ const coordX = x * radius + svgSize / 2;
1700
+ const coordY = y * -radius + svgSize / 2;
1701
+ return `${coordX} ${coordY}`;
1950
1702
  }
1951
- getMaterialTypesMapping() {
1952
- return this.filterAPI.getMaterialTypesMapping();
1703
+ percentToDegrees(percent) {
1704
+ return percent * 3.6;
1953
1705
  }
1954
- 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 }); }
1955
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, providedIn: 'root' }); }
1706
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1707
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, isStandalone: true, name: "slicesWithCommandsAndOffset" }); }
1956
1708
  }
1957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, decorators: [{
1958
- type: Injectable,
1709
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, decorators: [{
1710
+ type: Pipe,
1959
1711
  args: [{
1960
- providedIn: 'root',
1712
+ name: 'slicesWithCommandsAndOffset',
1713
+ pure: true,
1714
+ standalone: true,
1961
1715
  }]
1962
- }], ctorParameters: () => [{ type: CollectionAPIService }, { type: ReplicationSourceAPIService }, { type: FilterAPIService }, { type: EditorsAPIService }] });
1716
+ }] });
1963
1717
 
1964
1718
  /**
1965
- * This service provides methods to create links to the editorial desk with specific filters.
1719
+ * A donut chart component that displays a list of slices.
1720
+ * The chart is divided into slices, each slice has a color and a label.
1721
+ * Each slice is represented by a percentage of the total chart.
1722
+ * borrowed from https://medium.com/@theAngularGuy/how-to-create-an-interactive-donut-chart-using-svg-107cbf0b5b6
1966
1723
  */
1967
- /* This map makes it easier for me to keep track which issues are mapped to which filters */
1968
- const FilterNames2Issues = {
1969
- //Lizenzen
1970
- 'virtual:editorial_license': ['oer', 'other_cc', 'copyright', 'without_license'],
1971
- //Materialtypen werden im Constructor gesetzt
1972
- 'virtual:oeh_lrt': [],
1973
- 'virtual:editorial_exclusion': [
1974
- 'outdated',
1975
- 'without_preview',
1976
- 'without_title',
1977
- 'without_description',
1978
- 'without_url',
1979
- 'without_type',
1980
- 'without_taxonomy_id',
1981
- 'without_education_level',
1982
- 'without_target_group',
1983
- 'without_license',
1984
- 'without_publisher',
1985
- ],
1986
- };
1987
- // 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
1988
- const Issues2FilterNames = Object.entries(FilterNames2Issues).reduce((map, [key, value]) => {
1989
- value.forEach((issue) => map.set(issue, key));
1990
- return map;
1991
- }, new Map());
1992
- // maps our values to the values of the filter in the editorial desk
1993
- const MapValuesForFilter = {
1994
- 'virtual:editorial_exclusion': {
1995
- outdated: null,
1996
- without_preview: null,
1997
- without_title: ['missing_title'],
1998
- without_description: ['missing_description'],
1999
- without_url: ['links'],
2000
- without_type: ['missing_oeh_lrt'],
2001
- without_taxonomy_id: ['without_taxonomy_id'],
2002
- without_education_level: ['missing_educationalcontext'],
2003
- without_target_group: ['missing_educationalintendedenduserrole'],
2004
- without_license: ['missing_license'],
2005
- without_publisher: ['missing_replicationsource'],
2006
- },
2007
- 'virtual:editorial_license': {
2008
- oer: ['oer'],
2009
- copyright: ['none_oer'],
2010
- without_license: ['none'],
2011
- },
2012
- 'virtual:oeh_lrt': {},
2013
- };
2014
- /*
2015
- This is a map from properties of a document to filter names
2016
- */
2017
- const PROPERTIES2FILTERS = new Map([
2018
- ['metadata.educationalContexts', 'ccm:educationalcontext'],
2019
- ['metadata.disciplines', 'virtual:taxonid'],
2020
- //["responsibility", "virtual:collection_id_primary"] // das zeigt auf "sammlungszugehörigkeit" und ist falsch
2021
- ]);
2022
- class EditorialLinkService {
1724
+ class DonutChartComponent {
2023
1725
  constructor() {
2024
- this.env = inject(ConfigHelperService);
2025
- this.api = inject(MetaApiService);
2026
- this.typesLoaded$ = new BehaviorSubject(false);
2027
- this.api
2028
- .getMaterialTypesMapping()
2029
- .pipe(take(1))
2030
- .subscribe((types) => {
2031
- for (const [key, value] of Object.entries(types)) {
2032
- Issues2FilterNames.set(key, 'virtual:oeh_lrt');
2033
- MapValuesForFilter['virtual:oeh_lrt'][key] = value;
2034
- }
2035
- this.typesLoaded$.next(true);
2036
- });
1726
+ this.radius = 50;
1727
+ this.viewBox = 100;
1728
+ this.borderSize = 20;
1729
+ this.strokeWidth = 5;
1730
+ this.data = [];
2037
1731
  }
2038
- openByReplicationsourceAndIssueTypeWithFilters(source, issue, selectedFilters) {
2039
- const filters = {};
2040
- filters['virtual:audit_filter'] = ['all'];
2041
- filters['ccm:oeh_publisher_combined'] = [source];
2042
- filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issue];
2043
- for (const [field, values] of Object.entries(selectedFilters)) {
2044
- if (values && values.length) {
2045
- const editorialFiltername = PROPERTIES2FILTERS.get(field);
2046
- filters[editorialFiltername] = values;
2047
- }
1732
+ ngOnInit() {
1733
+ const sum = this.data?.reduce((accu, slice) => accu + slice.percent, 0);
1734
+ if (sum !== 100) {
1735
+ throw new Error(`The sum of all slices of the donut chart must equal to 100%. Found: ${sum}.`);
2048
1736
  }
2049
- const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2050
- const params = new URLSearchParams();
2051
- params.set('mode', 'audit');
2052
- params.set('filters', JSON.stringify(filters));
2053
- window.open(`${theUrl}?${params}`, 'editor_frontend');
2054
- }
2055
- openByCollectionAndIssueType(collectionId, issueType, pageTitle) {
2056
- const filters = {};
2057
- filters['virtual:audit_filter'] = ['all'];
2058
- filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issueType];
2059
- filters['virtual:collection_id_primary'] = [collectionId];
2060
- const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2061
- const params = new URLSearchParams();
2062
- params.set('title', pageTitle);
2063
- params.set('mode', 'audit');
2064
- params.set('filters', JSON.stringify(filters));
2065
- window.open(`${theUrl}?${params}`, 'editor_frontend');
2066
1737
  }
2067
- openByCollectionId(collectionId) {
2068
- const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2069
- const params = new URLSearchParams();
2070
- params.set('ids', collectionId);
2071
- params.set('mode', 'render');
2072
- window.open(`${theUrl}?${params}`, 'editor_frontend');
2073
- }
2074
- /**
2075
- * This method creates a link to the editorial desk with specific filters.
2076
- * It returns the URL to the editorial desk with the filters applied or null if the issueId is not mapped to a filter.
2077
- * With this we can render a link with an href attribute to the editorial desk in the frontend.
2078
- * @see the counts-with-history.component.scss how we style links only if their hrefs are not null
2079
- *
2080
- * @param sourceType The type of the source, e.g. "replicationSource" or "collection"
2081
- * @param sourceId The id of the source. This is the first column in the table.
2082
- * @param issueId The id of the issue. These are the other columns in the table.
2083
- */
2084
- createLinkForCountsWithHistory(sourceType, sourceId, issueId) {
2085
- const filters = {};
2086
- filters['virtual:audit_filter'] = ['all'];
2087
- // determine the "main" filter
2088
- if (sourceType === 'replicationSource') {
2089
- filters['ccm:oeh_publisher_combined'] = [sourceId];
2090
- }
2091
- else if (sourceType === 'collection') {
2092
- filters['virtual:collection_id_primary'] = [sourceId];
2093
- }
2094
- if (!Issues2FilterNames.has(issueId)) {
2095
- return null;
2096
- }
2097
- const filterName = Issues2FilterNames.get(issueId);
2098
- if (!filterName) {
2099
- // console.debug("No filter name found for issue id: " + issueId);
2100
- return null;
2101
- }
2102
- const filterValue = MapValuesForFilter[filterName][issueId];
2103
- if (!filterValue) {
2104
- // console.debug("No filter value found for issue id: " + issueId);
2105
- return null;
2106
- }
2107
- filters[filterName] = filterValue;
2108
- const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2109
- const params = new URLSearchParams();
2110
- params.set('mode', 'audit');
2111
- params.set('filters', JSON.stringify(filters));
2112
- return `${theUrl}?${params}`;
1738
+ trackByFn(index, slice) {
1739
+ return slice.id;
2113
1740
  }
2114
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2115
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, providedIn: 'root' }); }
1741
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1742
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DonutChartComponent, isStandalone: true, selector: "metaqs2-donut-chart", inputs: { radius: "radius", viewBox: "viewBox", borderSize: "borderSize", strokeWidth: "strokeWidth", data: "data" }, ngImport: i0, template: `
1743
+ <svg [attr.viewBox]="'0 0 ' + viewBox + ' ' + viewBox" *ngIf="data">
1744
+ <path
1745
+ *ngFor="
1746
+ let slice of data | slicesWithCommandsAndOffset : radius : viewBox : borderSize;
1747
+ trackBy: trackByFn;
1748
+ let index = index
1749
+ "
1750
+ [attr.fill]="slice.color"
1751
+ stroke="white"
1752
+ paint-order="stroke"
1753
+ stroke-opacity="1"
1754
+ [attr.stroke-width]="strokeWidth"
1755
+ [attr.d]="slice.commands"
1756
+ [attr.transform]="'rotate(' + slice.offset + ')'"
1757
+ (click)="slice.onClickCb?.()"
1758
+ >
1759
+ <title>{{ slice.label }}</title>
1760
+ </path>
1761
+ </svg>
1762
+ `, isInline: true, styles: [":host{display:block}svg{overflow:visible;transform-origin:center;width:3.5rem;aspect-ratio:1/1;rotate:-90deg}path{transform-origin:center;fill-opacity:.7;cursor:pointer}path:hover{fill-opacity:1}\n"], dependencies: [{ kind: "pipe", type: DonutChartPipe, name: "slicesWithCommandsAndOffset" }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2116
1763
  }
2117
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, decorators: [{
2118
- type: Injectable,
2119
- args: [{
2120
- providedIn: 'root',
2121
- }]
2122
- }], ctorParameters: () => [] });
1764
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartComponent, decorators: [{
1765
+ type: Component,
1766
+ args: [{ selector: 'metaqs2-donut-chart', changeDetection: ChangeDetectionStrategy.OnPush, template: `
1767
+ <svg [attr.viewBox]="'0 0 ' + viewBox + ' ' + viewBox" *ngIf="data">
1768
+ <path
1769
+ *ngFor="
1770
+ let slice of data | slicesWithCommandsAndOffset : radius : viewBox : borderSize;
1771
+ trackBy: trackByFn;
1772
+ let index = index
1773
+ "
1774
+ [attr.fill]="slice.color"
1775
+ stroke="white"
1776
+ paint-order="stroke"
1777
+ stroke-opacity="1"
1778
+ [attr.stroke-width]="strokeWidth"
1779
+ [attr.d]="slice.commands"
1780
+ [attr.transform]="'rotate(' + slice.offset + ')'"
1781
+ (click)="slice.onClickCb?.()"
1782
+ >
1783
+ <title>{{ slice.label }}</title>
1784
+ </path>
1785
+ </svg>
1786
+ `, imports: [DonutChartPipe, NgForOf, NgIf], standalone: true, styles: [":host{display:block}svg{overflow:visible;transform-origin:center;width:3.5rem;aspect-ratio:1/1;rotate:-90deg}path{transform-origin:center;fill-opacity:.7;cursor:pointer}path:hover{fill-opacity:1}\n"] }]
1787
+ }], propDecorators: { radius: [{
1788
+ type: Input
1789
+ }], viewBox: [{
1790
+ type: Input
1791
+ }], borderSize: [{
1792
+ type: Input
1793
+ }], strokeWidth: [{
1794
+ type: Input
1795
+ }], data: [{
1796
+ type: Input
1797
+ }] } });
1798
+
1799
+ function transformDonutChartData(data) {
1800
+ return data.map((slice) => [
1801
+ // inverted order is necessary for the donut chart to go clockwise
1802
+ {
1803
+ percent: 100 - slice.percent,
1804
+ color: 'transparent',
1805
+ id: 999999,
1806
+ },
1807
+ slice,
1808
+ ]);
1809
+ }
1810
+ class DonutChartTooltipComponent {
1811
+ constructor() {
1812
+ this.animationState = true;
1813
+ this.data = inject(TOOLTIP_DATA);
1814
+ }
1815
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1816
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DonutChartTooltipComponent, selector: "metaqs2-donut-chart-tooltip", host: { properties: { "@fadeInOut": "this.animationState" } }, ngImport: i0, template: "<h4>{{ data.label }}</h4>\n<p>Status</p>\n<ng-container *ngFor=\"let slicePair of data.data\">\n <ng-container *ngIf=\"slicePair[1].percent > 0\">\n <div style=\"display: flex; justify-content: flex-start; align-items: center; gap: 0.25rem\">\n <metaqs2-donut-chart [data]=\"slicePair\" [borderSize]=\"25\"></metaqs2-donut-chart>\n <p>{{ slicePair[1].verboseLabel }}</p>\n </div>\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;margin:1rem}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DonutChartComponent, selector: "metaqs2-donut-chart", inputs: ["radius", "viewBox", "borderSize", "strokeWidth", "data"] }], animations: [
1817
+ trigger('fadeInOut', [
1818
+ transition(':enter', [
1819
+ style({
1820
+ opacity: 0,
1821
+ scale: 0.5,
1822
+ }),
1823
+ animate('100ms ease-in', style({
1824
+ opacity: 1,
1825
+ scale: 1,
1826
+ })),
1827
+ ]),
1828
+ transition(':leave', [
1829
+ style({
1830
+ opacity: 1,
1831
+ scale: 1,
1832
+ }),
1833
+ animate('100ms ease-out', style({
1834
+ opacity: 0,
1835
+ scale: 0.5,
1836
+ })),
1837
+ ]),
1838
+ ]),
1839
+ ] }); }
1840
+ }
1841
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartTooltipComponent, decorators: [{
1842
+ type: Component,
1843
+ args: [{ selector: 'metaqs2-donut-chart-tooltip', animations: [
1844
+ trigger('fadeInOut', [
1845
+ transition(':enter', [
1846
+ style({
1847
+ opacity: 0,
1848
+ scale: 0.5,
1849
+ }),
1850
+ animate('100ms ease-in', style({
1851
+ opacity: 1,
1852
+ scale: 1,
1853
+ })),
1854
+ ]),
1855
+ transition(':leave', [
1856
+ style({
1857
+ opacity: 1,
1858
+ scale: 1,
1859
+ }),
1860
+ animate('100ms ease-out', style({
1861
+ opacity: 0,
1862
+ scale: 0.5,
1863
+ })),
1864
+ ]),
1865
+ ]),
1866
+ ], template: "<h4>{{ data.label }}</h4>\n<p>Status</p>\n<ng-container *ngFor=\"let slicePair of data.data\">\n <ng-container *ngIf=\"slicePair[1].percent > 0\">\n <div style=\"display: flex; justify-content: flex-start; align-items: center; gap: 0.25rem\">\n <metaqs2-donut-chart [data]=\"slicePair\" [borderSize]=\"25\"></metaqs2-donut-chart>\n <p>{{ slicePair[1].verboseLabel }}</p>\n </div>\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;margin:1rem}\n"] }]
1867
+ }], propDecorators: { animationState: [{
1868
+ type: HostBinding,
1869
+ args: ['@fadeInOut']
1870
+ }] } });
2123
1871
 
2124
1872
  const datePickerFormats$1 = {
2125
1873
  parse: {
@@ -2152,16 +1900,12 @@ class DatepickerComponent {
2152
1900
  { provide: LOCALE_ID, useValue: 'de-DE' },
2153
1901
  { provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
2154
1902
  { provide: MAT_LUXON_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true, firstDayOfWeek: 1 } },
2155
- ], ngImport: i0, template: "<mat-card>\n <mat-card-header>\n <mat-card-title> Zeitlicher Vergleich </mat-card-title>\n </mat-card-header>\n <mat-card-content [formGroup]=\"inputGroup\">\n <!-- start date -->\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\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<!--\n <mat-hint>d.M.yyyy</mat-hint>\n-->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker1 [startAt]=\"inputGroup.controls.start.defaultValue\">\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker2 [startAt]=\"inputGroup.controls.end.value\">\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n </mat-card-content>\n</mat-card>\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: 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: "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"] }] }); }
1903
+ ], ngImport: i0, template: "<div [formGroup]=\"inputGroup\">\n <!-- start date -->\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker1 [startAt]=\"inputGroup.controls.start.defaultValue\">\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker2 [startAt]=\"inputGroup.controls.end.value\">\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n</div>\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"] }] }); }
2156
1904
  }
2157
1905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatepickerComponent, decorators: [{
2158
1906
  type: Component,
2159
1907
  args: [{ selector: 'metaqs2-datepicker', standalone: true, imports: [
2160
1908
  FormsModule,
2161
- MatCard,
2162
- MatCardContent,
2163
- MatCardHeader,
2164
- MatCardTitle,
2165
1909
  MatDatepicker,
2166
1910
  MatDatepickerInput,
2167
1911
  MatDatepickerToggle,
@@ -2181,7 +1925,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2181
1925
  { provide: LOCALE_ID, useValue: 'de-DE' },
2182
1926
  { provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
2183
1927
  { provide: MAT_LUXON_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true, firstDayOfWeek: 1 } },
2184
- ], template: "<mat-card>\n <mat-card-header>\n <mat-card-title> Zeitlicher Vergleich </mat-card-title>\n </mat-card-header>\n <mat-card-content [formGroup]=\"inputGroup\">\n <!-- start date -->\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\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<!--\n <mat-hint>d.M.yyyy</mat-hint>\n-->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker1 [startAt]=\"inputGroup.controls.start.defaultValue\">\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker2 [startAt]=\"inputGroup.controls.end.value\">\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n </mat-card-content>\n</mat-card>\n" }]
1928
+ ], template: "<div [formGroup]=\"inputGroup\">\n <!-- start date -->\n <mat-form-field>\n <mat-label>Zeitpunkt 1</mat-label>\n <input matInput\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker1\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker1 [startAt]=\"inputGroup.controls.start.defaultValue\">\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 <!--\n <mat-hint>d.M.yyyy</mat-hint>\n -->\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker [disabled]=\"disabled\" #picker2 [startAt]=\"inputGroup.controls.end.value\">\n </mat-datepicker>\n </mat-form-field>\n <!-- /end date -->\n</div>\n" }]
2185
1929
  }], ctorParameters: () => [], propDecorators: { disabled: [{
2186
1930
  type: Input
2187
1931
  }], inputGroup: [{
@@ -2264,7 +2008,7 @@ class ProgressSpinnerComponent {
2264
2008
  : this.overlayRef.detach();
2265
2009
  }
2266
2010
  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 }); }
2267
- 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$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
2011
+ 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"] }] }); }
2268
2012
  }
2269
2013
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressSpinnerComponent, decorators: [{
2270
2014
  type: Component,
@@ -2286,143 +2030,279 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2286
2030
  args: ['progressSpinnerRef', { static: true }]
2287
2031
  }] } });
2288
2032
 
2289
- class DonutChartPipe {
2290
- transform(donutSlices, radius, svgSize, borderSize) {
2291
- let previousPercent = 0;
2292
- return donutSlices.map(slice => {
2293
- // this is a hack to that the circle is rendered when the percent is 100
2294
- slice.percent = slice.percent === 100 ? 99.999 : slice.percent;
2295
- const sliceWithCommands = {
2296
- ...slice,
2297
- commands: `${this.getSliceCommands(slice, radius, svgSize, borderSize)} z`,
2298
- offset: previousPercent * 3.6 * -1,
2299
- };
2300
- previousPercent += slice.percent;
2301
- return sliceWithCommands;
2302
- });
2033
+ class ScrollMarkerDirective {
2034
+ constructor() {
2035
+ this.element = inject(ElementRef);
2303
2036
  }
2304
- getSliceCommands(donutSlice, radius, svgSize, borderSize) {
2305
- const degrees = this.percentToDegrees(donutSlice.percent);
2306
- const longPathFlag = degrees > 180 ? 1 : 0;
2307
- const innerRadius = radius - borderSize;
2308
- const commands = [];
2309
- commands.push(`M ${svgSize / 2 + radius} ${svgSize / 2}`);
2310
- commands.push(`A ${radius} ${radius} 0 ${longPathFlag} 0 ${this.getCoordFromDegrees(degrees, radius, svgSize)}`);
2311
- commands.push(`L ${this.getCoordFromDegrees(degrees, innerRadius, svgSize)}`);
2312
- commands.push(`A ${innerRadius} ${innerRadius} 0 ${longPathFlag} 1 ${svgSize / 2 + innerRadius} ${svgSize / 2}`);
2313
- return commands.join(' ');
2037
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2038
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ScrollMarkerDirective, isStandalone: true, selector: "[metaqs2ScrollMarker]", ngImport: i0 }); }
2039
+ }
2040
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScrollMarkerDirective, decorators: [{
2041
+ type: Directive,
2042
+ args: [{
2043
+ selector: '[metaqs2ScrollMarker]',
2044
+ standalone: true,
2045
+ }]
2046
+ }] });
2047
+
2048
+ /**
2049
+ * This class is a thin wrapper around the API services.
2050
+ */
2051
+ class MetaApiService {
2052
+ constructor(collectionsAPI, replicationsAPI, filterAPI, editorsAPI) {
2053
+ this.collectionsAPI = collectionsAPI;
2054
+ this.replicationsAPI = replicationsAPI;
2055
+ this.filterAPI = filterAPI;
2056
+ this.editorsAPI = editorsAPI;
2314
2057
  }
2315
- getCoordFromDegrees(angle, radius, svgSize) {
2316
- const x = Math.cos(angle * Math.PI / 180);
2317
- const y = Math.sin(angle * Math.PI / 180);
2318
- const coordX = x * radius + svgSize / 2;
2319
- const coordY = y * -radius + svgSize / 2;
2320
- return `${coordX} ${coordY}`;
2058
+ /**
2059
+ * Get the filters for the quality matrix.
2060
+ * It pipes the observable to take only one value.
2061
+ */
2062
+ getSearchFilters() {
2063
+ return this.filterAPI.getQualitxMatrixFilters().pipe(take(1));
2321
2064
  }
2322
- percentToDegrees(percent) {
2323
- return percent * 3.6;
2065
+ getCategoryFilters() {
2066
+ return this.getSearchFilters().pipe(map((filters) => filters.filter((filter) => filter.field !== 'timerange')));
2324
2067
  }
2325
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2326
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, name: "slicesWithCommandsAndOffset" }); }
2068
+ getCollectionsFilter() {
2069
+ return this.collectionsAPI.getTopLevelCollection();
2070
+ }
2071
+ /**
2072
+ * Get the timerange filter for the quality matrix.
2073
+ * Returns the first filter of the historical timerange filters.
2074
+ */
2075
+ getTimerangeFilter() {
2076
+ return this.filterAPI.getHistoricalTimerange().pipe(take(1), map((filters) => filters[0]));
2077
+ }
2078
+ getMaterialCountMatrixPerCollection(nodeRef, oerOnly) {
2079
+ return this.collectionsAPI.getMaterialCountMatrixPerCollection(nodeRef, oerOnly);
2080
+ }
2081
+ getCollectionCompleteness(colId) {
2082
+ return this.collectionsAPI.getCompleteness(colId);
2083
+ }
2084
+ getQualityMatrixWithFiltersV2(body) {
2085
+ return this.replicationsAPI.getQualityMatrixV2(body);
2086
+ }
2087
+ getEditorialMaterialCounts(body) {
2088
+ return this.editorsAPI.getMaterialCount(body);
2089
+ }
2090
+ getMaterialTypeCountsByReplicationSource(body) {
2091
+ return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndType(body);
2092
+ }
2093
+ getLicenseCountsByReplicationSource(body) {
2094
+ return this.replicationsAPI.getMaterialCountMatrixByReplicationSourceAndLicense(body);
2095
+ }
2096
+ getMaterialCountMatrixByLicenseGroup(body) {
2097
+ return this.editorsAPI.getMaterialCountMatrixByLicenseGroup(body);
2098
+ }
2099
+ getCompletenessForDisciplinaryPortals(body) {
2100
+ return this.editorsAPI.getCompletenessForDisciplinaryPortals(body);
2101
+ }
2102
+ getCompletenessForReplicationSources(body) {
2103
+ return this.replicationsAPI.getCompletenessForReplicationSources(body);
2104
+ }
2105
+ getMaterialTypesMapping() {
2106
+ return this.filterAPI.getMaterialTypesMapping();
2107
+ }
2108
+ 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 }); }
2109
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, providedIn: 'root' }); }
2327
2110
  }
2328
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartPipe, decorators: [{
2329
- type: Pipe,
2111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetaApiService, decorators: [{
2112
+ type: Injectable,
2330
2113
  args: [{
2331
- name: 'slicesWithCommandsAndOffset',
2332
- pure: true,
2114
+ providedIn: 'root',
2333
2115
  }]
2334
- }] });
2116
+ }], ctorParameters: () => [{ type: CollectionAPIService }, { type: ReplicationSourceAPIService }, { type: FilterAPIService }, { type: EditorsAPIService }] });
2335
2117
 
2336
2118
  /**
2337
- * A donut chart component that displays a list of slices.
2338
- * The chart is divided into slices, each slice has a color and a label.
2339
- * Each slice is represented by a percentage of the total chart.
2340
- * borrowed from https://medium.com/@theAngularGuy/how-to-create-an-interactive-donut-chart-using-svg-107cbf0b5b6
2119
+ * This service provides methods to create links to the editorial desk with specific filters.
2120
+ */
2121
+ /* This map makes it easier for me to keep track which issues are mapped to which filters */
2122
+ const FilterNames2Issues = {
2123
+ //Lizenzen
2124
+ 'virtual:editorial_license': ['oer', 'other_cc', 'copyright', 'without_license'],
2125
+ //Materialtypen werden im Constructor gesetzt
2126
+ 'virtual:oeh_lrt': [],
2127
+ 'virtual:editorial_exclusion': [
2128
+ 'outdated',
2129
+ 'without_preview',
2130
+ 'without_title',
2131
+ 'without_description',
2132
+ 'without_url',
2133
+ 'without_type',
2134
+ 'without_taxonomy_id',
2135
+ 'without_education_level',
2136
+ 'without_target_group',
2137
+ 'without_license',
2138
+ 'without_publisher',
2139
+ ],
2140
+ };
2141
+ // 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
2142
+ const Issues2FilterNames = Object.entries(FilterNames2Issues).reduce((map, [key, value]) => {
2143
+ value.forEach((issue) => map.set(issue, key));
2144
+ return map;
2145
+ }, new Map());
2146
+ // maps our values to the values of the filter in the editorial desk
2147
+ const MapValuesForFilter = {
2148
+ 'virtual:editorial_exclusion': {
2149
+ outdated: null,
2150
+ without_preview: null,
2151
+ without_title: ['missing_title'],
2152
+ without_description: ['missing_description'],
2153
+ without_url: ['links'],
2154
+ without_type: ['missing_oeh_lrt'],
2155
+ without_taxonomy_id: ['without_taxonomy_id'],
2156
+ without_education_level: ['missing_educationalcontext'],
2157
+ without_target_group: ['missing_educationalintendedenduserrole'],
2158
+ without_license: ['missing_license'],
2159
+ without_publisher: ['missing_replicationsource'],
2160
+ },
2161
+ 'virtual:editorial_license': {
2162
+ oer: ['oer'],
2163
+ copyright: ['none_oer'],
2164
+ without_license: ['none'],
2165
+ },
2166
+ 'virtual:oeh_lrt': {},
2167
+ };
2168
+ /*
2169
+ This is a map from properties of a document to filter names
2341
2170
  */
2342
- class DonutChartComponent {
2171
+ const PROPERTIES2FILTERS = new Map([
2172
+ ['metadata.educationalContexts', 'ccm:educationalcontext'],
2173
+ ['metadata.disciplines', 'virtual:taxonid'],
2174
+ //["responsibility", "virtual:collection_id_primary"] // das zeigt auf "sammlungszugehörigkeit" und ist falsch
2175
+ ]);
2176
+ class EditorialLinkService {
2343
2177
  constructor() {
2344
- this.radius = 50;
2345
- this.viewBox = 100;
2346
- this.borderSize = 20;
2347
- this.strokeWidth = 5;
2348
- this.data = [];
2178
+ this.env = inject(ConfigHelperService);
2179
+ this.api = inject(MetaApiService);
2180
+ this.typesLoaded$ = new BehaviorSubject(false);
2181
+ this.api
2182
+ .getMaterialTypesMapping()
2183
+ .pipe(take(1))
2184
+ .subscribe((types) => {
2185
+ for (const [key, value] of Object.entries(types)) {
2186
+ Issues2FilterNames.set(key, 'virtual:oeh_lrt');
2187
+ MapValuesForFilter['virtual:oeh_lrt'][key] = value;
2188
+ }
2189
+ this.typesLoaded$.next(true);
2190
+ });
2349
2191
  }
2350
- ngOnInit() {
2351
- const sum = this.data?.reduce((accu, slice) => accu + slice.percent, 0);
2352
- if (sum !== 100) {
2353
- throw new Error(`The sum of all slices of the donut chart must equal to 100%. Found: ${sum}.`);
2192
+ openByReplicationsourceAndIssueTypeWithFilters(source, issue, selectedFilters) {
2193
+ const filters = {};
2194
+ filters['virtual:audit_filter'] = ['all'];
2195
+ filters['ccm:oeh_publisher_combined'] = [source];
2196
+ filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issue];
2197
+ for (const [field, values] of Object.entries(selectedFilters)) {
2198
+ if (values && values.length) {
2199
+ const editorialFiltername = PROPERTIES2FILTERS.get(field);
2200
+ filters[editorialFiltername] = values;
2201
+ }
2354
2202
  }
2203
+ const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2204
+ const params = new URLSearchParams();
2205
+ params.set('mode', 'audit');
2206
+ params.set('filters', JSON.stringify(filters));
2207
+ window.open(`${theUrl}?${params}`, 'editor_frontend');
2355
2208
  }
2356
- trackByFn(index, slice) {
2357
- return slice.id;
2209
+ openByCollectionAndIssueType(collectionId, issueType, pageTitle) {
2210
+ const filters = {};
2211
+ filters['virtual:audit_filter'] = ['all'];
2212
+ filters['virtual:editorial_exclusion'] = MapValuesForFilter['virtual:editorial_exclusion'][issueType];
2213
+ filters['virtual:collection_id_primary'] = [collectionId];
2214
+ const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2215
+ const params = new URLSearchParams();
2216
+ params.set('title', pageTitle);
2217
+ params.set('mode', 'audit');
2218
+ params.set('filters', JSON.stringify(filters));
2219
+ window.open(`${theUrl}?${params}`, 'editor_frontend');
2358
2220
  }
2359
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2360
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DonutChartComponent, selector: "metaqs2-donut-chart", inputs: { radius: "radius", viewBox: "viewBox", borderSize: "borderSize", strokeWidth: "strokeWidth", data: "data" }, ngImport: i0, template: `
2361
- <svg [attr.viewBox]="'0 0 ' + viewBox + ' ' + viewBox" *ngIf="data">
2362
- <path
2363
- *ngFor="
2364
- let slice of data | slicesWithCommandsAndOffset : radius : viewBox : borderSize;
2365
- trackBy: trackByFn;
2366
- let index = index
2367
- "
2368
- [attr.fill]="slice.color"
2369
- stroke="white"
2370
- paint-order="stroke"
2371
- stroke-opacity="1"
2372
- [attr.stroke-width]="strokeWidth"
2373
- [attr.d]="slice.commands"
2374
- [attr.transform]="'rotate(' + slice.offset + ')'"
2375
- (click)="slice.onClickCb?.()"
2376
- >
2377
- <title>{{ slice.label }}</title>
2378
- </path>
2379
- </svg>
2380
- `, isInline: true, styles: [":host{display:block}svg{overflow:visible;transform-origin:center;width:3.5rem;aspect-ratio:1/1;rotate:-90deg}path{transform-origin:center;fill-opacity:.7;cursor:pointer}path:hover{fill-opacity:1}\n"], dependencies: [{ kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: DonutChartPipe, name: "slicesWithCommandsAndOffset" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2221
+ openByCollectionId(collectionId) {
2222
+ const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2223
+ const params = new URLSearchParams();
2224
+ params.set('ids', collectionId);
2225
+ params.set('mode', 'render');
2226
+ window.open(`${theUrl}?${params}`, 'editor_frontend');
2227
+ }
2228
+ /**
2229
+ * This method creates a link to the editorial desk with specific filters.
2230
+ * It returns the URL to the editorial desk with the filters applied or null if the issueId is not mapped to a filter.
2231
+ * With this we can render a link with an href attribute to the editorial desk in the frontend.
2232
+ * @see the counts-with-history.component.scss how we style links only if their hrefs are not null
2233
+ *
2234
+ * @param sourceType The type of the source, e.g. "replicationSource" or "collection"
2235
+ * @param sourceId The id of the source. This is the first column in the table.
2236
+ * @param issueId The id of the issue. These are the other columns in the table.
2237
+ */
2238
+ createLinkForCountsWithHistory(sourceType, sourceId, issueId) {
2239
+ const filters = {};
2240
+ filters['virtual:audit_filter'] = ['all'];
2241
+ // determine the "main" filter
2242
+ if (sourceType === 'replicationSource') {
2243
+ filters['ccm:oeh_publisher_combined'] = [sourceId];
2244
+ }
2245
+ else if (sourceType === 'collection') {
2246
+ filters['virtual:collection_id_primary'] = [sourceId];
2247
+ }
2248
+ if (!Issues2FilterNames.has(issueId)) {
2249
+ return null;
2250
+ }
2251
+ const filterName = Issues2FilterNames.get(issueId);
2252
+ if (!filterName) {
2253
+ // console.debug("No filter name found for issue id: " + issueId);
2254
+ return null;
2255
+ }
2256
+ const filterValue = MapValuesForFilter[filterName][issueId];
2257
+ if (!filterValue) {
2258
+ // console.debug("No filter value found for issue id: " + issueId);
2259
+ return null;
2260
+ }
2261
+ filters[filterName] = filterValue;
2262
+ const theUrl = this.env.eduSharingPath + '/components/editorial-desk';
2263
+ const params = new URLSearchParams();
2264
+ params.set('mode', 'audit');
2265
+ params.set('filters', JSON.stringify(filters));
2266
+ return `${theUrl}?${params}`;
2267
+ }
2268
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2269
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, providedIn: 'root' }); }
2381
2270
  }
2382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DonutChartComponent, decorators: [{
2383
- type: Component,
2384
- args: [{ selector: 'metaqs2-donut-chart', changeDetection: ChangeDetectionStrategy.OnPush, template: `
2385
- <svg [attr.viewBox]="'0 0 ' + viewBox + ' ' + viewBox" *ngIf="data">
2386
- <path
2387
- *ngFor="
2388
- let slice of data | slicesWithCommandsAndOffset : radius : viewBox : borderSize;
2389
- trackBy: trackByFn;
2390
- let index = index
2391
- "
2392
- [attr.fill]="slice.color"
2393
- stroke="white"
2394
- paint-order="stroke"
2395
- stroke-opacity="1"
2396
- [attr.stroke-width]="strokeWidth"
2397
- [attr.d]="slice.commands"
2398
- [attr.transform]="'rotate(' + slice.offset + ')'"
2399
- (click)="slice.onClickCb?.()"
2400
- >
2401
- <title>{{ slice.label }}</title>
2402
- </path>
2403
- </svg>
2404
- `, styles: [":host{display:block}svg{overflow:visible;transform-origin:center;width:3.5rem;aspect-ratio:1/1;rotate:-90deg}path{transform-origin:center;fill-opacity:.7;cursor:pointer}path:hover{fill-opacity:1}\n"] }]
2405
- }], propDecorators: { radius: [{
2406
- type: Input
2407
- }], viewBox: [{
2408
- type: Input
2409
- }], borderSize: [{
2410
- type: Input
2411
- }], strokeWidth: [{
2412
- type: Input
2413
- }], data: [{
2414
- type: Input
2415
- }] } });
2271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EditorialLinkService, decorators: [{
2272
+ type: Injectable,
2273
+ args: [{
2274
+ providedIn: 'root',
2275
+ }]
2276
+ }], ctorParameters: () => [] });
2416
2277
 
2278
+ const openCloseTimeout = 150;
2417
2279
  class QualityMatrixComponent {
2418
- constructor(metaApi, linkService) {
2280
+ constructor(metaApi, linkService, overlay, tooltipService) {
2419
2281
  this.metaApi = metaApi;
2420
2282
  this.linkService = linkService;
2283
+ this.overlay = overlay;
2284
+ this.tooltipService = tooltipService;
2285
+ this.ref = inject(ElementRef);
2286
+ this.scrollLeft = signal(0);
2287
+ this.scrollWidth = signal(0);
2288
+ this.isLeftScrollable = computed(() => this.scrollLeft() > 0);
2289
+ this.isRightScrollable = computed(() => {
2290
+ const viewport = globalThis.visualViewport;
2291
+ if (!viewport) {
2292
+ return;
2293
+ }
2294
+ const viewportWidth = viewport.width;
2295
+ return this.scrollWidth() > viewportWidth && this.scrollLeft() + viewportWidth < this.scrollWidth();
2296
+ });
2297
+ this.issueTypeHeader = viewChild('issueType', {
2298
+ read: ElementRef,
2299
+ });
2421
2300
  this.filteredColumns = [];
2422
2301
  this.datatableColumns = [];
2423
2302
  this.showHistoricalData = new FormControl({ value: false, disabled: true });
2424
2303
  this.onlySourcesWithMaterial = new FormControl({ value: true, disabled: true });
2425
2304
  this.isLoading = signal(true);
2305
+ this.scrollMarkers = viewChildren(ScrollMarkerDirective);
2426
2306
  this.categoryFilterValues = new Map();
2427
2307
  this.recentQualityMatrix$ = new BehaviorSubject({ columns: [], rows: [] });
2428
2308
  this.pastQualityMatrix$ = new BehaviorSubject({ columns: [], rows: [] });
@@ -2430,8 +2310,9 @@ class QualityMatrixComponent {
2430
2310
  start: new FormControl(),
2431
2311
  end: new FormControl(),
2432
2312
  });
2433
- this.pageTitle = 'Quality Matrix';
2313
+ this.tooltips = new Map();
2434
2314
  this.DateTime = DateTime;
2315
+ this.pageTitle = 'Quality Matrix';
2435
2316
  // a FormRecord has to be initialized with one source to determine its type :-(
2436
2317
  this.categoryControls = new FormRecord({ dummy: new FormControl([], { nonNullable: true }) });
2437
2318
  this.categoryControls.removeControl('dummy', { emitEvent: false });
@@ -2444,6 +2325,9 @@ class QualityMatrixComponent {
2444
2325
  this.onLoadedDataChanges();
2445
2326
  //this.loadDataWithCurrentlySelectedFilters();
2446
2327
  }
2328
+ ngAfterViewChecked() {
2329
+ this.onScroll();
2330
+ }
2447
2331
  filterIdent(_index, item) {
2448
2332
  return item.key;
2449
2333
  }
@@ -2597,47 +2481,177 @@ class QualityMatrixComponent {
2597
2481
  }
2598
2482
  }
2599
2483
  getDonutSlices(row, column) {
2600
- let sufficientfillRate = 0;
2601
- let insufficientfillRate = 0;
2602
- //Der Wert berechnet sich aus dem total_count - without_description_count.
2603
- if (column.total !== 0) {
2604
- sufficientfillRate = Math.round((100 * row.counts[column.id].sufficient) / column.total);
2605
- insufficientfillRate = Math.round((100 * row.counts[column.id].insufficient) / column.total);
2606
- }
2607
2484
  const sufficientTotal = row.counts[column.id].sufficient;
2608
2485
  const insufficientTotal = row.counts[column.id].insufficient;
2609
2486
  const missingTotal = column.total - sufficientTotal - insufficientTotal;
2610
- const rest = 100 - (sufficientfillRate + insufficientfillRate); // a.k.a. "missing"
2611
- const slices = [
2487
+ let sufficientFillRate = 0;
2488
+ let insufficientFillRate = 0;
2489
+ //Der Wert berechnet sich aus dem total_count - without_description_count.
2490
+ if (column.total !== 0) {
2491
+ sufficientFillRate = Math.round((100 * sufficientTotal) / column.total);
2492
+ insufficientFillRate = Math.round((100 * insufficientTotal) / column.total);
2493
+ }
2494
+ const rest = 100 - (sufficientFillRate + insufficientFillRate); // a.k.a. "missing"
2495
+ return [
2612
2496
  {
2613
2497
  id: 3,
2614
2498
  percent: rest,
2615
2499
  color: '#D8EDFC',
2616
2500
  label: `${rest} % (${missingTotal})`,
2501
+ verboseLabel: `${missingTotal} Metadatens\u00e4tze fehlen`,
2617
2502
  },
2618
2503
  {
2619
2504
  id: 1,
2620
- percent: insufficientfillRate,
2505
+ percent: insufficientFillRate,
2621
2506
  color: '#C20808',
2622
- label: `${insufficientfillRate} % (${insufficientTotal})`,
2507
+ label: `${insufficientFillRate} % (${insufficientTotal})`,
2508
+ verboseLabel: `${insufficientTotal} Metadatens\u00e4tze sind unzureichend ausgef\u00fcllt`,
2623
2509
  },
2624
2510
  {
2625
2511
  id: 2,
2626
- percent: sufficientfillRate,
2512
+ percent: sufficientFillRate,
2627
2513
  color: '#4ABEFF',
2628
- label: `${sufficientfillRate} % (${sufficientTotal})`,
2514
+ label: `${sufficientFillRate} % (${sufficientTotal})`,
2515
+ verboseLabel: `${sufficientTotal} Metadatens\u00e4tze sind gut ausgef\u00fcllt`,
2629
2516
  },
2630
2517
  ];
2631
- return slices;
2632
2518
  }
2633
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, deps: [{ token: MetaApiService }, { token: EditorialLinkService }], target: i0.ɵɵFactoryTarget.Component }); }
2634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: QualityMatrixComponent, selector: "metaqs2-quality-matrix-v2", inputs: { pageTitle: "pageTitle" }, 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>\n <metaqs2-qm-filter\n *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\"></metaqs2-qm-filter>\n </mat-card-content>\n <mat-card-actions align=\"end\">\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"onlySourcesWithMaterial\" id=\"onlySourcesWithMaterial\" >\n show only sources with material\n </mat-slide-toggle>\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 </mat-card-actions>\n</mat-card>\n<metaqs2-datepicker *ngIf=\"showHistoricalData.value\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" ></metaqs2-datepicker>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [ngClass]=\"{'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>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\" 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\">\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}.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}\n"], dependencies: [{ kind: "directive", type: i2$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { 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: i1$4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.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: "component", type: i6$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: "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: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: QualityMatrixFilterComponent, selector: "metaqs2-qm-filter", inputs: ["options", "inputFormControl", "label", "multiple"], outputs: ["changedFilters"] }, { kind: "component", type: DatepickerComponent, selector: "metaqs2-datepicker", inputs: ["disabled", "inputGroup"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }, { kind: "component", type: DonutChartComponent, selector: "metaqs2-donut-chart", inputs: ["radius", "viewBox", "borderSize", "strokeWidth", "data"] }, { kind: "pipe", type: i2$2.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }] }); }
2519
+ showTooltip(row, column, cell) {
2520
+ if (row.counts[column.id].sufficient + row.counts[column.id].insufficient === 0) {
2521
+ return;
2522
+ }
2523
+ if (this.tooltips.has(cell)) {
2524
+ this.tooltips.get(cell).cancelCloseAction();
2525
+ return;
2526
+ }
2527
+ const tooltipRef = this.tooltipService.create(DonutChartTooltipComponent, {
2528
+ closeTimeout: openCloseTimeout,
2529
+ openTimeout: openCloseTimeout,
2530
+ data: {
2531
+ label: column.label,
2532
+ data: transformDonutChartData(this.getDonutSlices(row, column)),
2533
+ },
2534
+ overlayConfig: {
2535
+ hasBackdrop: false,
2536
+ positionStrategy: this.overlay.position().flexibleConnectedTo(cell).withPositions(centerPositionStrategy),
2537
+ disposeOnNavigation: true,
2538
+ panelClass: 'donut-chart-tooltip',
2539
+ },
2540
+ onClose: () => {
2541
+ this.tooltips.delete(cell);
2542
+ },
2543
+ });
2544
+ tooltipRef.open();
2545
+ this.tooltips.set(cell, tooltipRef);
2546
+ }
2547
+ hideTooltip(cell) {
2548
+ this.tooltips.get(cell)?.markForClose();
2549
+ }
2550
+ findHorizontalScrollContainer(element) {
2551
+ if (element.scrollWidth > element.clientWidth && ['auto', 'scroll'].includes(getComputedStyle(element).overflowX)) {
2552
+ // find the nearest horizontally scrollable element
2553
+ return element;
2554
+ }
2555
+ else {
2556
+ if (!element.parentElement) {
2557
+ return document.scrollingElement;
2558
+ }
2559
+ return this.findHorizontalScrollContainer(element.parentElement);
2560
+ }
2561
+ }
2562
+ scrollToRight() {
2563
+ const scrollingElement = this.findHorizontalScrollContainer(this.ref.nativeElement);
2564
+ if (!scrollingElement) {
2565
+ return;
2566
+ }
2567
+ const viewport = globalThis.visualViewport;
2568
+ if (!viewport) {
2569
+ return;
2570
+ }
2571
+ const viewportWidth = viewport.width;
2572
+ const lastVisible = this.scrollMarkers().findLast((marker) => marker.element.nativeElement.getBoundingClientRect().left < viewportWidth);
2573
+ if (!lastVisible) {
2574
+ return;
2575
+ }
2576
+ const leftColumnWidth = this.issueTypeHeader()?.nativeElement.getBoundingClientRect().width ?? 0;
2577
+ scrollingElement.scrollBy({
2578
+ left: lastVisible.element.nativeElement.getBoundingClientRect().left - leftColumnWidth,
2579
+ behavior: 'smooth',
2580
+ });
2581
+ }
2582
+ scrollToLeft() {
2583
+ const scrollingElement = this.findHorizontalScrollContainer(this.ref.nativeElement);
2584
+ if (!scrollingElement) {
2585
+ return;
2586
+ }
2587
+ const viewport = globalThis.visualViewport;
2588
+ if (!viewport) {
2589
+ return;
2590
+ }
2591
+ const viewportWidth = viewport.width;
2592
+ const leftColumnWidth = this.issueTypeHeader()?.nativeElement.getBoundingClientRect().width ?? 0;
2593
+ const firstVisible = this.scrollMarkers().find((marker) => marker.element.nativeElement.getBoundingClientRect().right > leftColumnWidth);
2594
+ if (!firstVisible) {
2595
+ return;
2596
+ }
2597
+ scrollingElement.scrollBy({
2598
+ left: firstVisible.element.nativeElement.getBoundingClientRect().right - viewportWidth,
2599
+ behavior: 'smooth',
2600
+ });
2601
+ }
2602
+ onScroll() {
2603
+ const scrollingElement = this.findHorizontalScrollContainer(this.ref.nativeElement);
2604
+ if (!scrollingElement) {
2605
+ return;
2606
+ }
2607
+ this.scrollLeft.set(scrollingElement.scrollLeft);
2608
+ this.scrollWidth.set(scrollingElement.scrollWidth);
2609
+ }
2610
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, deps: [{ token: MetaApiService }, { token: EditorialLinkService }, { token: i1$3.Overlay }, { token: TooltipService }], target: i0.ɵɵFactoryTarget.Component }); }
2611
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.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, isSignal: true }, { propertyName: "scrollMarkers", predicate: ScrollMarkerDirective, descendants: true, isSignal: 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 <metaqs2-datepicker *ngIf=\"showHistoricalData.value\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" />\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"onlySourcesWithMaterial\" id=\"onlySourcesWithMaterial\" >\n show only sources with material\n </mat-slide-toggle>\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 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 style=\"flex: 1 0 {{scroller.getBoundingClientRect().width}}px\"></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{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]" }] }); }
2635
2612
  }
2636
2613
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: QualityMatrixComponent, decorators: [{
2637
2614
  type: Component,
2638
- args: [{ selector: 'metaqs2-quality-matrix-v2', 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>\n <metaqs2-qm-filter\n *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\"></metaqs2-qm-filter>\n </mat-card-content>\n <mat-card-actions align=\"end\">\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"onlySourcesWithMaterial\" id=\"onlySourcesWithMaterial\" >\n show only sources with material\n </mat-slide-toggle>\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 </mat-card-actions>\n</mat-card>\n<metaqs2-datepicker *ngIf=\"showHistoricalData.value\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" ></metaqs2-datepicker>\n<mat-card>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n <table [ngClass]=\"{'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>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\" 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\">\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}.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}\n"] }]
2639
- }], ctorParameters: () => [{ type: MetaApiService }, { type: EditorialLinkService }], propDecorators: { pageTitle: [{
2615
+ args: [{ selector: 'metaqs2-quality-matrix-v2', providers: [TooltipService], standalone: true, imports: [
2616
+ MatCard,
2617
+ MatCardHeader,
2618
+ MatCardTitle,
2619
+ MatCardContent,
2620
+ QualityMatrixFilterComponent,
2621
+ TranslateModule,
2622
+ KeyValuePipe,
2623
+ MatIcon,
2624
+ DatepickerComponent,
2625
+ MatSlideToggle,
2626
+ ReactiveFormsModule,
2627
+ ProgressSpinnerComponent,
2628
+ MatTable,
2629
+ MatTooltip,
2630
+ MatCell,
2631
+ MatColumnDef,
2632
+ MatHeaderCell,
2633
+ NgClass,
2634
+ MatHeaderRow,
2635
+ MatRow,
2636
+ MatHeaderRowDef,
2637
+ MatRowDef,
2638
+ MatHeaderCellDef,
2639
+ NgForOf,
2640
+ NgIf,
2641
+ MatCellDef,
2642
+ MatButton,
2643
+ MatIconButton,
2644
+ DonutChartComponent,
2645
+ ScrollMarkerDirective,
2646
+ ], 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 <metaqs2-datepicker *ngIf=\"showHistoricalData.value\" [disabled]=\"isLoading()\" [inputGroup]=\"range\" />\n <mat-slide-toggle [disabled]=\"isLoading()\" labelPosition=\"before\" [formControl]=\"onlySourcesWithMaterial\" id=\"onlySourcesWithMaterial\" >\n show only sources with material\n </mat-slide-toggle>\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 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 style=\"flex: 1 0 {{scroller.getBoundingClientRect().width}}px\"></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{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"] }]
2647
+ }], ctorParameters: () => [{ type: MetaApiService }, { type: EditorialLinkService }, { type: i1$3.Overlay }, { type: TooltipService }], propDecorators: { pageTitle: [{
2640
2648
  type: Input
2649
+ }], onScroll: [{
2650
+ type: HostListener,
2651
+ args: ['window:scroll']
2652
+ }, {
2653
+ type: HostListener,
2654
+ args: ['window:resize']
2641
2655
  }] } });
2642
2656
 
2643
2657
  class NodeImageUrlPipe {
@@ -2683,7 +2697,7 @@ class NodeEntryComponent {
2683
2697
  // return (this.node as MaterialCounts).materials_count !== undefined;
2684
2698
  }
2685
2699
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NodeEntryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2686
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NodeEntryComponent, selector: "metaqs2-node-entry", inputs: { node: "node" }, outputs: { edit: "edit" }, ngImport: i0, template: "<div class=\"node\">\n <img class=\"icon\" [src]=\"node | nodeImageUrl\" loading=\"lazy\" />\n <div class=\"text\">\n <span class=\"title\">{{ node.title }}</span>\n <span class=\"description\" *ngIf=\"!isCollectionCount()\">{{ node.description }}</span>\n <span class=\"count\" *ngIf=\"isCollectionCount()\">{{ $any(node).materials_count }} Materialien</span>\n </div>\n <div class=\"actions\">\n <button mat-icon-button color=\"primary\" (click)=\"openNode(node)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n <button *ngIf=\"$any(node).type === 'ccm:io'\" mat-icon-button color=\"primary\" (click)=\"edit.emit(node)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.node{display:flex;align-items:center;padding:5px 0}.node .icon{width:50px;min-width:50px;height:50px;object-fit:cover;padding-right:10px}.node .text{flex-grow:1;display:flex;flex-direction:column}.node .text .title{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;word-break:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical}.node .text .description,.node .text .count{font-size:90%;color:#555;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;word-break:break-word;-webkit-line-clamp:1;-webkit-box-orient:vertical}.node .actions{display:flex}\n"], dependencies: [{ kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "pipe", type: NodeImageUrlPipe, name: "nodeImageUrl" }] }); }
2700
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NodeEntryComponent, selector: "metaqs2-node-entry", inputs: { node: "node" }, outputs: { edit: "edit" }, ngImport: i0, template: "<div class=\"node\">\n <img class=\"icon\" [src]=\"node | nodeImageUrl\" loading=\"lazy\" />\n <div class=\"text\">\n <span class=\"title\">{{ node.title }}</span>\n <span class=\"description\" *ngIf=\"!isCollectionCount()\">{{ node.description }}</span>\n <span class=\"count\" *ngIf=\"isCollectionCount()\">{{ $any(node).materials_count }} Materialien</span>\n </div>\n <div class=\"actions\">\n <button mat-icon-button color=\"primary\" (click)=\"openNode(node)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n <button *ngIf=\"$any(node).type === 'ccm:io'\" mat-icon-button color=\"primary\" (click)=\"edit.emit(node)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.node{display:flex;align-items:center;padding:5px 0}.node .icon{width:50px;min-width:50px;height:50px;object-fit:cover;padding-right:10px}.node .text{flex-grow:1;display:flex;flex-direction:column}.node .text .title{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;word-break:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical}.node .text .description,.node .text .count{font-size:90%;color:#555;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;word-break:break-word;-webkit-line-clamp:1;-webkit-box-orient:vertical}.node .actions{display:flex}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "pipe", type: NodeImageUrlPipe, name: "nodeImageUrl" }] }); }
2687
2701
  }
2688
2702
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NodeEntryComponent, decorators: [{
2689
2703
  type: Component,
@@ -2703,9 +2717,13 @@ class NodeListComponent {
2703
2717
  */
2704
2718
  this.countChanged = new EventEmitter();
2705
2719
  /**
2706
- * default max count of nodes that should be shown
2720
+ * default max count of nodes that should be shown in view
2707
2721
  */
2708
2722
  this.DEFAULT_LIMIT = 25;
2723
+ /**
2724
+ * default count to fetch from api
2725
+ */
2726
+ this.FETCH_LIMIT = 200;
2709
2727
  this.data = new BehaviorSubject(undefined);
2710
2728
  // rawData: (MaterialWithMissingAttributes | CollectionWithMissingAttributes)[] | undefined;
2711
2729
  this.count = 0;
@@ -2714,9 +2732,9 @@ class NodeListComponent {
2714
2732
  * should all nodes be shown?
2715
2733
  */
2716
2734
  this.showAll = false;
2717
- this.data.pipe(takeUntil(this.destroyed$)).subscribe((d) => this.countChanged.next(d?.length || 0));
2735
+ this.data.pipe(takeUntil(this.destroyed$)).subscribe((d) => this.countChanged.next(d?.total || 0));
2718
2736
  }
2719
- async ngOnChanges(changes) {
2737
+ async ngOnChanges(_changes) {
2720
2738
  if (this.collectionId) {
2721
2739
  await this.refresh();
2722
2740
  }
@@ -2728,10 +2746,10 @@ class NodeListComponent {
2728
2746
  async refresh() {
2729
2747
  let getByMissingAttribute = () => {
2730
2748
  if (this.type === 'material') {
2731
- return this.collectionAPIService.getMaterialsWithMissingAttribute(this.collectionId, this.mode);
2749
+ return this.collectionAPIService.getMaterialsWithMissingAttribute(this.collectionId, this.mode, 0, this.FETCH_LIMIT);
2732
2750
  }
2733
2751
  else {
2734
- return this.collectionAPIService.getCollectionsWithMissingAttribute(this.collectionId, this.mode);
2752
+ return this.collectionAPIService.getCollectionsWithMissingAttribute(this.collectionId, this.mode, 0, this.FETCH_LIMIT);
2735
2753
  }
2736
2754
  };
2737
2755
  // reset all data before switching
@@ -2760,7 +2778,7 @@ class NodeListComponent {
2760
2778
  action = 'OPTIONS.EDIT';
2761
2779
  }
2762
2780
  const id = node.node_id;
2763
- const win = window.open(this.env.eduSharingPath +
2781
+ window.open(this.env.eduSharingPath +
2764
2782
  '/components/editorial-desk?mode=audit&viewType=single&ids=' +
2765
2783
  encodeURIComponent(id) +
2766
2784
  '&action=' +
@@ -2771,11 +2789,11 @@ class NodeListComponent {
2771
2789
  // this.data = this.rawData?.filter((d) => (d as MaterialCounts).materials_count <= (this.count ?? 0));
2772
2790
  }
2773
2791
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NodeListComponent, deps: [{ token: CollectionAPIService }], target: i0.ɵɵFactoryTarget.Component }); }
2774
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NodeListComponent, selector: "metaqs2-node-list", inputs: { mode: "mode", type: "type", collectionId: "collectionId" }, outputs: { countChanged: "countChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"wrapper\">\n <mat-card *ngIf=\"mode\">\n <mat-card-header>\n <mat-card-title>\n {{ 'issues.' + mode | translate }}\n <span class=\"count\" *ngIf=\"(data | async) as d\">({{ d.length || 0 }})</span>\n </mat-card-title>\n <button mat-icon-button color=\"primary\" [disabled]=\"!(data | async)\" (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-card-header>\n <!-- @TODO -->\n <div *ngIf=\"type === 'collection' && mode === 'TODO_count'\" class=\"count-slider\">\n <label>Sammlungen mit {{ count }} oder weniger Inhalten</label>\n <mat-slider\n [showTickMarks]=\"true\"\n step=\"1\"\n [ngModel]=\"count\"\n (ngModelChange)=\"count = $event; filterCount()\"\n min=\"0\"\n max=\"10\"\n ></mat-slider>\n </div>\n <ng-container *ngIf=\"wrappedData$ | async as wrappedData\">\n <mat-spinner *ngIf=\"wrappedData.state === 'loading'\" diameter=\"40\" color=\"primary\"></mat-spinner>\n <div class=\"error\" *ngIf=\"wrappedData.state === 'error'\">\n <p class=\"error-text\">Etwas ist schief gelaufen.</p>\n </div>\n <div class=\"scroll\" *ngIf=\"wrappedData.state === 'success'\">\n <ng-container *ngIf=\"(data | async) as d\">\n <metaqs2-node-entry\n *ngFor=\"let node of DEFAULT_LIMIT < d.length && !showAll ? d.slice(0, DEFAULT_LIMIT) : d\"\n [node]=\"node\"\n (edit)=\"editNode(node)\"\n ></metaqs2-node-entry>\n <div *ngIf=\"!d.length\">\n <div class=\"all-done\">\n <p class=\"all-done-emoji\">\uD83E\uDD73</p>\n <p class=\"all-done-text\">Keine Elemente ausstehend</p>\n </div>\n </div>\n <button *ngIf=\"DEFAULT_LIMIT < d.length && !showAll\" (click)=\"showAll = true\" color=\"primary\" mat-button>\n Alle Elemente anzeigen <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </mat-card>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.wrapper{width:100%;height:100%}.wrapper mat-card{display:flex;flex-direction:column;width:100%;height:100%;padding:0;box-shadow:none}.wrapper mat-card ::ng-deep mat-card-header{align-items:center}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.wrapper mat-card .count-slider{display:flex;flex-direction:column;width:100%}.wrapper mat-card .count-slider>label{padding:0 20px;font-size:90%}.wrapper mat-card .count-slider>mat-slider{width:100%}.wrapper mat-card mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20%}.wrapper mat-card .scroll{flex-grow:1;overflow-y:auto}.wrapper mat-card .scroll>button{display:flex;margin:auto}.wrapper mat-card .scroll .all-done{display:flex;flex-direction:column;align-items:center}.wrapper mat-card .scroll .all-done .all-done-emoji{font-size:72px;margin-bottom:20px}.wrapper mat-card .scroll .all-done .all-done-text{text-align:center;font-size:1.3em;color:var(--font-light)}.wrapper mat-card .error{border:#d00 solid 2px;background-color:#d005;display:flex;flex-direction:column;align-items:center}.wrapper mat-card .error .error-text{font-size:1.3em}\n"], dependencies: [{ kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: i1$4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "component", type: i6$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i2$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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: NodeEntryComponent, selector: "metaqs2-node-entry", inputs: ["node"], outputs: ["edit"] }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }] }); }
2792
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NodeListComponent, selector: "metaqs2-node-list", inputs: { mode: "mode", type: "type", collectionId: "collectionId" }, outputs: { countChanged: "countChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"wrapper\">\n <mat-card *ngIf=\"mode\">\n <mat-card-header>\n <mat-card-title>\n {{ 'issues.' + mode | translate }}\n <span class=\"count\" *ngIf=\"(data | async) as d\">({{ d.total || 0 }})</span>\n </mat-card-title>\n <button mat-icon-button color=\"primary\" [disabled]=\"!(data | async)\" (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-card-header>\n <!-- @TODO -->\n <div *ngIf=\"type === 'collection' && mode === 'TODO_count'\" class=\"count-slider\">\n <label>Sammlungen mit {{ count }} oder weniger Inhalten</label>\n <mat-slider\n [showTickMarks]=\"true\"\n step=\"1\"\n [ngModel]=\"count\"\n (ngModelChange)=\"count = $event; filterCount()\"\n min=\"0\"\n max=\"10\"\n ></mat-slider>\n </div>\n <ng-container *ngIf=\"wrappedData$ | async as wrappedData\">\n <mat-spinner *ngIf=\"wrappedData.state === 'loading'\" diameter=\"40\" color=\"primary\"></mat-spinner>\n <div class=\"error\" *ngIf=\"wrappedData.state === 'error'\">\n <p class=\"error-text\">Etwas ist schief gelaufen.</p>\n </div>\n <div class=\"scroll\" *ngIf=\"wrappedData.state === 'success'\">\n <ng-container *ngIf=\"(data | async) as d\">\n <metaqs2-node-entry\n *ngFor=\"let node of DEFAULT_LIMIT < (d?.total || 0) && !showAll ? $any(d.materials || d.collections)?.slice(0, DEFAULT_LIMIT) : (d.materials || d.collections)\"\n [node]=\"node\"\n (edit)=\"editNode(node)\"\n ></metaqs2-node-entry>\n <div *ngIf=\"!d.total\">\n <div class=\"all-done\">\n <p class=\"all-done-emoji\">\uD83E\uDD73</p>\n <p class=\"all-done-text\">Keine Elemente ausstehend</p>\n </div>\n </div>\n <button *ngIf=\"DEFAULT_LIMIT < (d?.total || 0) && !showAll\" (click)=\"showAll = true\" color=\"primary\" mat-button>\n Alle Elemente anzeigen <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </mat-card>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.wrapper{width:100%;height:100%}.wrapper mat-card{display:flex;flex-direction:column;width:100%;height:100%;padding:0;box-shadow:none}.wrapper mat-card ::ng-deep mat-card-header{align-items:center}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.wrapper mat-card .count-slider{display:flex;flex-direction:column;width:100%}.wrapper mat-card .count-slider>label{padding:0 20px;font-size:90%}.wrapper mat-card .count-slider>mat-slider{width:100%}.wrapper mat-card mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20%}.wrapper mat-card .scroll{flex-grow:1;overflow-y:auto}.wrapper mat-card .scroll>button{display:flex;margin:auto}.wrapper mat-card .scroll .all-done{display:flex;flex-direction:column;align-items:center}.wrapper mat-card .scroll .all-done .all-done-emoji{font-size:72px;margin-bottom:20px}.wrapper mat-card .scroll .all-done .all-done-text{text-align:center;font-size:1.3em;color:var(--font-light)}.wrapper mat-card .error{border:#d00 solid 2px;background-color:#d005;display:flex;flex-direction:column;align-items:center}.wrapper mat-card .error .error-text{font-size:1.3em}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: i1$4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i2$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { 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: NodeEntryComponent, selector: "metaqs2-node-entry", inputs: ["node"], outputs: ["edit"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }] }); }
2775
2793
  }
2776
2794
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NodeListComponent, decorators: [{
2777
2795
  type: Component,
2778
- args: [{ selector: 'metaqs2-node-list', template: "<div class=\"wrapper\">\n <mat-card *ngIf=\"mode\">\n <mat-card-header>\n <mat-card-title>\n {{ 'issues.' + mode | translate }}\n <span class=\"count\" *ngIf=\"(data | async) as d\">({{ d.length || 0 }})</span>\n </mat-card-title>\n <button mat-icon-button color=\"primary\" [disabled]=\"!(data | async)\" (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-card-header>\n <!-- @TODO -->\n <div *ngIf=\"type === 'collection' && mode === 'TODO_count'\" class=\"count-slider\">\n <label>Sammlungen mit {{ count }} oder weniger Inhalten</label>\n <mat-slider\n [showTickMarks]=\"true\"\n step=\"1\"\n [ngModel]=\"count\"\n (ngModelChange)=\"count = $event; filterCount()\"\n min=\"0\"\n max=\"10\"\n ></mat-slider>\n </div>\n <ng-container *ngIf=\"wrappedData$ | async as wrappedData\">\n <mat-spinner *ngIf=\"wrappedData.state === 'loading'\" diameter=\"40\" color=\"primary\"></mat-spinner>\n <div class=\"error\" *ngIf=\"wrappedData.state === 'error'\">\n <p class=\"error-text\">Etwas ist schief gelaufen.</p>\n </div>\n <div class=\"scroll\" *ngIf=\"wrappedData.state === 'success'\">\n <ng-container *ngIf=\"(data | async) as d\">\n <metaqs2-node-entry\n *ngFor=\"let node of DEFAULT_LIMIT < d.length && !showAll ? d.slice(0, DEFAULT_LIMIT) : d\"\n [node]=\"node\"\n (edit)=\"editNode(node)\"\n ></metaqs2-node-entry>\n <div *ngIf=\"!d.length\">\n <div class=\"all-done\">\n <p class=\"all-done-emoji\">\uD83E\uDD73</p>\n <p class=\"all-done-text\">Keine Elemente ausstehend</p>\n </div>\n </div>\n <button *ngIf=\"DEFAULT_LIMIT < d.length && !showAll\" (click)=\"showAll = true\" color=\"primary\" mat-button>\n Alle Elemente anzeigen <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </mat-card>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.wrapper{width:100%;height:100%}.wrapper mat-card{display:flex;flex-direction:column;width:100%;height:100%;padding:0;box-shadow:none}.wrapper mat-card ::ng-deep mat-card-header{align-items:center}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.wrapper mat-card .count-slider{display:flex;flex-direction:column;width:100%}.wrapper mat-card .count-slider>label{padding:0 20px;font-size:90%}.wrapper mat-card .count-slider>mat-slider{width:100%}.wrapper mat-card mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20%}.wrapper mat-card .scroll{flex-grow:1;overflow-y:auto}.wrapper mat-card .scroll>button{display:flex;margin:auto}.wrapper mat-card .scroll .all-done{display:flex;flex-direction:column;align-items:center}.wrapper mat-card .scroll .all-done .all-done-emoji{font-size:72px;margin-bottom:20px}.wrapper mat-card .scroll .all-done .all-done-text{text-align:center;font-size:1.3em;color:var(--font-light)}.wrapper mat-card .error{border:#d00 solid 2px;background-color:#d005;display:flex;flex-direction:column;align-items:center}.wrapper mat-card .error .error-text{font-size:1.3em}\n"] }]
2796
+ args: [{ selector: 'metaqs2-node-list', template: "<div class=\"wrapper\">\n <mat-card *ngIf=\"mode\">\n <mat-card-header>\n <mat-card-title>\n {{ 'issues.' + mode | translate }}\n <span class=\"count\" *ngIf=\"(data | async) as d\">({{ d.total || 0 }})</span>\n </mat-card-title>\n <button mat-icon-button color=\"primary\" [disabled]=\"!(data | async)\" (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-card-header>\n <!-- @TODO -->\n <div *ngIf=\"type === 'collection' && mode === 'TODO_count'\" class=\"count-slider\">\n <label>Sammlungen mit {{ count }} oder weniger Inhalten</label>\n <mat-slider\n [showTickMarks]=\"true\"\n step=\"1\"\n [ngModel]=\"count\"\n (ngModelChange)=\"count = $event; filterCount()\"\n min=\"0\"\n max=\"10\"\n ></mat-slider>\n </div>\n <ng-container *ngIf=\"wrappedData$ | async as wrappedData\">\n <mat-spinner *ngIf=\"wrappedData.state === 'loading'\" diameter=\"40\" color=\"primary\"></mat-spinner>\n <div class=\"error\" *ngIf=\"wrappedData.state === 'error'\">\n <p class=\"error-text\">Etwas ist schief gelaufen.</p>\n </div>\n <div class=\"scroll\" *ngIf=\"wrappedData.state === 'success'\">\n <ng-container *ngIf=\"(data | async) as d\">\n <metaqs2-node-entry\n *ngFor=\"let node of DEFAULT_LIMIT < (d?.total || 0) && !showAll ? $any(d.materials || d.collections)?.slice(0, DEFAULT_LIMIT) : (d.materials || d.collections)\"\n [node]=\"node\"\n (edit)=\"editNode(node)\"\n ></metaqs2-node-entry>\n <div *ngIf=\"!d.total\">\n <div class=\"all-done\">\n <p class=\"all-done-emoji\">\uD83E\uDD73</p>\n <p class=\"all-done-text\">Keine Elemente ausstehend</p>\n </div>\n </div>\n <button *ngIf=\"DEFAULT_LIMIT < (d?.total || 0) && !showAll\" (click)=\"showAll = true\" color=\"primary\" mat-button>\n Alle Elemente anzeigen <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </mat-card>\n</div>\n", styles: [".while-loading{filter:blur(2px)}.wrapper{width:100%;height:100%}.wrapper mat-card{display:flex;flex-direction:column;width:100%;height:100%;padding:0;box-shadow:none}.wrapper mat-card ::ng-deep mat-card-header{align-items:center}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text{flex-grow:1;margin:0}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title{padding-top:20px;font-size:120%}.wrapper mat-card ::ng-deep mat-card-header .mat-card-header-text mat-card-title .count{font-size:80%;color:#888}.wrapper mat-card .count-slider{display:flex;flex-direction:column;width:100%}.wrapper mat-card .count-slider>label{padding:0 20px;font-size:90%}.wrapper mat-card .count-slider>mat-slider{width:100%}.wrapper mat-card mat-spinner{flex-grow:1;display:flex;align-self:center;justify-self:center;margin-top:20%}.wrapper mat-card .scroll{flex-grow:1;overflow-y:auto}.wrapper mat-card .scroll>button{display:flex;margin:auto}.wrapper mat-card .scroll .all-done{display:flex;flex-direction:column;align-items:center}.wrapper mat-card .scroll .all-done .all-done-emoji{font-size:72px;margin-bottom:20px}.wrapper mat-card .scroll .all-done .all-done-text{text-align:center;font-size:1.3em;color:var(--font-light)}.wrapper mat-card .error{border:#d00 solid 2px;background-color:#d005;display:flex;flex-direction:column;align-items:center}.wrapper mat-card .error .error-text{font-size:1.3em}\n"] }]
2779
2797
  }], ctorParameters: () => [{ type: CollectionAPIService }], propDecorators: { mode: [{
2780
2798
  type: Input
2781
2799
  }], type: [{
@@ -2797,7 +2815,7 @@ class MaterialIssuesComponent {
2797
2815
  this.issues = await this.filterAPIService.getMaterialIssueFieldNames().toPromise();
2798
2816
  }
2799
2817
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MaterialIssuesComponent, deps: [{ token: FilterAPIService }], target: i0.ɵɵFactoryTarget.Component }); }
2800
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MaterialIssuesComponent, selector: "metaqs2-material-issues", ngImport: i0, template: "<metaqs2-node-list\n *ngFor=\"let mode of issues\"\n [collectionId]=\"collectionId\"\n [mode]=\"mode\"\n type=\"material\"\n></metaqs2-node-list>\n", styles: [".while-loading{filter:blur(2px)}:host{padding:0 30px;display:flex;gap:30px;flex-wrap:wrap}:host>metaqs2-node-list{width:400px}\n"], dependencies: [{ kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NodeListComponent, selector: "metaqs2-node-list", inputs: ["mode", "type", "collectionId"], outputs: ["countChanged"] }] }); }
2818
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MaterialIssuesComponent, selector: "metaqs2-material-issues", ngImport: i0, template: "<metaqs2-node-list\n *ngFor=\"let mode of issues\"\n [collectionId]=\"collectionId\"\n [mode]=\"mode\"\n type=\"material\"\n></metaqs2-node-list>\n", styles: [".while-loading{filter:blur(2px)}:host{padding:0 30px;display:flex;gap:30px;flex-wrap:wrap}:host>metaqs2-node-list{width:400px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NodeListComponent, selector: "metaqs2-node-list", inputs: ["mode", "type", "collectionId"], outputs: ["countChanged"] }] }); }
2801
2819
  }
2802
2820
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MaterialIssuesComponent, decorators: [{
2803
2821
  type: Component,
@@ -2815,7 +2833,7 @@ class CollectionIssuesComponent {
2815
2833
  this.issues = await this.filterAPIService.getCollectionIssueFieldNames().toPromise();
2816
2834
  }
2817
2835
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CollectionIssuesComponent, deps: [{ token: FilterAPIService }], target: i0.ɵɵFactoryTarget.Component }); }
2818
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CollectionIssuesComponent, selector: "metaqs2-collection-issues", ngImport: i0, template: "<metaqs2-node-list\n *ngFor=\"let mode of issues\"\n [collectionId]=\"collectionId\"\n [mode]=\"mode\"\n type=\"collection\"\n></metaqs2-node-list>\n", styles: [".while-loading{filter:blur(2px)}:host{padding:0 30px;display:flex;gap:30px;flex-wrap:wrap}:host>metaqs2-node-list{width:400px}\n"], dependencies: [{ kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NodeListComponent, selector: "metaqs2-node-list", inputs: ["mode", "type", "collectionId"], outputs: ["countChanged"] }] }); }
2836
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CollectionIssuesComponent, selector: "metaqs2-collection-issues", ngImport: i0, template: "<metaqs2-node-list\n *ngFor=\"let mode of issues\"\n [collectionId]=\"collectionId\"\n [mode]=\"mode\"\n type=\"collection\"\n></metaqs2-node-list>\n", styles: [".while-loading{filter:blur(2px)}:host{padding:0 30px;display:flex;gap:30px;flex-wrap:wrap}:host>metaqs2-node-list{width:400px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NodeListComponent, selector: "metaqs2-node-list", inputs: ["mode", "type", "collectionId"], outputs: ["countChanged"] }] }); }
2819
2837
  }
2820
2838
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CollectionIssuesComponent, decorators: [{
2821
2839
  type: Component,
@@ -2869,7 +2887,7 @@ class NgMetaWidgetsLibModule {
2869
2887
  ngModule: NgMetaWidgetsLibModule,
2870
2888
  providers: [
2871
2889
  ConfigHelperService,
2872
- { provide: 'config', useValue: params },
2890
+ { provide: NG_META_WIDGETS_LIB_CONFIGURATION, useValue: params },
2873
2891
  {
2874
2892
  provide: Configuration,
2875
2893
  useFactory: () => {
@@ -2884,18 +2902,19 @@ class NgMetaWidgetsLibModule {
2884
2902
  }
2885
2903
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgMetaWidgetsLibModule, deps: [{ token: SvgIconsService }], target: i0.ɵɵFactoryTarget.NgModule }); }
2886
2904
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: NgMetaWidgetsLibModule, declarations: [WrapObservablePipe,
2887
- QualityMatrixComponent,
2888
- DonutChartComponent,
2889
- DonutChartPipe,
2890
2905
  CollectionIssuesComponent,
2891
2906
  MaterialIssuesComponent,
2892
2907
  NodeEntryComponent,
2893
2908
  NodeListComponent,
2894
- NodeImageUrlPipe], imports: [BrowserModule, ApiModule, MatCardModule,
2909
+ NodeImageUrlPipe,
2910
+ DonutChartTooltipComponent], imports: [BrowserModule, ApiModule, MatCardModule,
2895
2911
  MatTreeModule,
2912
+ DonutChartComponent,
2913
+ DonutChartPipe,
2896
2914
  BrowserAnimationsModule,
2897
2915
  MatIconModule,
2898
2916
  MatSliderModule,
2917
+ QualityMatrixComponent,
2899
2918
  MatSlideToggleModule,
2900
2919
  MatButtonModule,
2901
2920
  MatProgressSpinnerModule,
@@ -2921,7 +2940,8 @@ class NgMetaWidgetsLibModule {
2921
2940
  MatDatepickerInput,
2922
2941
  MatDatepicker,
2923
2942
  DatepickerComponent,
2924
- ProgressSpinnerComponent], exports: [CollectionIssuesComponent, MaterialIssuesComponent, NodeListComponent, QualityMatrixComponent] }); }
2943
+ ProgressSpinnerComponent,
2944
+ ScrollMarkerDirective], exports: [CollectionIssuesComponent, MaterialIssuesComponent, NodeListComponent, QualityMatrixComponent] }); }
2925
2945
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgMetaWidgetsLibModule, providers: [provideHttpClient(withInterceptorsFromDi()), provideCharts(withDefaultRegisterables())], imports: [BrowserModule,
2926
2946
  ApiModule.forRoot(() => new Configuration()),
2927
2947
  MatCardModule,
@@ -2929,6 +2949,7 @@ class NgMetaWidgetsLibModule {
2929
2949
  BrowserAnimationsModule,
2930
2950
  MatIconModule,
2931
2951
  MatSliderModule,
2952
+ QualityMatrixComponent,
2932
2953
  MatSlideToggleModule,
2933
2954
  MatButtonModule,
2934
2955
  MatProgressSpinnerModule,
@@ -2959,14 +2980,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2959
2980
  args: [{
2960
2981
  declarations: [
2961
2982
  WrapObservablePipe,
2962
- QualityMatrixComponent,
2963
- DonutChartComponent,
2964
- DonutChartPipe,
2965
2983
  CollectionIssuesComponent,
2966
2984
  MaterialIssuesComponent,
2967
2985
  NodeEntryComponent,
2968
2986
  NodeListComponent,
2969
2987
  NodeImageUrlPipe,
2988
+ DonutChartTooltipComponent,
2970
2989
  ],
2971
2990
  exports: [CollectionIssuesComponent, MaterialIssuesComponent, NodeListComponent, QualityMatrixComponent],
2972
2991
  imports: [
@@ -2974,9 +2993,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2974
2993
  ApiModule.forRoot(() => new Configuration()),
2975
2994
  MatCardModule,
2976
2995
  MatTreeModule,
2996
+ DonutChartComponent,
2997
+ DonutChartPipe,
2977
2998
  BrowserAnimationsModule,
2978
2999
  MatIconModule,
2979
3000
  MatSliderModule,
3001
+ QualityMatrixComponent,
2980
3002
  MatSlideToggleModule,
2981
3003
  MatButtonModule,
2982
3004
  MatProgressSpinnerModule,
@@ -3003,6 +3025,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3003
3025
  MatDatepicker,
3004
3026
  DatepickerComponent,
3005
3027
  ProgressSpinnerComponent,
3028
+ ScrollMarkerDirective,
3006
3029
  ],
3007
3030
  providers: [provideHttpClient(withInterceptorsFromDi()), provideCharts(withDefaultRegisterables())],
3008
3031
  }]
@@ -3057,7 +3080,7 @@ class TreeCollectionDetailsComponent {
3057
3080
  return this.linkService.openByCollectionAndIssueType(collectionId, issueType, title);
3058
3081
  }
3059
3082
  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 }); }
3060
- 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 matTooltip=\"{{row.meta.alt_label}}\"\n class=\"row-header {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"row.meta.level === 1 ? 'tree' : 'child'\"></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 matTooltip=\"{{column.altLabel}}\" >{{ \"quality_matrix.\" + column.label | translate }}</th>\n <td mat-cell *matCellDef=\"let row\" matTooltip=\"{{'cell tooltip' //getCellTooltip(row, column.id)}}\">\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: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}.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:20}\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: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { 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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
3083
+ 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]=\"row.meta.level === 1 ? 'tree' : 'child'\"></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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
3061
3084
  }
3062
3085
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeCollectionDetailsComponent, decorators: [{
3063
3086
  type: Component,
@@ -3066,14 +3089,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3066
3089
  AsyncPipe,
3067
3090
  NgClass,
3068
3091
  MatCardModule,
3069
- MatTooltip,
3070
3092
  MatIcon,
3071
3093
  NgIf,
3072
3094
  NgForOf,
3073
3095
  MatTableModule,
3074
- MatProgressSpinner,
3075
3096
  ProgressSpinnerComponent,
3076
- ], 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 matTooltip=\"{{row.meta.alt_label}}\"\n class=\"row-header {{'mat-cell-level-' + (row.meta.level+1)}}\"\n >\n <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"row.meta.level === 1 ? 'tree' : 'child'\"></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 matTooltip=\"{{column.altLabel}}\" >{{ \"quality_matrix.\" + column.label | translate }}</th>\n <td mat-cell *matCellDef=\"let row\" matTooltip=\"{{'cell tooltip' //getCellTooltip(row, column.id)}}\">\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: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}.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:20}\n"] }]
3097
+ ], 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]=\"row.meta.level === 1 ? 'tree' : 'child'\"></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"] }]
3077
3098
  }], ctorParameters: () => [{ type: MetaApiService }, { type: i2$3.TranslateService }, { type: EditorialLinkService }], propDecorators: { collectionId: [{
3078
3099
  type: Input,
3079
3100
  args: [{ required: true }]
@@ -3300,7 +3321,7 @@ class TreeSearchCountsComponent {
3300
3321
  encodeURIComponent(JSON.stringify(filters)) +
3301
3322
  '&' +
3302
3323
  'panel=contents&tab=4&';
3303
- const ref = window.open(url);
3324
+ window.open(url);
3304
3325
  }
3305
3326
  showCollectionItems(collectionId, collectionName, materialType) {
3306
3327
  const id = this.extractCollectionIdFromVocabUrl(collectionId);
@@ -3347,7 +3368,7 @@ class TreeSearchCountsComponent {
3347
3368
  return this.collectionColumns.flatMap((e, i) => [e, this.searchColumns[i]]);
3348
3369
  }
3349
3370
  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 }); }
3350
- 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 *ngIf=\"pageTitle\" appearance=\"raised\">\n<mat-card-header >\n <mat-card-title>\n Material in Sammlungen{{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=\"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\n <div >\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showOERonly\" >\n zeige nur OER\n </mat-slide-toggle>\n </div>\n <div>\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showAllColumns\" >\n zeige alle Typen\n </mat-slide-toggle>\n </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 <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"row.meta.level<=1?'layers':'child'\" />\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}}\"' matTooltip=\"{{col.label}}\" >{{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 matTooltip=\"{{column.label}}\" >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>", 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}\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: "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: "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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: 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"] }] }); }
3371
+ 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]=\"row.meta.level<=1?'layers':'child'\" />\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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: 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"] }] }); }
3351
3372
  }
3352
3373
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TreeSearchCountsComponent, decorators: [{
3353
3374
  type: Component,
@@ -3356,7 +3377,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3356
3377
  AsyncPipe,
3357
3378
  NgClass,
3358
3379
  MatCardModule,
3359
- MatTooltip,
3360
3380
  MatIcon,
3361
3381
  NgIf,
3362
3382
  NgForOf,
@@ -3364,7 +3384,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3364
3384
  MatSlideToggle,
3365
3385
  ReactiveFormsModule,
3366
3386
  ProgressSpinnerComponent,
3367
- ], template: "<mat-card *ngIf=\"pageTitle\" appearance=\"raised\">\n<mat-card-header >\n <mat-card-title>\n Material in Sammlungen{{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=\"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\n <div >\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showOERonly\" >\n zeige nur OER\n </mat-slide-toggle>\n </div>\n <div>\n <mat-slide-toggle labelPosition=\"before\" class=\"toggle\" [formControl]=\"showAllColumns\" >\n zeige alle Typen\n </mat-slide-toggle>\n </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 <a (click)=\"openCollection(row.meta.id)\">\n <mat-icon [svgIcon]=\"row.meta.level<=1?'layers':'child'\" />\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}}\"' matTooltip=\"{{col.label}}\" >{{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 matTooltip=\"{{column.label}}\" >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>", 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}\n"] }]
3387
+ ], 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]=\"row.meta.level<=1?'layers':'child'\" />\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"] }]
3368
3388
  }], ctorParameters: () => [{ type: MetaApiService }, { type: ConfigHelperService }, { type: Document, decorators: [{
3369
3389
  type: Inject,
3370
3390
  args: [DOCUMENT]
@@ -3545,7 +3565,7 @@ class CollectionCountHistoryComponent {
3545
3565
  }), finalize(() => this.isLoading.set(false)));
3546
3566
  }
3547
3567
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CollectionCountHistoryComponent, deps: [{ token: MetaApiService }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component }); }
3548
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CollectionCountHistoryComponent, isStandalone: true, selector: "metaqs2-collection-count-history", inputs: { pageTitle: "pageTitle" }, viewQueries: [{ propertyName: "chart", first: true, predicate: BaseChartDirective, descendants: true }], ngImport: i0, template: "<mat-card appearance=\"outlined\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n {{ pageTitle }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div style=\"display: flex; gap: 0.5rem; align-items: center\">\n <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n <metaqs2-monthpicker [disabled]=\"!isHistoryEnabled()\"\n [inputGroup]=\"range\"></metaqs2-monthpicker>\n </div>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n\n <div [class.while-loading]=\"isLoading()\">\n <canvas\n baseChart\n [datasets]=\"(datapoints$ | async) || []\"\n [options]=\"lineChartOptions\"\n [type]=\"'line'\"\n ></canvas>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}\n"], dependencies: [{ kind: "directive", type: BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }, { kind: "component", type: MonthpickerComponent, selector: "metaqs2-monthpicker", inputs: ["startView", "inputGroup", "disabled"] }, { 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: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: FormsModule }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
3568
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CollectionCountHistoryComponent, isStandalone: true, selector: "metaqs2-collection-count-history", inputs: { pageTitle: "pageTitle" }, viewQueries: [{ propertyName: "chart", first: true, predicate: BaseChartDirective, descendants: true }], ngImport: i0, template: "<mat-card appearance=\"outlined\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n {{ pageTitle }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div style=\"display: flex; gap: 0.5rem; align-items: center\">\n <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n <metaqs2-monthpicker *ngIf=\"isHistoryEnabled()\"\n [inputGroup]=\"range\"></metaqs2-monthpicker>\n </div>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n\n <div [class.while-loading]=\"isLoading()\">\n <canvas\n baseChart\n [datasets]=\"(datapoints$ | async) || []\"\n [options]=\"lineChartOptions\"\n [type]=\"'line'\"\n ></canvas>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}\n"], dependencies: [{ kind: "directive", type: BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }, { kind: "component", type: MonthpickerComponent, selector: "metaqs2-monthpicker", inputs: ["startView", "inputGroup", "disabled"] }, { 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: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: FormsModule }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "metaqs2-progress-spinner", inputs: ["color", "diameter", "strokeWidth", "backdropEnabled", "positionGloballyCenter", "displayProgressSpinner"] }] }); }
3549
3569
  }
3550
3570
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CollectionCountHistoryComponent, decorators: [{
3551
3571
  type: Component,
@@ -3562,7 +3582,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3562
3582
  MatSlideToggle,
3563
3583
  FormsModule,
3564
3584
  ProgressSpinnerComponent,
3565
- ], template: "<mat-card appearance=\"outlined\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n {{ pageTitle }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div style=\"display: flex; gap: 0.5rem; align-items: center\">\n <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n <metaqs2-monthpicker [disabled]=\"!isHistoryEnabled()\"\n [inputGroup]=\"range\"></metaqs2-monthpicker>\n </div>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n\n <div [class.while-loading]=\"isLoading()\">\n <canvas\n baseChart\n [datasets]=\"(datapoints$ | async) || []\"\n [options]=\"lineChartOptions\"\n [type]=\"'line'\"\n ></canvas>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}\n"] }]
3585
+ ], template: "<mat-card appearance=\"outlined\">\n <mat-card-header *ngIf=\"pageTitle\">\n <mat-card-title>\n {{ pageTitle }}{{ isLoading() ? \": Lade neue Daten.\" : \"\" }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div style=\"display: flex; gap: 0.5rem; align-items: center\">\n <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n <metaqs2-monthpicker *ngIf=\"isHistoryEnabled()\"\n [inputGroup]=\"range\"></metaqs2-monthpicker>\n </div>\n <metaqs2-progress-spinner [displayProgressSpinner]=\"isLoading()\"></metaqs2-progress-spinner>\n\n <div [class.while-loading]=\"isLoading()\">\n <canvas\n baseChart\n [datasets]=\"(datapoints$ | async) || []\"\n [options]=\"lineChartOptions\"\n [type]=\"'line'\"\n ></canvas>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [".while-loading{filter:blur(2px)}\n"] }]
3566
3586
  }], ctorParameters: () => [{ type: MetaApiService }, { type: i0.DestroyRef }], propDecorators: { chart: [{
3567
3587
  type: ViewChild,
3568
3588
  args: [BaseChartDirective]
@@ -3591,7 +3611,7 @@ class CountsWithHistoryComponent {
3591
3611
  start: new FormControl(),
3592
3612
  end: new FormControl(DateTime.utc().startOf('day'), { nonNullable: true }),
3593
3613
  });
3594
- this.isHistoryEnabled = signal(true);
3614
+ this.isHistoryEnabled = signal(false);
3595
3615
  this.allColumns = computed(() => {
3596
3616
  if (!this.isHistoryEnabled()) {
3597
3617
  return this.recentColumns();
@@ -3694,7 +3714,7 @@ class CountsWithHistoryComponent {
3694
3714
  }));
3695
3715
  }
3696
3716
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CountsWithHistoryComponent, deps: [{ token: MetaApiService }, { token: i0.DestroyRef }, { token: EditorialLinkService }], target: i0.ɵɵFactoryTarget.Component }); }
3697
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CountsWithHistoryComponent, isStandalone: true, selector: "metaqs2-counts-with-history", inputs: { apiMethod: "apiMethod", columnTranslationkey: "columnTranslationkey", pageTitle: "pageTitle", sourceType: "sourceType" }, 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>\n <metaqs2-datepicker [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded()\"></metaqs2-datepicker>\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 <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\" *ngIf=\"timeFilterLoaded()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col\"\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}\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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: "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"] }] }); }
3717
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CountsWithHistoryComponent, isStandalone: true, selector: "metaqs2-counts-with-history", inputs: { apiMethod: "apiMethod", columnTranslationkey: "columnTranslationkey", pageTitle: "pageTitle", sourceType: "sourceType" }, 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 [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()\" *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\"\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}.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: 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: "directive", type: i4.MatCell, selector: "mat-cell, td[mat-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: "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"] }] }); }
3698
3718
  }
3699
3719
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CountsWithHistoryComponent, decorators: [{
3700
3720
  type: Component,
@@ -3720,7 +3740,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3720
3740
  MatSlideToggle,
3721
3741
  AsyncPipe,
3722
3742
  ProgressSpinnerComponent,
3723
- ], 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>\n <metaqs2-datepicker [disabled]=\"isLoading() || !isHistoryEnabled()\" [inputGroup]=\"range\" *ngIf=\"timeFilterLoaded()\"></metaqs2-datepicker>\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 <mat-slide-toggle [(ngModel)]=\"isHistoryEnabled\" [disabled]=\"isLoading()\" *ngIf=\"timeFilterLoaded()\">\n <label>Zeige historische Daten</label>\n </mat-slide-toggle>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [matTooltip]=\"row.meta.alt_label\"\n class=\"label-col\"\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}\n"] }]
3743
+ ], 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 [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()\" *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\"\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}.actionbar{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:.5rem}\n"] }]
3724
3744
  }], ctorParameters: () => [{ type: MetaApiService }, { type: i0.DestroyRef }, { type: EditorialLinkService }], propDecorators: { apiMethod: [{
3725
3745
  type: Input,
3726
3746
  args: [{ required: true }]
@@ -3733,6 +3753,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3733
3753
  args: [{ required: true }]
3734
3754
  }] } });
3735
3755
 
3756
+ async function createRegister(environment) {
3757
+ if (environment.production) {
3758
+ enableProdMode();
3759
+ }
3760
+ const app = await createApplication({
3761
+ providers: [
3762
+ importProvidersFrom(NgMetaWidgetsLibModule.forRoot({
3763
+ eduSharingPath: environment.eduSharingPath,
3764
+ apiPath: environment.apiPath,
3765
+ }), TranslateModule.forRoot({
3766
+ defaultLanguage: 'de',
3767
+ loader: {
3768
+ provide: TranslateLoader,
3769
+ useFactory: (httpClient) => new TranslateHttpLoader(httpClient),
3770
+ deps: [HttpClient],
3771
+ },
3772
+ })),
3773
+ provideHttpClient(),
3774
+ provideAnimations(),
3775
+ ],
3776
+ });
3777
+ const injector = app.injector;
3778
+ return (tag, component) => {
3779
+ const customElement = createCustomElement(component, { injector });
3780
+ customElements.define(tag, customElement);
3781
+ };
3782
+ }
3783
+
3736
3784
  /*
3737
3785
  * Public API Surface of ng-meta-widgets-lib
3738
3786
  */
@@ -3741,5 +3789,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3741
3789
  * Generated bundle index. Do not edit.
3742
3790
  */
3743
3791
 
3744
- export { CollectionCountHistoryComponent, CollectionIssuesComponent, ConfigHelperService, CountsWithHistoryComponent, MaterialIssuesComponent, NgMetaWidgetsLibConfiguration, NgMetaWidgetsLibModule, NodeListComponent, QualityMatrixComponent, TreeCollectionDetailsComponent, TreeSearchCountsComponent };
3792
+ export { CollectionCountHistoryComponent, CollectionIssuesComponent, ConfigHelperService, CountsWithHistoryComponent, DonutChartTooltipComponent, MaterialIssuesComponent, NG_META_WIDGETS_LIB_CONFIGURATION, NgMetaWidgetsLibConfiguration, NgMetaWidgetsLibModule, NodeListComponent, QualityMatrixComponent, TOOLTIP_DATA, TOOLTIP_REF, TooltipRefImpl, TooltipService, TreeCollectionDetailsComponent, TreeSearchCountsComponent, borderPositionStrategy, centerPositionStrategy, createRegister, transformDonutChartData };
3745
3793
  //# sourceMappingURL=ngx-edu-sharing-metaqs2.mjs.map