@hestia-earth/ui-components 0.39.0 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, InjectionToken, inject, input, computed, HostBinding, Component as Component$1, model, output, signal, effect, ChangeDetectionStrategy,
|
|
2
|
+
import { Injectable, InjectionToken, inject, input, computed, HostBinding, Component as Component$1, model, output, signal, effect, ChangeDetectionStrategy, ElementRef, untracked, Directive, viewChild, Pipe, DestroyRef, HostListener, ViewEncapsulation, contentChild, viewChildren, forwardRef } from '@angular/core';
|
|
3
3
|
import { toSignal, toObservable, outputFromObservable, takeUntilDestroyed, rxResource } from '@angular/core/rxjs-interop';
|
|
4
4
|
import * as i1 from '@angular/forms';
|
|
5
5
|
import { UntypedFormBuilder, Validators, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR, FormControl } from '@angular/forms';
|
|
@@ -21,12 +21,12 @@ import { BreakpointObserver } from '@angular/cdk/layout';
|
|
|
21
21
|
import { select, selectAll } from 'd3-selection';
|
|
22
22
|
import { json2csv } from 'json-2-csv';
|
|
23
23
|
import { propertyValue as propertyValue$1, emptyValue } from '@hestia-earth/utils/dist/term';
|
|
24
|
-
import { getDefaultModelId, getModelGroup,
|
|
25
|
-
import { LocalStorageService } from 'ngx-webstorage';
|
|
24
|
+
import { getDefaultModelId, getModelGroup, isInSystemBoundary } from '@hestia-earth/glossary';
|
|
26
25
|
import isEqual$1 from 'lodash.isequal';
|
|
27
26
|
import { DataState, filenameWithoutExt, nodeTypeToParam, SupportedExtensions, fileToExt, allowedDataStates, fileExt, maxFileSizeMb } from '@hestia-earth/api';
|
|
28
27
|
import { models as models$1, loadConfig, getMaxStage } from '@hestia-earth/engine-models';
|
|
29
28
|
import { DeltaDisplayType, delta, customDeltaFuncs } from '@hestia-earth/utils/dist/delta';
|
|
29
|
+
import { LocalStorageService } from 'ngx-webstorage';
|
|
30
30
|
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
31
31
|
import { signalStore, withState, withComputed, withMethods, patchState, withHooks } from '@ngrx/signals';
|
|
32
32
|
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
@@ -1140,9 +1140,8 @@ const registerChart = (items = []) => () => {
|
|
|
1140
1140
|
|
|
1141
1141
|
class ChartConfigurationDirective {
|
|
1142
1142
|
constructor() {
|
|
1143
|
-
this._zone = inject(NgZone);
|
|
1144
1143
|
this._elementRef = inject(ElementRef);
|
|
1145
|
-
this._observer = new ResizeObserver(() => this.
|
|
1144
|
+
this._observer = new ResizeObserver(() => this.resize());
|
|
1146
1145
|
/**
|
|
1147
1146
|
* The chart configuration.
|
|
1148
1147
|
* This is used to initialize the chart.
|
|
@@ -1161,12 +1160,10 @@ class ChartConfigurationDirective {
|
|
|
1161
1160
|
effect(onCleanup => {
|
|
1162
1161
|
const configuration = this.chartConfiguration();
|
|
1163
1162
|
untracked(() => {
|
|
1164
|
-
this.
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
}
|
|
1169
|
-
});
|
|
1163
|
+
this.removeChart();
|
|
1164
|
+
if (configuration) {
|
|
1165
|
+
this._chart = new Chart(this._elementRef.nativeElement, configuration);
|
|
1166
|
+
}
|
|
1170
1167
|
});
|
|
1171
1168
|
onCleanup(() => this.removeChart());
|
|
1172
1169
|
});
|
|
@@ -2379,34 +2376,6 @@ const groupNodesByTerm = (nodes = [], key, includeNode = (_node) => true, hideZe
|
|
|
2379
2376
|
};
|
|
2380
2377
|
const isGroupVisible = (blankNodes) => blankNodes.some(v => v.value.visible);
|
|
2381
2378
|
|
|
2382
|
-
/**
|
|
2383
|
-
* Signal utility to patch local storage.
|
|
2384
|
-
*/
|
|
2385
|
-
const localStorageSignal = (initialValue, localStorageKey) => {
|
|
2386
|
-
const localStorage = inject(LocalStorageService);
|
|
2387
|
-
// retrieve value from local storage
|
|
2388
|
-
const storedValueRaw = localStorage.retrieve(localStorageKey);
|
|
2389
|
-
if (storedValueRaw) {
|
|
2390
|
-
try {
|
|
2391
|
-
initialValue = JSON.parse(storedValueRaw);
|
|
2392
|
-
}
|
|
2393
|
-
catch (e) {
|
|
2394
|
-
console.error('Failed to parse stored value for key:', localStorageKey);
|
|
2395
|
-
}
|
|
2396
|
-
}
|
|
2397
|
-
else {
|
|
2398
|
-
localStorage.store(localStorageKey, JSON.stringify(initialValue));
|
|
2399
|
-
}
|
|
2400
|
-
const writableSignal = signal(initialValue, ...(ngDevMode ? [{ debugName: "writableSignal" }] : []));
|
|
2401
|
-
// monkey-patch signal setter to also store to local storage on set
|
|
2402
|
-
const setter = writableSignal.set;
|
|
2403
|
-
writableSignal.set = (value) => {
|
|
2404
|
-
localStorage.store(localStorageKey, JSON.stringify(value));
|
|
2405
|
-
setter(value);
|
|
2406
|
-
};
|
|
2407
|
-
return writableSignal;
|
|
2408
|
-
};
|
|
2409
|
-
|
|
2410
2379
|
/* eslint-disable */
|
|
2411
2380
|
// copied from https://github.com/plurals/pluralize but incompatible with angular 14 and webpack 6
|
|
2412
2381
|
// Rule storage - pluralize and singularize need to be run sequentially,
|
|
@@ -2854,9 +2823,8 @@ class ResizedEvent {
|
|
|
2854
2823
|
class ResizedDirective {
|
|
2855
2824
|
constructor() {
|
|
2856
2825
|
this.element = inject(ElementRef);
|
|
2857
|
-
this.zone = inject(NgZone);
|
|
2858
2826
|
this.resized = output();
|
|
2859
|
-
this.observer = new ResizeObserver(entries => this.
|
|
2827
|
+
this.observer = new ResizeObserver(entries => this.observe(entries));
|
|
2860
2828
|
}
|
|
2861
2829
|
ngOnInit() {
|
|
2862
2830
|
this.observer.observe(this.element.nativeElement);
|
|
@@ -3169,7 +3137,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
3169
3137
|
|
|
3170
3138
|
class DataTableComponent {
|
|
3171
3139
|
constructor() {
|
|
3172
|
-
this.ngZone = inject(NgZone);
|
|
3173
3140
|
this.elementRef = inject(ElementRef);
|
|
3174
3141
|
this.minHeight = input(...(ngDevMode ? [undefined, { debugName: "minHeight" }] : []));
|
|
3175
3142
|
this.maxHeight = input(...(ngDevMode ? [undefined, { debugName: "maxHeight" }] : []));
|
|
@@ -3182,9 +3149,7 @@ class DataTableComponent {
|
|
|
3182
3149
|
return this.elementRef.nativeElement.querySelector('.data-table-holder');
|
|
3183
3150
|
}
|
|
3184
3151
|
onResized({ newRect: { width } }) {
|
|
3185
|
-
this.
|
|
3186
|
-
this.containerEl.style.width = `${width}px`;
|
|
3187
|
-
});
|
|
3152
|
+
this.containerEl.style.width = `${width}px`;
|
|
3188
3153
|
}
|
|
3189
3154
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3190
3155
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.13", type: DataTableComponent, isStandalone: true, selector: "he-data-table", inputs: { minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, small: { classPropertyName: "small", publicName: "small", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "resized": "onResized($event)" }, properties: { "class.is-small": "this.isSmall" } }, ngImport: i0, template: "<div class=\"w-100 h-100 is-overflow-hidden | data-table-holder\">\n <div\n class=\"w-100 h-100 is-overflow-auto | table-container\"\n [style.min-height]=\"minHeight() + 'px'\"\n [style.max-height]=\"maxHeight() + 'px'\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:block;height:inherit;width:100%}:host *{box-sizing:border-box}:host .data-table-holder{z-index:1}:host.is-bordered>.data-table-holder{border:1px solid #dbe3ea;border-radius:3px;box-shadow:inset -2px 0 #bdb7b726;padding:8px}:host ::ng-deep *{box-sizing:border-box}:host ::ng-deep>.data-table-holder>.table-container>.table{width:100%}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th{height:42px;white-space:nowrap;font-weight:600}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td{border:none}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th>span:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td>span:first-child{display:inline-block;max-width:100%}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table .fixed-column{position:sticky}:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td{z-index:10}:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column{z-index:11}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th{top:0;z-index:1070}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column{z-index:1071}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.has-border-right:not(:last-child),:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.has-border-right:not(:last-child){box-shadow:inset -2px 0 #bdb7b726}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column{left:0;max-width:300px;width:300px}@media screen and (max-width: 767px){:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column{max-width:180px;width:180px}}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th:first-child.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column.has-border-right{box-shadow:none}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column.has-border-right:after{position:absolute;content:\"\";height:100%;top:0;right:0;width:4px;box-shadow:2px 0 4px #bdb7b726}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column{left:300px}@media screen and (max-width: 767px){:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td.fixed-column{left:180px}}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th{box-shadow:inset 0 -1px #ffc000}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th.has-border-right:not(:last-child){box-shadow:inset 0 -1px #ffc000,inset -2px 0 #bdb7b726}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th:first-child.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th.fixed-column.has-border-right{box-shadow:inset 0 -1px #ffc000}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr:last-child>th.fixed-column.has-border-right:after{box-shadow:inset 0 -1px #ffc000,2px 0 4px #bdb7b726}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr>th.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>tbody>tr>td.has-border-right{box-shadow:inset -2px 0 #6c8093}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr>th:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr>th.fixed-column.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>tbody>tr>td:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>tbody>tr>td.fixed-column.has-border-right:after{box-shadow:2px 0 4px #6c8093}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th{box-shadow:inset 0 -1px #c5cdd5}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th.has-border-right{box-shadow:inset 0 -1px #c5cdd5,inset -2px 0 #6c8093}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th:first-child.has-border-right,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th.fixed-column.has-border-right{box-shadow:inset 0 -1px #c5cdd5}:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th:first-child.has-border-right:after,:host ::ng-deep>.data-table-holder>.table-container>.table.is-dark>thead>tr:last-child>th.fixed-column.has-border-right:after{box-shadow:inset 0 -1px #c5cdd5,2px 0 4px #6c8093}:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr{background-color:transparent!important}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr+tr th{top:42px}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr+tr+tr th{top:84px}:host ::ng-deep>.data-table-holder>.table-container>.table>thead>tr>th,:host ::ng-deep>.data-table-holder>.table-container>.table>tbody>tr>td{background-color:#fff}:host ::ng-deep>.data-table-holder>.table-container>.table.is-hoverable>tbody>tr:not(.is-selected):hover>td{background-color:#f3f5f7}:host ::ng-deep>.data-table-holder>.table-container>.table.is-striped>tbody>tr:not(.is-selected):nth-child(2n)>td{background-color:#fefcf7}:host ::ng-deep>.data-table-holder>.table-container>.table.is-striped.is-hoverable>tr:not(.is-selected):nth-child(2n):hover>td{background-color:#f3f5f7}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow{font-size:.875rem;line-height:1rem}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th{height:30px}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td.fixed-column{min-width:200px;max-width:200px;width:200px}@media screen and (max-width: 767px){:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td:first-child,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td.fixed-column{min-width:120px;max-width:120px;width:120px}}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td.fixed-column{left:200px}@media screen and (max-width: 767px){:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr>th.fixed-column,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>tbody>tr>td.fixed-column{left:120px}}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr+tr th{top:30px}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow>thead>tr+tr+tr th{top:60px}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow .select,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow .select select,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow .input{height:30px;font-size:.875rem;line-height:1rem}:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow .select select,:host ::ng-deep>.data-table-holder>.table-container>.table.is-narrow .input{padding-top:5px;padding-bottom:5px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
@@ -4246,13 +4211,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
4246
4211
|
/* eslint-disable @angular-eslint/directive-selector */
|
|
4247
4212
|
class DocumentClickService {
|
|
4248
4213
|
constructor() {
|
|
4249
|
-
this.ngZone = inject(NgZone);
|
|
4250
4214
|
this.documentClick$ = new Subject();
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
.subscribe();
|
|
4255
|
-
});
|
|
4215
|
+
fromEvent(document, 'click')
|
|
4216
|
+
.pipe(takeUntilDestroyed(), tap(event => this.documentClick$.next(event)))
|
|
4217
|
+
.subscribe();
|
|
4256
4218
|
}
|
|
4257
4219
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DocumentClickService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4258
4220
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DocumentClickService, providedIn: 'root' }); }
|
|
@@ -4264,7 +4226,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
4264
4226
|
class ClickOutsideDirective {
|
|
4265
4227
|
constructor() {
|
|
4266
4228
|
this.elementRef = inject(ElementRef);
|
|
4267
|
-
this.zone = inject(NgZone);
|
|
4268
4229
|
this.destroyRef = inject(DestroyRef);
|
|
4269
4230
|
this.documentClickService = inject(DocumentClickService);
|
|
4270
4231
|
this.clickOutsideListenAfter = input(0, ...(ngDevMode ? [{ debugName: "clickOutsideListenAfter" }] : []));
|
|
@@ -4272,17 +4233,13 @@ class ClickOutsideDirective {
|
|
|
4272
4233
|
}
|
|
4273
4234
|
ngAfterViewInit() {
|
|
4274
4235
|
const skip$ = timer(this.clickOutsideListenAfter()).pipe(take(1));
|
|
4275
|
-
this.
|
|
4276
|
-
this.
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
}
|
|
4283
|
-
}))
|
|
4284
|
-
.subscribe();
|
|
4285
|
-
});
|
|
4236
|
+
this.documentClickService.documentClick$
|
|
4237
|
+
.pipe(skipUntil(skip$), takeUntilDestroyed(this.destroyRef), tap(event => {
|
|
4238
|
+
if (!this.elementRef.nativeElement.contains(event.target)) {
|
|
4239
|
+
this.clickOutside.emit();
|
|
4240
|
+
}
|
|
4241
|
+
}))
|
|
4242
|
+
.subscribe();
|
|
4286
4243
|
}
|
|
4287
4244
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: ClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4288
4245
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.13", type: ClickOutsideDirective, isStandalone: true, selector: "[clickOutside]", inputs: { clickOutsideListenAfter: { classPropertyName: "clickOutsideListenAfter", publicName: "clickOutsideListenAfter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickOutside: "clickOutside" }, ngImport: i0 }); }
|
|
@@ -7041,7 +6998,7 @@ const groupLogsByModel = (data = '', groupByAnimal = false) => data
|
|
|
7041
6998
|
.trim()
|
|
7042
6999
|
.split('\n')
|
|
7043
7000
|
.map(parseMessage)
|
|
7044
|
-
.filter(v => [hasValue(v?.model),
|
|
7001
|
+
.filter(v => [hasValue(v?.model), ['term', 'key', 'animalId'].some(k => hasValue(v?.[k]))].every(Boolean))
|
|
7045
7002
|
.reduce((group, log) => {
|
|
7046
7003
|
const subValue = subValueKeys.find(v => !!log[v] && log[v] != noValue);
|
|
7047
7004
|
return subValue && !log.cycle ? groupLogSubValue(group, log, subValue) : groupLog(group, log, groupByAnimal);
|
|
@@ -7410,39 +7367,37 @@ const configModelWithDocs = ({ nodeType, type, termId, termType, key }, subValue
|
|
|
7410
7367
|
methodModel: { '@id': methodId }
|
|
7411
7368
|
};
|
|
7412
7369
|
const modelKey = (allLogs?.[subValue?.id]?.[termId]?.[methodId] || allLogs?.[termId]?.[methodId])?.model_key;
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
(isNotRelevantModel({ methodId }) ? findMatchingModel({ model: methodId }) : undefined)
|
|
7445
|
-
};
|
|
7370
|
+
const model =
|
|
7371
|
+
// handle "hestia.seed_emissions"
|
|
7372
|
+
findMatchingModel(modelParams(node, !['backgroundData'].includes(subValue?.key), subValue?.modelKey)) ||
|
|
7373
|
+
findMatchingModel(modelParams(node, !['backgroundData'].includes(subValue?.key))) ||
|
|
7374
|
+
// handle background emissions
|
|
7375
|
+
findMatchingModel({ modelKey: toSnakeCase(nodeType), model: methodId }) ||
|
|
7376
|
+
// handle "liveAnimal"
|
|
7377
|
+
(termType && findMatchingModel(modelKeyParams(node, termType))) ||
|
|
7378
|
+
// handle "completeness.cropResidue"
|
|
7379
|
+
(key ? findMatchingModel(modelKeyParams(node, `${methodId}.${key}`)) : undefined) ||
|
|
7380
|
+
findMatchingModel(modelKeyParams(node, `${subValue?.key}.${methodId}`)) ||
|
|
7381
|
+
// handle "input.price"
|
|
7382
|
+
findMatchingModel(modelKeyParams(node, `${type?.toLowerCase()}.${subValue?.key}`)) ||
|
|
7383
|
+
// handle "input.hestiaAggregatedData"
|
|
7384
|
+
findMatchingModel(modelKeyParams(node, `${type?.toLowerCase()}.${methodId}`)) ||
|
|
7385
|
+
// handle "transformation"
|
|
7386
|
+
(subValue?.key ? findMatchingModel(modelKeyParams(node, subValue?.key)) : undefined) ||
|
|
7387
|
+
// handle "transformation/input/excreta" and other models with "/"
|
|
7388
|
+
(methodId.includes('/')
|
|
7389
|
+
? findMatchingModel({
|
|
7390
|
+
model: methodId.split('/')[0],
|
|
7391
|
+
modelKey: methodId.split('/').slice(1).join('.')
|
|
7392
|
+
})
|
|
7393
|
+
: undefined) ||
|
|
7394
|
+
// handle "seed_emissions"
|
|
7395
|
+
([subValue?.id === 'seed', type === SchemaType.Emission].every(Boolean)
|
|
7396
|
+
? findMatchingModel({ model: methodId, modelKey: 'seed_emissions' })
|
|
7397
|
+
: undefined) ||
|
|
7398
|
+
(modelKey ? findMatchingModel({ modelKey, model: methodId }) : undefined) ||
|
|
7399
|
+
(isNotRelevantModel({ methodId }) ? findMatchingModel({ model: methodId }) : undefined);
|
|
7400
|
+
return { methodId, model };
|
|
7446
7401
|
};
|
|
7447
7402
|
const configModelWithLogs = (data, logs, previousModelSuccess = false) => (model) => {
|
|
7448
7403
|
const status = logStatus(data, logs, model, previousModelSuccess);
|
|
@@ -7771,25 +7726,22 @@ class NodeLogsModelsLogsStatusComponent {
|
|
|
7771
7726
|
return values.some(v => 'methodTier' in v && v.methodTier === methodTier);
|
|
7772
7727
|
}
|
|
7773
7728
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: NodeLogsModelsLogsStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7774
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: NodeLogsModelsLogsStatusComponent, isStandalone: true, selector: "he-node-logs-models-logs-status", inputs: { nodeType: { classPropertyName: "nodeType", publicName: "nodeType", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ modelStatus() }}</span>\n</div>\n\n@if (modelStatus() === LogStatus.notRequired && modelLogs().is_not_relevant === 'True') {\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().logs?.siteType_allowed === 'False') {\n <li>\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n }\n @if (modelLogs().logs?.product_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.site_measurement_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Measurement</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.product_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n </ul>\n}\n\n@if (modelLogs() && modelStatus() !== LogStatus.notRequired && modelStatus() !== LogStatus.skipHierarchy) {\n @let config = model().config;\n\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().shouldRunOrchestrator === false) {\n <li class=\"is-no-run-orchestrator\">\n @if (!modelLogs().runRequired) {\n @if (modelLogs().logs?.node_type_allowed === 'False') {\n <span class=\"is-run-node-type-not-allowed\">\n This model should not run for {{ nodeType() | pluralize: 0 }}\n </span>\n }\n }\n @if (config) {\n <p class=\"is-run-strategy-{{ config.runStrategy }}\">\n @switch (config.runStrategy) {\n @case ('always') {\n <span></span>\n }\n @case ('add_key_if_missing') {\n <span>We only gap-fill this key if not present</span>\n }\n @case ('add_blank_node_if_missing') {\n <span>We only gap-fill this Blank Node if not present.</span>\n }\n }\n </p>\n <p class=\"is-mt-1\">\n @if (config.runArgs?.runNonMeasured && hasMethodTier(data().original, EmissionMethodTier.measured)) {\n <span class=\"is-run-with-measured\">\n The\n <code class=\"is-mx-1\">{{ config.value }}</code>\n was reported as measured.\n </span>\n }\n </p>\n } @else if (modelLogs().logs?.is_empty === 'False') {\n <span class=\"is-run-not-empty\">\n The {{ data().type || 'blank node' }} with Term\n <code class=\"is-mx-1\">{{ data().termId }}</code>\n is already present or already added by another model.\n </span>\n }\n </li>\n } @else {\n <li class=\"is-run-orchestrator\">\n @if (modelLogs().shouldRun) {\n <p>All the requirements were met to run the model.</p>\n } @else {\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on
|
|
7729
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: NodeLogsModelsLogsStatusComponent, isStandalone: true, selector: "he-node-logs-models-logs-status", inputs: { nodeType: { classPropertyName: "nodeType", publicName: "nodeType", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ modelStatus() }}</span>\n</div>\n\n@if (modelStatus() === LogStatus.notRequired && modelLogs().is_not_relevant === 'True') {\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().logs?.siteType_allowed === 'False') {\n <li>\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n }\n @if (modelLogs().logs?.product_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.site_measurement_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Measurement</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.product_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n </ul>\n}\n\n@if (modelLogs() && modelStatus() !== LogStatus.notRequired && modelStatus() !== LogStatus.skipHierarchy) {\n @let config = model().config;\n\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().shouldRunOrchestrator === false) {\n <li class=\"is-no-run-orchestrator\">\n @if (!modelLogs().runRequired) {\n @if (modelLogs().logs?.node_type_allowed === 'False') {\n <span class=\"is-run-node-type-not-allowed\">\n This model should not run for {{ nodeType() | pluralize: 0 }}\n </span>\n }\n }\n @if (config) {\n <p class=\"is-run-strategy-{{ config.runStrategy }}\">\n @switch (config.runStrategy) {\n @case ('always') {\n <span></span>\n }\n @case ('add_key_if_missing') {\n <span>We only gap-fill this key if not present</span>\n }\n @case ('add_blank_node_if_missing') {\n <span>We only gap-fill this Blank Node if not present.</span>\n }\n }\n </p>\n <p class=\"is-mt-1\">\n @if (config.runArgs?.runNonMeasured && hasMethodTier(data().original, EmissionMethodTier.measured)) {\n <span class=\"is-run-with-measured\">\n The\n <code class=\"is-mx-1\">{{ config.value }}</code>\n was reported as measured.\n </span>\n }\n </p>\n } @else if (modelLogs().logs?.is_empty === 'False') {\n <span class=\"is-run-not-empty\">\n The {{ data().type || 'blank node' }} with Term\n <code class=\"is-mx-1\">{{ data().termId }}</code>\n is already present or already added by another model.\n </span>\n }\n </li>\n } @else {\n <li class=\"is-run-orchestrator\">\n @if (modelStatus() === LogStatus.success || modelLogs().shouldRun) {\n <p>All the requirements were met to run the model.</p>\n } @else {\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on \"logs\" to view the debugging logs when available.</p>\n }\n @if (modelLogs().logs?.error) {\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ modelLogs().logs.error }}</code>\n </p>\n }\n </li>\n }\n @if (modelLogs().replaceLowerTier !== undefined) {\n <li>\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n @if (modelLogs().replaceLowerTier) {\n <span class=\"is-pl-1 is-underlined\">higher than or equal to</span>\n } @else {\n <span class=\"is-pl-1 is-underlined\">lower than</span>\n }\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n }\n @if (modelLogs().replaceLowerTier) {\n <li class=\"is-merge-replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n @if (config?.mergeArgs) {\n @if (modelLogs().replaceThreshold) {\n <span class=\"is-underlined\">more than or equal to</span>\n } @else {\n <span class=\"is-underlined\">less than</span>\n }\n <b class=\"is-pl-1\">{{ config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n } @else {\n @if (modelLogs().replaceThreshold) {\n <span class=\"is-underlined\">sufficiently</span>\n } @else {\n <span class=\"is-underlined\">not sufficiently</span>\n }\n }\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n }\n </ul>\n}\n", styles: [""], dependencies: [{ kind: "pipe", type: PluralizePipe, name: "pluralize" }] }); }
|
|
7775
7730
|
}
|
|
7776
7731
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: NodeLogsModelsLogsStatusComponent, decorators: [{
|
|
7777
7732
|
type: Component$1,
|
|
7778
|
-
args: [{ selector: 'he-node-logs-models-logs-status', imports: [PluralizePipe], template: "<div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ modelStatus() }}</span>\n</div>\n\n@if (modelStatus() === LogStatus.notRequired && modelLogs().is_not_relevant === 'True') {\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().logs?.siteType_allowed === 'False') {\n <li>\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n }\n @if (modelLogs().logs?.product_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.site_measurement_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Measurement</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.product_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n </ul>\n}\n\n@if (modelLogs() && modelStatus() !== LogStatus.notRequired && modelStatus() !== LogStatus.skipHierarchy) {\n @let config = model().config;\n\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().shouldRunOrchestrator === false) {\n <li class=\"is-no-run-orchestrator\">\n @if (!modelLogs().runRequired) {\n @if (modelLogs().logs?.node_type_allowed === 'False') {\n <span class=\"is-run-node-type-not-allowed\">\n This model should not run for {{ nodeType() | pluralize: 0 }}\n </span>\n }\n }\n @if (config) {\n <p class=\"is-run-strategy-{{ config.runStrategy }}\">\n @switch (config.runStrategy) {\n @case ('always') {\n <span></span>\n }\n @case ('add_key_if_missing') {\n <span>We only gap-fill this key if not present</span>\n }\n @case ('add_blank_node_if_missing') {\n <span>We only gap-fill this Blank Node if not present.</span>\n }\n }\n </p>\n <p class=\"is-mt-1\">\n @if (config.runArgs?.runNonMeasured && hasMethodTier(data().original, EmissionMethodTier.measured)) {\n <span class=\"is-run-with-measured\">\n The\n <code class=\"is-mx-1\">{{ config.value }}</code>\n was reported as measured.\n </span>\n }\n </p>\n } @else if (modelLogs().logs?.is_empty === 'False') {\n <span class=\"is-run-not-empty\">\n The {{ data().type || 'blank node' }} with Term\n <code class=\"is-mx-1\">{{ data().termId }}</code>\n is already present or already added by another model.\n </span>\n }\n </li>\n } @else {\n <li class=\"is-run-orchestrator\">\n @if (modelLogs().shouldRun) {\n <p>All the requirements were met to run the model.</p>\n } @else {\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on
|
|
7733
|
+
args: [{ selector: 'he-node-logs-models-logs-status', imports: [PluralizePipe], template: "<div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ modelStatus() }}</span>\n</div>\n\n@if (modelStatus() === LogStatus.notRequired && modelLogs().is_not_relevant === 'True') {\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().logs?.siteType_allowed === 'False') {\n <li>\n The\n <code class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n }\n @if (modelLogs().logs?.product_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.site_measurement_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Measurement</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.product_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_id_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n }\n @if (modelLogs().logs?.input_termType_allowed === 'False') {\n <li>\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n }\n </ul>\n}\n\n@if (modelLogs() && modelStatus() !== LogStatus.notRequired && modelStatus() !== LogStatus.skipHierarchy) {\n @let config = model().config;\n\n <ul class=\"is-pl-3 is-list-style-disc\">\n @if (modelLogs().shouldRunOrchestrator === false) {\n <li class=\"is-no-run-orchestrator\">\n @if (!modelLogs().runRequired) {\n @if (modelLogs().logs?.node_type_allowed === 'False') {\n <span class=\"is-run-node-type-not-allowed\">\n This model should not run for {{ nodeType() | pluralize: 0 }}\n </span>\n }\n }\n @if (config) {\n <p class=\"is-run-strategy-{{ config.runStrategy }}\">\n @switch (config.runStrategy) {\n @case ('always') {\n <span></span>\n }\n @case ('add_key_if_missing') {\n <span>We only gap-fill this key if not present</span>\n }\n @case ('add_blank_node_if_missing') {\n <span>We only gap-fill this Blank Node if not present.</span>\n }\n }\n </p>\n <p class=\"is-mt-1\">\n @if (config.runArgs?.runNonMeasured && hasMethodTier(data().original, EmissionMethodTier.measured)) {\n <span class=\"is-run-with-measured\">\n The\n <code class=\"is-mx-1\">{{ config.value }}</code>\n was reported as measured.\n </span>\n }\n </p>\n } @else if (modelLogs().logs?.is_empty === 'False') {\n <span class=\"is-run-not-empty\">\n The {{ data().type || 'blank node' }} with Term\n <code class=\"is-mx-1\">{{ data().termId }}</code>\n is already present or already added by another model.\n </span>\n }\n </li>\n } @else {\n <li class=\"is-run-orchestrator\">\n @if (modelStatus() === LogStatus.success || modelLogs().shouldRun) {\n <p>All the requirements were met to run the model.</p>\n } @else {\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on \"logs\" to view the debugging logs when available.</p>\n }\n @if (modelLogs().logs?.error) {\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ modelLogs().logs.error }}</code>\n </p>\n }\n </li>\n }\n @if (modelLogs().replaceLowerTier !== undefined) {\n <li>\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n @if (modelLogs().replaceLowerTier) {\n <span class=\"is-pl-1 is-underlined\">higher than or equal to</span>\n } @else {\n <span class=\"is-pl-1 is-underlined\">lower than</span>\n }\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n }\n @if (modelLogs().replaceLowerTier) {\n <li class=\"is-merge-replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n @if (config?.mergeArgs) {\n @if (modelLogs().replaceThreshold) {\n <span class=\"is-underlined\">more than or equal to</span>\n } @else {\n <span class=\"is-underlined\">less than</span>\n }\n <b class=\"is-pl-1\">{{ config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n } @else {\n @if (modelLogs().replaceThreshold) {\n <span class=\"is-underlined\">sufficiently</span>\n } @else {\n <span class=\"is-underlined\">not sufficiently</span>\n }\n }\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n }\n </ul>\n}\n" }]
|
|
7779
7734
|
}], propDecorators: { nodeType: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeType", required: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }] } });
|
|
7780
7735
|
|
|
7781
7736
|
class GuideOverlayService {
|
|
7782
7737
|
constructor() {
|
|
7783
|
-
this.ngZone = inject(NgZone);
|
|
7784
7738
|
this.message = signal(null, ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
7785
7739
|
this.messageListener = ({ data }) => {
|
|
7786
7740
|
if (data.namespace == guideNamespace) {
|
|
7787
|
-
this.
|
|
7741
|
+
this.message.set(data);
|
|
7788
7742
|
}
|
|
7789
7743
|
};
|
|
7790
|
-
this.
|
|
7791
|
-
window.addEventListener('message', this.messageListener);
|
|
7792
|
-
});
|
|
7744
|
+
window.addEventListener('message', this.messageListener);
|
|
7793
7745
|
}
|
|
7794
7746
|
ngOnDestroy() {
|
|
7795
7747
|
window.removeEventListener('message', this.messageListener);
|
|
@@ -7905,8 +7857,8 @@ const methodIdLabel = (methodId, _model) => (methodId
|
|
|
7905
7857
|
const getModelsAt = (log, index) => ('modelsInSubValues' in log ? !log.modelsInSubValues || !log.isOpen : true) && log.configModels?.[index];
|
|
7906
7858
|
const isSystemBoundary = (termId) => ({ isRecalculated, isRequired }) => {
|
|
7907
7859
|
// only exists for some terms
|
|
7908
|
-
const inSystemBoundary =
|
|
7909
|
-
return
|
|
7860
|
+
const inSystemBoundary = isInSystemBoundary(termId);
|
|
7861
|
+
return inSystemBoundary || [isRecalculated, isRequired].some(Boolean);
|
|
7910
7862
|
};
|
|
7911
7863
|
const isGenericTerm = (termId) => [termId.startsWith('excreta')].every(Boolean);
|
|
7912
7864
|
const extraTermIdsFromConfig = (config, key, logs) => unique([
|
|
@@ -7945,7 +7897,7 @@ const restrictTermTypeFromKey = {
|
|
|
7945
7897
|
...matchTermTypeFromKey
|
|
7946
7898
|
};
|
|
7947
7899
|
const filterBlankNode = ({ term: { name, '@id': id }, subValues, ...log }, selectedTerm, filterTermTypes, onlyRequired) => selectedTerm
|
|
7948
|
-
? name.toLowerCase().includes(selectedTerm.toLowerCase())
|
|
7900
|
+
? name.toLowerCase().includes(selectedTerm.name.toLowerCase())
|
|
7949
7901
|
: !filterTermTypes?.length || !onlyRequired || isSystemBoundary(id)(log) || subValues.some(isSystemBoundary(id));
|
|
7950
7902
|
const orderBlankNodesByNodeKey = {
|
|
7951
7903
|
emissions: values => orderBy(values.map(value => ({
|
|
@@ -7985,7 +7937,7 @@ class NodeLogsModelsComponent {
|
|
|
7985
7937
|
this.logIcon = logIcon;
|
|
7986
7938
|
this.logColor = logColor;
|
|
7987
7939
|
this.getModelsAt = getModelsAt;
|
|
7988
|
-
this.
|
|
7940
|
+
this.isInSystemBoundary = isInSystemBoundary;
|
|
7989
7941
|
this.showLegend = signal(true, ...(ngDevMode ? [{ debugName: "showLegend" }] : []));
|
|
7990
7942
|
this.onlyRequired = signal(true, ...(ngDevMode ? [{ debugName: "onlyRequired" }] : []));
|
|
7991
7943
|
this.schemaType = computed(() => (this.originalValues()?.[0]?.['@type'] ||
|
|
@@ -8119,8 +8071,9 @@ class NodeLogsModelsComponent {
|
|
|
8119
8071
|
});
|
|
8120
8072
|
this.termsById = computed(() => this.termsByIdResource.value() ?? {}, ...(ngDevMode ? [{ debugName: "termsById" }] : []));
|
|
8121
8073
|
// filter list of results by a single Term
|
|
8122
|
-
this.term = signal(
|
|
8074
|
+
this.term = signal(undefined, ...(ngDevMode ? [{ debugName: "term" }] : []));
|
|
8123
8075
|
this.enableFilterByTerm = computed(() => this.allTerms()?.length > 0, ...(ngDevMode ? [{ debugName: "enableFilterByTerm" }] : []));
|
|
8076
|
+
this.termFormatter = ({ name }) => name;
|
|
8124
8077
|
this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), map(v => this.suggestByTerm(v)));
|
|
8125
8078
|
this.typeaheadFocus = typeaheadFocus;
|
|
8126
8079
|
this.loading = computed(() => [
|
|
@@ -8138,9 +8091,7 @@ class NodeLogsModelsComponent {
|
|
|
8138
8091
|
this.isNumber = (value) => typeof value === 'number';
|
|
8139
8092
|
}
|
|
8140
8093
|
suggestByTerm(term) {
|
|
8141
|
-
return this.allTerms()
|
|
8142
|
-
.map(({ name }) => name)
|
|
8143
|
-
.filter(v => termSearch(v).includes(termSearch(term)));
|
|
8094
|
+
return this.allTerms().filter(v => termSearch(v.name).includes(termSearch(term)));
|
|
8144
8095
|
}
|
|
8145
8096
|
searchTerms(query, ...extraFields) {
|
|
8146
8097
|
return this.searchService
|
|
@@ -8180,7 +8131,7 @@ class NodeLogsModelsComponent {
|
|
|
8180
8131
|
return subValues.every(v => v.configModels.some(vv => vv.status === LogStatus.success));
|
|
8181
8132
|
}
|
|
8182
8133
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: NodeLogsModelsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8183
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: NodeLogsModelsComponent, isStandalone: true, selector: "he-node-logs-models", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, originalValues: { classPropertyName: "originalValues", publicName: "originalValues", isSignal: true, isRequired: false, transformFunction: null }, recalculatedValues: { classPropertyName: "recalculatedValues", publicName: "recalculatedValues", isSignal: true, isRequired: false, transformFunction: null }, terms: { classPropertyName: "terms", publicName: "terms", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypes: { classPropertyName: "filterTermTypes", publicName: "filterTermTypes", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypesLabel: { classPropertyName: "filterTermTypesLabel", publicName: "filterTermTypesLabel", isSignal: true, isRequired: false, transformFunction: null }, logsKey: { classPropertyName: "logsKey", publicName: "logsKey", isSignal: true, isRequired: false, transformFunction: null }, noDataMessage: { classPropertyName: "noDataMessage", publicName: "noDataMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n\n @if (!isExternal && !loading() && logsUrl() && hasLogs()) {\n <a class=\"is-size-7\" [href]=\"logsUrl()\" target=\"_blank\">\n <span>Open Full Logs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</div>\n\n@if (!isExternal && !loading() && !hasLogs()) {\n <p class=\"is-my-2\">\n <he-svg-icon class=\"has-text-warning\" name=\"exclamation-triangle\" />\n <span class=\"is-size-7 has-text-warning is-pl-1\">No logs found. Recalculation logs will be incomplete.</span>\n </p>\n}\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set('')\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>\n <span class=\"is-pr-1\">Units</span>\n @if (functionalUnit()) {\n <span>(per </span>\n <span>{{ functionalUnit() }}</span>\n <span>)</span>\n }\n </span>\n </div>\n </th>\n }\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Original</span>\n </div>\n </th>\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Recalculated</span>\n </div>\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Difference</span>\n </div>\n </th>\n }\n @for (c of methodModelsCount() | times; track i; let i = $index) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Model {{ i + 1 }}</span>\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n </td>\n </tr>\n } @else if (blankNodes().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"6\">\n <span>{{ noDataMessage() || 'No original data was provided and no gap filling occurred.' }}</span>\n </td>\n </tr>\n }\n @for (blankNode of blankNodes(); track trackByBlankNode($index, blankNode)) {\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td\n class=\"width-auto has-border-right is-nowrap\"\n [attr.title]=\"$any(blankNode).term?.name || $any(blankNode).key\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: blankNode }\" />\n @if ($any(blankNode).term) {\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"$any(blankNode).term\">\n <span\n class=\"break-word\"\n [innerHtml]=\"$any(blankNode).term.name | compound: $any(blankNode).term.termType\"></span>\n </he-node-link>\n } @else if ($any(blankNode).key) {\n @if (nodeKey() === 'completeness') {\n <a [href]=\"schemaBaseUrl + '/Completeness#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n } @else {\n <a [href]=\"schemaBaseUrl + '/' + nodeType() + '#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n }\n }\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if ($any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n <ng-template #originalValueContent>\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </ng-template>\n\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).originalValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span\n [class.trigger-popover]=\"!!$any(blankNode).original?.[0]?.methodModel\"\n [ngbPopover]=\"blankNodeOriginalValueDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n placement=\"bottom left right auto\"\n container=\"body\"\n [disablePopover]=\"!$any(blankNode).original?.[0]?.methodModel\"\n [popoverContext]=\"{ blankNode }\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </span>\n }\n </td>\n <td class=\"has-border-right\">\n @if (!blankNode.isOriginal || blankNode.isRecalculated) {\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).recalculatedValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: blankNode.recalculatedValue }\" />\n </span>\n }\n } @else if ($any(blankNode).configModels?.length) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right is-nowrap\">\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n @if (\n $any(blankNode).originalValueByMethodId[model.methodId] !== null &&\n $any(blankNode).recalculatedValueByMethodId[model.methodId] !== null\n ) {\n <he-blank-node-value-delta\n [value]=\"$any(blankNode).recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"$any(blankNode).originalValueByMethodId[model.methodId]\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n </div>\n }\n } @else {\n @if ($any(blankNode).original.length && blankNode.isRecalculated) {\n <he-blank-node-value-delta\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"$any(blankNode).originalValue\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n }\n </td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\" />\n </tr>\n @for (subValue of $any(blankNode).keys; track trackBySubValue(subValue)) {\n @if (blankNode.isOpen) {\n <tr [class.has-sub-rows]=\"$any(blankNode).subValues?.length\" [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n @if (blankNode.type) {\n <a\n class=\"is-inline-block is-pre-wrap\"\n [href]=\"schemaBaseUrl + '/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n }\n @if (!blankNode.type) {\n <span class=\"is-inline-block is-align-top\">{{ subValue.key }}</span>\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\"></td>\n }\n <td class=\"has-border-right\">\n @if (subValue.originalValue !== null) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated || subValue.key === 'impactAssessment') {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n } @else {\n not recalculated\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n }\n @for (subValue of $any(blankNode).subValues; track trackBySubValue(subValue)) {\n <ng-container *ngTemplateOutlet=\"subValueRow; context: { blankNode, parent: blankNode, subValue }\" />\n }\n }\n </tbody>\n </table>\n</he-data-table>\n<div class=\"is-size-7\">\n <div class=\"is-flex is-py-2 is-px-3 is-gap-16 | status-legend\">\n <div\n class=\"is-flex is-justify-content-center is-align-items-center is-align-content-center is-flex-wrap-wrap is-gap-8\">\n @for (status of LogStatus | keyvalue; track status.value) {\n @if (logIcon[status.value]) {\n <span class=\"is-flex is-align-items-center is-gap-8\">\n <he-svg-icon [name]=\"logIcon[status.value]\" size=\"20\" class=\"has-text-{{ logColor[status.value] }}\" />\n <span class=\"is-size-7 is-capitalized\">{{ status.value }}</span>\n </span>\n }\n }\n </div>\n\n @if (filteredType()) {\n <div class=\"field is-relative\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n [(ngModel)]=\"onlyRequired\"\n [disabled]=\"!!term()\"\n id=\"onlyRequired\" />\n <label class=\"is-size-7\" for=\"onlyRequired\">\n <span>Show only {{ filteredType() }} terms included in the default HESTIA system boundary</span>\n </label>\n </div>\n }\n </div>\n</div>\n\n<ng-template #valueContent let-value=\"value\">\n @if (isNumber(value)) {\n {{ value | precision: 3 | default: '-' }}\n } @else {\n {{ value | default: '-' }}\n }\n</ng-template>\n\n<ng-template #collapseButton let-blankNode>\n @if (blankNode.canOpen) {\n <a class=\"open-node\" (click)=\"toggleBlankNode(blankNode)\">\n <he-svg-icon [name]=\"blankNode.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n</ng-template>\n\n<ng-template #subValueRow let-blankNode=\"blankNode\" let-parent=\"parent\" let-subValue=\"subValue\" let-rowClass=\"rowClass\">\n @let term = subValue.term || termById(subValue.id);\n @if (parent.isOpen) {\n <tr [class.is-sub-row]=\"parent.canOpen\" [ngClass]=\"rowClass\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 h-100\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: subValue }\" />\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <div class=\"is-flex is-align-items-flex-start is-flex-wrap-wrap is-gap-4\" [class.is-pl-3]=\"!subValue.canOpen\">\n <span>\n <span>{{ subValue.key | keyToLabel }}</span>\n @if (subValue.id) {\n <span class=\"is-inline-block\">:</span>\n }\n </span>\n @if (subValue.id) {\n @switch (subValue.key) {\n @case ('backgroundData') {\n <span class=\"is-inline-block\">{{ term?.name }}</span>\n }\n @case ('animal') {\n <span class=\"is-inline-block\">{{ subValue.id }}</span>\n }\n @default {\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-inline-block\"\n [node]=\"term\"\n [attr.title]=\"term?.name\">\n <span class=\"break-word\" [innerHtml]=\"term?.name | compound\"></span>\n </he-node-link>\n }\n }\n }\n </div>\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if (subValue.showUnits && $any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n @if (!isEmpty(subValue.originalValue)) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated) {\n @if (subValue.multiGroups) {\n <span\n class=\"trigger-popover\"\n ngbPopover=\"The total value across all inputs\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow is-overflow-visible\"\n placement=\"left bottom auto\"\n container=\"body\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n </span>\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n }\n } @else if (!isEmpty(subValue.originalValue)) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n @if (subValue.subValues) {\n @for (sub of subValue.subValues; track trackBySubValue(sub)) {\n <ng-container\n *ngTemplateOutlet=\"\n subValueRow;\n context: { blankNode, parent: subValue, subValue: sub, rowClass: 'is-sub-sub-row' }\n \" />\n }\n }\n</ng-template>\n\n<ng-template #blankNodeOriginalValueDetails let-blankNode=\"blankNode\">\n <span class=\"is-pr-1\">The original value was reported using:</span>\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-dark\"\n [node]=\"$any(blankNode).original[0].methodModel\"\n [showExternalLink]=\"true\">\n <span>{{ $any(blankNode).original[0].methodModel.name }}</span>\n </he-node-link>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n @let extraColumns = methodModelsCount() - 1;\n\n <ng-template #notInSystemBoundary>\n <td class=\"has-border-right\">\n <span>Not in HESTIA system boundary</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n </ng-template>\n\n @if (data.canOpen && !data.isOpen && !data.configModels?.length) {\n <td class=\"has-border-right\">\n <span>Expand to see logs (</span>\n @let key = subValuesKey(data, 'sub-values');\n @if (hasCompleteSuccess(data)) {\n <span>all succeeded</span>\n <he-svg-icon class=\"is-ml-1\" name=\"checkmark\" class=\"has-text-success\" />\n } @else {\n <span>some failed</span>\n <he-svg-icon class=\"is-ml-1\" name=\"xmark\" class=\"has-text-danger\" />\n }\n <span>)</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n } @else if (isSystemBoundary(data)) {\n @for (configModel of methodModelsCount() | times; track configModelIndex; let configModelIndex = $index) {\n <td class=\"has-border-right blank-node-index-{{ configModelIndex }}\">\n @if (getModelsAt(data, configModelIndex); as models) {\n @if ($any(models) | isArray) {\n <div>\n @for (model of $any(models); track model.methodId) {\n <p>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\" />\n </p>\n }\n </div>\n } @else {\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\" />\n }\n } @else {\n -\n }\n </td>\n }\n } @else {\n -\n }\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <div class=\"is-flex is-align-self-stretch is-justify-content-center is-align-items-center is-gap-8\">\n <div class=\"is-flex is-gap-4 is-flex-grow-1 is-align-items-center\">\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }}\"\n [class.trigger-popover]=\"hasLogs()\"\n [ngbPopover]=\"logStatusDetails\"\n [disablePopover]=\"!hasLogs()\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <he-svg-icon [name]=\"logIcon[model.status]\" />\n </span>\n\n <span class=\"is-flex is-flex-grow-1 is-gap-4\">\n <span class=\"is-nowrap is-capitalized\">{{ methodName(model) }}</span>\n\n @if (model.logs?.methodTier || model.model?.methodTier) {\n <span class=\"is-nowrap\">[{{ model.logs?.methodTier || model.model?.methodTier }}]</span>\n }\n </span>\n </div>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n @if (model.showLogs) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"logDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n }\n\n @if (model.model) {\n @if (model.showLogs) {\n <div class=\"vertical-divider\"></div>\n }\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\" />\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <he-node-logs-models-logs [logs]=\"logs\" />\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <he-node-logs-models-logs-status [nodeType]=\"nodeType()\" [model]=\"model\" [data]=\"\" />\n</ng-template>\n\n<ng-template #docsLink let-model>\n @if (guideEnabled && model.guidePath) {\n <he-guide-overlay [pageId]=\"model.guidePath\" [width]=\"500\" />\n } @else {\n <a [href]=\"model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .status-legend{border:1px solid #dbe3ea;background:#f5f7f9}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row td:first-child{padding-left:12px}::ng-deep .table .is-sub-row .sub-sub-row-icon{display:none}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon{display:inline-block}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon+div{padding-left:0!important}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "dataState", "showExternalLink", "linkClass"] }, { kind: "component", type: BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType", "useCustomFunctions"] }, { kind: "directive", type: NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "selectOnExact", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: NodeLogsModelsLogsComponent, selector: "he-node-logs-models-logs", inputs: ["logs"] }, { kind: "component", type: NodeLogsModelsLogsStatusComponent, selector: "he-node-logs-models-logs-status", inputs: ["nodeType", "model", "data"] }, { kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "component", type: GuideOverlayComponent, selector: "he-guide-overlay", inputs: ["pageId", "width", "height", "positions"], outputs: ["widthChange", "heightChange"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: CompoundPipe, name: "compound" }, { kind: "pipe", type: DefaultPipe, name: "default" }, { kind: "pipe", type: KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: PrecisionPipe, name: "precision" }, { kind: "pipe", type: TimesPipe, name: "times" }, { kind: "pipe", type: IsArrayPipe, name: "isArray" }, { kind: "pipe", type: RepeatPipe, name: "repeat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8134
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: NodeLogsModelsComponent, isStandalone: true, selector: "he-node-logs-models", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, originalValues: { classPropertyName: "originalValues", publicName: "originalValues", isSignal: true, isRequired: false, transformFunction: null }, recalculatedValues: { classPropertyName: "recalculatedValues", publicName: "recalculatedValues", isSignal: true, isRequired: false, transformFunction: null }, terms: { classPropertyName: "terms", publicName: "terms", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypes: { classPropertyName: "filterTermTypes", publicName: "filterTermTypes", isSignal: true, isRequired: false, transformFunction: null }, filterTermTypesLabel: { classPropertyName: "filterTermTypesLabel", publicName: "filterTermTypesLabel", isSignal: true, isRequired: false, transformFunction: null }, logsKey: { classPropertyName: "logsKey", publicName: "logsKey", isSignal: true, isRequired: false, transformFunction: null }, noDataMessage: { classPropertyName: "noDataMessage", publicName: "noDataMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n\n @if (!isExternal && !loading() && logsUrl() && hasLogs()) {\n <a class=\"is-size-7\" [href]=\"logsUrl()\" target=\"_blank\">\n <span>Open Full Logs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</div>\n\n@if (!isExternal && !loading() && !hasLogs()) {\n <p class=\"is-my-2\">\n <he-svg-icon class=\"has-text-warning\" name=\"exclamation-triangle\" />\n <span class=\"is-size-7 has-text-warning is-pl-1\">No logs found. Recalculation logs will be incomplete.</span>\n </p>\n}\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [resultFormatter]=\"termFormatter\"\n [inputFormatter]=\"termFormatter\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set(undefined)\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>\n <span class=\"is-pr-1\">Units</span>\n @if (functionalUnit()) {\n <span>(per </span>\n <span>{{ functionalUnit() }}</span>\n <span>)</span>\n }\n </span>\n </div>\n </th>\n }\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Original</span>\n </div>\n </th>\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Recalculated</span>\n </div>\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Difference</span>\n </div>\n </th>\n }\n @for (c of methodModelsCount() | times; track i; let i = $index) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Model {{ i + 1 }}</span>\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n </td>\n </tr>\n } @else if (blankNodes().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <p class=\"is-p-1\">\n @if (noDataMessage()) {\n <span>{{ noDataMessage() }}</span>\n } @else {\n <ng-container *ngTemplateOutlet=\"noResultsDefaultMessage\" />\n }\n </p>\n </td>\n </tr>\n }\n @for (blankNode of blankNodes(); track trackByBlankNode($index, blankNode)) {\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td\n class=\"width-auto has-border-right is-nowrap\"\n [attr.title]=\"$any(blankNode).term?.name || $any(blankNode).key\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: blankNode }\" />\n @if ($any(blankNode).term) {\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"$any(blankNode).term\">\n <span\n class=\"break-word\"\n [innerHtml]=\"$any(blankNode).term.name | compound: $any(blankNode).term.termType\"></span>\n </he-node-link>\n } @else if ($any(blankNode).key) {\n @if (nodeKey() === 'completeness') {\n <a [href]=\"schemaBaseUrl + '/Completeness#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n } @else {\n <a [href]=\"schemaBaseUrl + '/' + nodeType() + '#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n }\n }\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if ($any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n <ng-template #originalValueContent>\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </ng-template>\n\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).originalValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span\n [class.trigger-popover]=\"!!$any(blankNode).original?.[0]?.methodModel\"\n [ngbPopover]=\"blankNodeOriginalValueDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n placement=\"bottom left right auto\"\n container=\"body\"\n [disablePopover]=\"!$any(blankNode).original?.[0]?.methodModel\"\n [popoverContext]=\"{ blankNode }\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </span>\n }\n </td>\n <td class=\"has-border-right\">\n @if (!blankNode.isOriginal || blankNode.isRecalculated) {\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).recalculatedValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: blankNode.recalculatedValue }\" />\n </span>\n }\n } @else if ($any(blankNode).configModels?.length) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right is-nowrap\">\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n @if (\n $any(blankNode).originalValueByMethodId[model.methodId] !== null &&\n $any(blankNode).recalculatedValueByMethodId[model.methodId] !== null\n ) {\n <he-blank-node-value-delta\n [value]=\"$any(blankNode).recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"$any(blankNode).originalValueByMethodId[model.methodId]\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n </div>\n }\n } @else {\n @if ($any(blankNode).original.length && blankNode.isRecalculated) {\n <he-blank-node-value-delta\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"$any(blankNode).originalValue\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n }\n </td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\" />\n </tr>\n @for (subValue of $any(blankNode).keys; track trackBySubValue(subValue)) {\n @if (blankNode.isOpen) {\n <tr [class.has-sub-rows]=\"$any(blankNode).subValues?.length\" [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n @if (blankNode.type) {\n <a\n class=\"is-inline-block is-pre-wrap\"\n [href]=\"schemaBaseUrl + '/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n }\n @if (!blankNode.type) {\n <span class=\"is-inline-block is-align-top\">{{ subValue.key }}</span>\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\"></td>\n }\n <td class=\"has-border-right\">\n @if (subValue.originalValue !== null) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated || subValue.key === 'impactAssessment') {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n } @else {\n not recalculated\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n }\n @for (subValue of $any(blankNode).subValues; track trackBySubValue(subValue)) {\n <ng-container *ngTemplateOutlet=\"subValueRow; context: { blankNode, parent: blankNode, subValue }\" />\n }\n }\n </tbody>\n </table>\n</he-data-table>\n<div class=\"is-size-7\">\n <div class=\"is-flex is-py-2 is-px-3 is-gap-16 | status-legend\">\n <div\n class=\"is-flex is-justify-content-center is-align-items-center is-align-content-center is-flex-wrap-wrap is-gap-8\">\n @for (status of LogStatus | keyvalue; track status.value) {\n @if (logIcon[status.value]) {\n <span class=\"is-flex is-align-items-center is-gap-8\">\n <he-svg-icon [name]=\"logIcon[status.value]\" size=\"20\" class=\"has-text-{{ logColor[status.value] }}\" />\n <span class=\"is-size-7 is-capitalized\">{{ status.value }}</span>\n </span>\n }\n }\n </div>\n\n @if (filteredType()) {\n <div class=\"field is-relative\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n [(ngModel)]=\"onlyRequired\"\n [disabled]=\"!!term()\"\n id=\"onlyRequired\" />\n <label class=\"is-size-7\" for=\"onlyRequired\">\n <span>Show only {{ filteredType() }} terms included in the default HESTIA system boundary</span>\n </label>\n </div>\n }\n </div>\n</div>\n\n<ng-template #noResultsDefaultMessage>\n <span>No original data was provided and no gap filling occurred</span>\n @if (term() && !isInSystemBoundary(term()['@id'])) {\n <span class=\"is-pl-1\">as</span>\n <i class=\"is-px-1\">{{ term().name }}</i>\n <span>is not in the HESTIA system boundary</span>\n }\n <span>.</span>\n</ng-template>\n\n<ng-template #valueContent let-value=\"value\">\n @if (isNumber(value)) {\n {{ value | precision: 3 | default: '-' }}\n } @else {\n {{ value | default: '-' }}\n }\n</ng-template>\n\n<ng-template #collapseButton let-blankNode>\n @if (blankNode.canOpen) {\n <a class=\"open-node\" (click)=\"toggleBlankNode(blankNode)\">\n <he-svg-icon [name]=\"blankNode.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n</ng-template>\n\n<ng-template #subValueRow let-blankNode=\"blankNode\" let-parent=\"parent\" let-subValue=\"subValue\" let-rowClass=\"rowClass\">\n @let term = subValue.term || termById(subValue.id);\n @if (parent.isOpen) {\n <tr [class.is-sub-row]=\"parent.canOpen\" [ngClass]=\"rowClass\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 h-100\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: subValue }\" />\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <div class=\"is-flex is-align-items-flex-start is-flex-wrap-wrap is-gap-4\" [class.is-pl-3]=\"!subValue.canOpen\">\n <span>\n <span>{{ subValue.key | keyToLabel }}</span>\n @if (subValue.id) {\n <span class=\"is-inline-block\">:</span>\n }\n </span>\n @if (subValue.id) {\n @switch (subValue.key) {\n @case ('backgroundData') {\n <span class=\"is-inline-block\">{{ term?.name }}</span>\n }\n @case ('animal') {\n <span class=\"is-inline-block\">{{ subValue.id }}</span>\n }\n @default {\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-inline-block\"\n [node]=\"term\"\n [attr.title]=\"term?.name\">\n <span class=\"break-word\" [innerHtml]=\"term?.name | compound\"></span>\n </he-node-link>\n }\n }\n }\n </div>\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if (subValue.showUnits && $any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n @if (!isEmpty(subValue.originalValue)) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated) {\n @if (subValue.multiGroups) {\n <span\n class=\"trigger-popover\"\n ngbPopover=\"The total value across all inputs\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow is-overflow-visible\"\n placement=\"left bottom auto\"\n container=\"body\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n </span>\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n }\n } @else if (!isEmpty(subValue.originalValue)) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n @if (subValue.subValues) {\n @for (sub of subValue.subValues; track trackBySubValue(sub)) {\n <ng-container\n *ngTemplateOutlet=\"\n subValueRow;\n context: { blankNode, parent: subValue, subValue: sub, rowClass: 'is-sub-sub-row' }\n \" />\n }\n }\n</ng-template>\n\n<ng-template #blankNodeOriginalValueDetails let-blankNode=\"blankNode\">\n <span class=\"is-pr-1\">The original value was reported using:</span>\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-dark\"\n [node]=\"$any(blankNode).original[0].methodModel\"\n [showExternalLink]=\"true\">\n <span>{{ $any(blankNode).original[0].methodModel.name }}</span>\n </he-node-link>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n @let extraColumns = methodModelsCount() - 1;\n\n <ng-template #notInSystemBoundary>\n <td class=\"has-border-right\">\n <span>Not in HESTIA system boundary</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n </ng-template>\n\n @if (data.canOpen && !data.isOpen && !data.configModels?.length) {\n <td class=\"has-border-right\">\n <span>Expand to see logs (</span>\n @let key = subValuesKey(data, 'sub-values');\n @if (hasCompleteSuccess(data)) {\n <span>all succeeded</span>\n <he-svg-icon class=\"is-ml-1\" name=\"checkmark\" class=\"has-text-success\" />\n } @else {\n <span>some failed</span>\n <he-svg-icon class=\"is-ml-1\" name=\"xmark\" class=\"has-text-danger\" />\n }\n <span>)</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n } @else {\n @for (configModel of methodModelsCount() | times; track configModelIndex; let configModelIndex = $index) {\n <td class=\"has-border-right blank-node-index-{{ configModelIndex }}\">\n @if (getModelsAt(data, configModelIndex); as models) {\n @if ($any(models) | isArray) {\n <div>\n @for (model of $any(models); track model.methodId) {\n <p>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\" />\n </p>\n }\n </div>\n } @else {\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\" />\n }\n } @else {\n -\n }\n </td>\n }\n }\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <div class=\"is-flex is-align-self-stretch is-justify-content-center is-align-items-center is-gap-8\">\n <div class=\"is-flex is-gap-4 is-flex-grow-1 is-align-items-center\">\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }}\"\n [class.trigger-popover]=\"hasLogs()\"\n [ngbPopover]=\"logStatusDetails\"\n [disablePopover]=\"!hasLogs()\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <he-svg-icon [name]=\"logIcon[model.status]\" />\n </span>\n\n <span class=\"is-flex is-flex-grow-1 is-gap-4\">\n <span class=\"is-nowrap is-capitalized\">{{ methodName(model) }}</span>\n\n @if (model.logs?.methodTier || model.model?.methodTier) {\n <span class=\"is-nowrap\">[{{ model.logs?.methodTier || model.model?.methodTier }}]</span>\n }\n </span>\n </div>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n @if (model.showLogs) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"logDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n }\n\n @if (model.model) {\n @if (model.showLogs) {\n <div class=\"vertical-divider\"></div>\n }\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\" />\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <he-node-logs-models-logs [logs]=\"logs\" />\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <he-node-logs-models-logs-status [nodeType]=\"nodeType()\" [model]=\"model\" [data]=\"\" />\n</ng-template>\n\n<ng-template #docsLink let-model>\n @if (guideEnabled && model.guidePath) {\n <he-guide-overlay [pageId]=\"model.guidePath\" [width]=\"500\" />\n } @else {\n <a [href]=\"model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .status-legend{border:1px solid #dbe3ea;background:#f5f7f9}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row td:first-child{padding-left:12px}::ng-deep .table .is-sub-row .sub-sub-row-icon{display:none}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon{display:inline-block}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon+div{padding-left:0!important}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "dataState", "showExternalLink", "linkClass"] }, { kind: "component", type: BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType", "useCustomFunctions"] }, { kind: "directive", type: NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "selectOnExact", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: NodeLogsModelsLogsComponent, selector: "he-node-logs-models-logs", inputs: ["logs"] }, { kind: "component", type: NodeLogsModelsLogsStatusComponent, selector: "he-node-logs-models-logs-status", inputs: ["nodeType", "model", "data"] }, { kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "component", type: GuideOverlayComponent, selector: "he-guide-overlay", inputs: ["pageId", "width", "height", "positions"], outputs: ["widthChange", "heightChange"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: CompoundPipe, name: "compound" }, { kind: "pipe", type: DefaultPipe, name: "default" }, { kind: "pipe", type: KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: PrecisionPipe, name: "precision" }, { kind: "pipe", type: TimesPipe, name: "times" }, { kind: "pipe", type: IsArrayPipe, name: "isArray" }, { kind: "pipe", type: RepeatPipe, name: "repeat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8184
8135
|
}
|
|
8185
8136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
|
|
8186
8137
|
type: Component$1,
|
|
@@ -8205,7 +8156,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
8205
8156
|
NodeLogsModelsLogsStatusComponent,
|
|
8206
8157
|
HESvgIconComponent,
|
|
8207
8158
|
GuideOverlayComponent
|
|
8208
|
-
], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n\n @if (!isExternal && !loading() && logsUrl() && hasLogs()) {\n <a class=\"is-size-7\" [href]=\"logsUrl()\" target=\"_blank\">\n <span>Open Full Logs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</div>\n\n@if (!isExternal && !loading() && !hasLogs()) {\n <p class=\"is-my-2\">\n <he-svg-icon class=\"has-text-warning\" name=\"exclamation-triangle\" />\n <span class=\"is-size-7 has-text-warning is-pl-1\">No logs found. Recalculation logs will be incomplete.</span>\n </p>\n}\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set('')\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>\n <span class=\"is-pr-1\">Units</span>\n @if (functionalUnit()) {\n <span>(per </span>\n <span>{{ functionalUnit() }}</span>\n <span>)</span>\n }\n </span>\n </div>\n </th>\n }\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Original</span>\n </div>\n </th>\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Recalculated</span>\n </div>\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Difference</span>\n </div>\n </th>\n }\n @for (c of methodModelsCount() | times; track i; let i = $index) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Model {{ i + 1 }}</span>\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n </td>\n </tr>\n } @else if (blankNodes().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"6\">\n <span>{{ noDataMessage() || 'No original data was provided and no gap filling occurred.' }}</span>\n </td>\n </tr>\n }\n @for (blankNode of blankNodes(); track trackByBlankNode($index, blankNode)) {\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td\n class=\"width-auto has-border-right is-nowrap\"\n [attr.title]=\"$any(blankNode).term?.name || $any(blankNode).key\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: blankNode }\" />\n @if ($any(blankNode).term) {\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"$any(blankNode).term\">\n <span\n class=\"break-word\"\n [innerHtml]=\"$any(blankNode).term.name | compound: $any(blankNode).term.termType\"></span>\n </he-node-link>\n } @else if ($any(blankNode).key) {\n @if (nodeKey() === 'completeness') {\n <a [href]=\"schemaBaseUrl + '/Completeness#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n } @else {\n <a [href]=\"schemaBaseUrl + '/' + nodeType() + '#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n }\n }\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if ($any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n <ng-template #originalValueContent>\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </ng-template>\n\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).originalValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span\n [class.trigger-popover]=\"!!$any(blankNode).original?.[0]?.methodModel\"\n [ngbPopover]=\"blankNodeOriginalValueDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n placement=\"bottom left right auto\"\n container=\"body\"\n [disablePopover]=\"!$any(blankNode).original?.[0]?.methodModel\"\n [popoverContext]=\"{ blankNode }\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </span>\n }\n </td>\n <td class=\"has-border-right\">\n @if (!blankNode.isOriginal || blankNode.isRecalculated) {\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).recalculatedValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: blankNode.recalculatedValue }\" />\n </span>\n }\n } @else if ($any(blankNode).configModels?.length) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right is-nowrap\">\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n @if (\n $any(blankNode).originalValueByMethodId[model.methodId] !== null &&\n $any(blankNode).recalculatedValueByMethodId[model.methodId] !== null\n ) {\n <he-blank-node-value-delta\n [value]=\"$any(blankNode).recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"$any(blankNode).originalValueByMethodId[model.methodId]\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n </div>\n }\n } @else {\n @if ($any(blankNode).original.length && blankNode.isRecalculated) {\n <he-blank-node-value-delta\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"$any(blankNode).originalValue\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n }\n </td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\" />\n </tr>\n @for (subValue of $any(blankNode).keys; track trackBySubValue(subValue)) {\n @if (blankNode.isOpen) {\n <tr [class.has-sub-rows]=\"$any(blankNode).subValues?.length\" [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n @if (blankNode.type) {\n <a\n class=\"is-inline-block is-pre-wrap\"\n [href]=\"schemaBaseUrl + '/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n }\n @if (!blankNode.type) {\n <span class=\"is-inline-block is-align-top\">{{ subValue.key }}</span>\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\"></td>\n }\n <td class=\"has-border-right\">\n @if (subValue.originalValue !== null) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated || subValue.key === 'impactAssessment') {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n } @else {\n not recalculated\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n }\n @for (subValue of $any(blankNode).subValues; track trackBySubValue(subValue)) {\n <ng-container *ngTemplateOutlet=\"subValueRow; context: { blankNode, parent: blankNode, subValue }\" />\n }\n }\n </tbody>\n </table>\n</he-data-table>\n<div class=\"is-size-7\">\n <div class=\"is-flex is-py-2 is-px-3 is-gap-16 | status-legend\">\n <div\n class=\"is-flex is-justify-content-center is-align-items-center is-align-content-center is-flex-wrap-wrap is-gap-8\">\n @for (status of LogStatus | keyvalue; track status.value) {\n @if (logIcon[status.value]) {\n <span class=\"is-flex is-align-items-center is-gap-8\">\n <he-svg-icon [name]=\"logIcon[status.value]\" size=\"20\" class=\"has-text-{{ logColor[status.value] }}\" />\n <span class=\"is-size-7 is-capitalized\">{{ status.value }}</span>\n </span>\n }\n }\n </div>\n\n @if (filteredType()) {\n <div class=\"field is-relative\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n [(ngModel)]=\"onlyRequired\"\n [disabled]=\"!!term()\"\n id=\"onlyRequired\" />\n <label class=\"is-size-7\" for=\"onlyRequired\">\n <span>Show only {{ filteredType() }} terms included in the default HESTIA system boundary</span>\n </label>\n </div>\n }\n </div>\n</div>\n\n<ng-template #valueContent let-value=\"value\">\n @if (isNumber(value)) {\n {{ value | precision: 3 | default: '-' }}\n } @else {\n {{ value | default: '-' }}\n }\n</ng-template>\n\n<ng-template #collapseButton let-blankNode>\n @if (blankNode.canOpen) {\n <a class=\"open-node\" (click)=\"toggleBlankNode(blankNode)\">\n <he-svg-icon [name]=\"blankNode.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n</ng-template>\n\n<ng-template #subValueRow let-blankNode=\"blankNode\" let-parent=\"parent\" let-subValue=\"subValue\" let-rowClass=\"rowClass\">\n @let term = subValue.term || termById(subValue.id);\n @if (parent.isOpen) {\n <tr [class.is-sub-row]=\"parent.canOpen\" [ngClass]=\"rowClass\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 h-100\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: subValue }\" />\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <div class=\"is-flex is-align-items-flex-start is-flex-wrap-wrap is-gap-4\" [class.is-pl-3]=\"!subValue.canOpen\">\n <span>\n <span>{{ subValue.key | keyToLabel }}</span>\n @if (subValue.id) {\n <span class=\"is-inline-block\">:</span>\n }\n </span>\n @if (subValue.id) {\n @switch (subValue.key) {\n @case ('backgroundData') {\n <span class=\"is-inline-block\">{{ term?.name }}</span>\n }\n @case ('animal') {\n <span class=\"is-inline-block\">{{ subValue.id }}</span>\n }\n @default {\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-inline-block\"\n [node]=\"term\"\n [attr.title]=\"term?.name\">\n <span class=\"break-word\" [innerHtml]=\"term?.name | compound\"></span>\n </he-node-link>\n }\n }\n }\n </div>\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if (subValue.showUnits && $any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n @if (!isEmpty(subValue.originalValue)) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated) {\n @if (subValue.multiGroups) {\n <span\n class=\"trigger-popover\"\n ngbPopover=\"The total value across all inputs\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow is-overflow-visible\"\n placement=\"left bottom auto\"\n container=\"body\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n </span>\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n }\n } @else if (!isEmpty(subValue.originalValue)) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n @if (subValue.subValues) {\n @for (sub of subValue.subValues; track trackBySubValue(sub)) {\n <ng-container\n *ngTemplateOutlet=\"\n subValueRow;\n context: { blankNode, parent: subValue, subValue: sub, rowClass: 'is-sub-sub-row' }\n \" />\n }\n }\n</ng-template>\n\n<ng-template #blankNodeOriginalValueDetails let-blankNode=\"blankNode\">\n <span class=\"is-pr-1\">The original value was reported using:</span>\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-dark\"\n [node]=\"$any(blankNode).original[0].methodModel\"\n [showExternalLink]=\"true\">\n <span>{{ $any(blankNode).original[0].methodModel.name }}</span>\n </he-node-link>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n @let extraColumns = methodModelsCount() - 1;\n\n <ng-template #notInSystemBoundary>\n <td class=\"has-border-right\">\n <span>Not in HESTIA system boundary</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n </ng-template>\n\n @if (data.canOpen && !data.isOpen && !data.configModels?.length) {\n <td class=\"has-border-right\">\n <span>Expand to see logs (</span>\n @let key = subValuesKey(data, 'sub-values');\n @if (hasCompleteSuccess(data)) {\n <span>all succeeded</span>\n <he-svg-icon class=\"is-ml-1\" name=\"checkmark\" class=\"has-text-success\" />\n } @else {\n <span>some failed</span>\n <he-svg-icon class=\"is-ml-1\" name=\"xmark\" class=\"has-text-danger\" />\n }\n <span>)</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n } @else if (isSystemBoundary(data)) {\n @for (configModel of methodModelsCount() | times; track configModelIndex; let configModelIndex = $index) {\n <td class=\"has-border-right blank-node-index-{{ configModelIndex }}\">\n @if (getModelsAt(data, configModelIndex); as models) {\n @if ($any(models) | isArray) {\n <div>\n @for (model of $any(models); track model.methodId) {\n <p>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\" />\n </p>\n }\n </div>\n } @else {\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\" />\n }\n } @else {\n -\n }\n </td>\n }\n } @else {\n -\n }\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <div class=\"is-flex is-align-self-stretch is-justify-content-center is-align-items-center is-gap-8\">\n <div class=\"is-flex is-gap-4 is-flex-grow-1 is-align-items-center\">\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }}\"\n [class.trigger-popover]=\"hasLogs()\"\n [ngbPopover]=\"logStatusDetails\"\n [disablePopover]=\"!hasLogs()\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <he-svg-icon [name]=\"logIcon[model.status]\" />\n </span>\n\n <span class=\"is-flex is-flex-grow-1 is-gap-4\">\n <span class=\"is-nowrap is-capitalized\">{{ methodName(model) }}</span>\n\n @if (model.logs?.methodTier || model.model?.methodTier) {\n <span class=\"is-nowrap\">[{{ model.logs?.methodTier || model.model?.methodTier }}]</span>\n }\n </span>\n </div>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n @if (model.showLogs) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"logDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n }\n\n @if (model.model) {\n @if (model.showLogs) {\n <div class=\"vertical-divider\"></div>\n }\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\" />\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <he-node-logs-models-logs [logs]=\"logs\" />\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <he-node-logs-models-logs-status [nodeType]=\"nodeType()\" [model]=\"model\" [data]=\"\" />\n</ng-template>\n\n<ng-template #docsLink let-model>\n @if (guideEnabled && model.guidePath) {\n <he-guide-overlay [pageId]=\"model.guidePath\" [width]=\"500\" />\n } @else {\n <a [href]=\"model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .status-legend{border:1px solid #dbe3ea;background:#f5f7f9}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row td:first-child{padding-left:12px}::ng-deep .table .is-sub-row .sub-sub-row-icon{display:none}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon{display:inline-block}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon+div{padding-left:0!important}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}\n"] }]
|
|
8159
|
+
], template: "<div class=\"is-flex is-gap-8 is-justify-content-space-between is-align-items-center is-my-2\">\n <div>\n <ng-content />\n </div>\n\n @if (!isExternal && !loading() && logsUrl() && hasLogs()) {\n <a class=\"is-size-7\" [href]=\"logsUrl()\" target=\"_blank\">\n <span>Open Full Logs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</div>\n\n@if (!isExternal && !loading() && !hasLogs()) {\n <p class=\"is-my-2\">\n <he-svg-icon class=\"has-text-warning\" name=\"exclamation-triangle\" />\n <span class=\"is-size-7 has-text-warning is-pl-1\">No logs found. Recalculation logs will be incomplete.</span>\n </p>\n}\n\n<he-data-table class=\"is-mt-2 is-mb-1 is-bordered\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n @if (enableFilterByTerm()) {\n <div class=\"field is-pb-1\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [ngModel]=\"term()\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [resultFormatter]=\"termFormatter\"\n [inputFormatter]=\"termFormatter\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"term.set($event.item)\"\n container=\"body\"\n popupClass=\"is-small\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term()\" (click)=\"term.set(undefined)\">\n <he-svg-icon name=\"xmark\" />\n </a>\n </div>\n </div>\n }\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>\n <span class=\"is-pr-1\">Units</span>\n @if (functionalUnit()) {\n <span>(per </span>\n <span>{{ functionalUnit() }}</span>\n <span>)</span>\n }\n </span>\n </div>\n </th>\n }\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Original</span>\n </div>\n </th>\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Recalculated</span>\n </div>\n </th>\n @if (isBlankNodes()) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Difference</span>\n </div>\n </th>\n }\n @for (c of methodModelsCount() | times; track i; let i = $index) {\n <th class=\"has-border-right\">\n <div class=\"is-flex is-flex-direction-column is-justify-content-center h-100\">\n <span>Model {{ i + 1 }}</span>\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading()) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <div class=\"has-text-center py-3\">\n <he-svg-icon name=\"loading\" animation=\"spin\" size=\"40\" />\n </div>\n </td>\n </tr>\n } @else if (blankNodes().length === 0) {\n <tr>\n <td class=\"has-border-right has-text-centered\" colspan=\"100\">\n <p class=\"is-p-1\">\n @if (noDataMessage()) {\n <span>{{ noDataMessage() }}</span>\n } @else {\n <ng-container *ngTemplateOutlet=\"noResultsDefaultMessage\" />\n }\n </p>\n </td>\n </tr>\n }\n @for (blankNode of blankNodes(); track trackByBlankNode($index, blankNode)) {\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td\n class=\"width-auto has-border-right is-nowrap\"\n [attr.title]=\"$any(blankNode).term?.name || $any(blankNode).key\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: blankNode }\" />\n @if ($any(blankNode).term) {\n <he-node-link class=\"is-inline-block is-pre-wrap is-pr-2\" [node]=\"$any(blankNode).term\">\n <span\n class=\"break-word\"\n [innerHtml]=\"$any(blankNode).term.name | compound: $any(blankNode).term.termType\"></span>\n </he-node-link>\n } @else if ($any(blankNode).key) {\n @if (nodeKey() === 'completeness') {\n <a [href]=\"schemaBaseUrl + '/Completeness#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n } @else {\n <a [href]=\"schemaBaseUrl + '/' + nodeType() + '#' + $any(blankNode).key\" target=\"_blank\">\n <span>{{ $any(blankNode).key | keyToLabel }}</span>\n </a>\n }\n }\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if ($any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n <ng-template #originalValueContent>\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </ng-template>\n\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).originalValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span\n [class.trigger-popover]=\"!!$any(blankNode).original?.[0]?.methodModel\"\n [ngbPopover]=\"blankNodeOriginalValueDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n placement=\"bottom left right auto\"\n container=\"body\"\n [disablePopover]=\"!$any(blankNode).original?.[0]?.methodModel\"\n [popoverContext]=\"{ blankNode }\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: $any(blankNode).originalValue }\" />\n </span>\n </span>\n }\n </td>\n <td class=\"has-border-right\">\n @if (!blankNode.isOriginal || blankNode.isRecalculated) {\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n valueContent;\n context: { value: $any(blankNode).recalculatedValueByMethodId[model.methodId] }\n \" />\n </div>\n }\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: blankNode.recalculatedValue }\" />\n </span>\n }\n } @else if ($any(blankNode).configModels?.length) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right is-nowrap\">\n @if (blankNode.allParallel) {\n @for (model of $any(blankNode).configModels[0]; track model.methodId) {\n <div>\n @if (\n $any(blankNode).originalValueByMethodId[model.methodId] !== null &&\n $any(blankNode).recalculatedValueByMethodId[model.methodId] !== null\n ) {\n <he-blank-node-value-delta\n [value]=\"$any(blankNode).recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"$any(blankNode).originalValueByMethodId[model.methodId]\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n </div>\n }\n } @else {\n @if ($any(blankNode).original.length && blankNode.isRecalculated) {\n <he-blank-node-value-delta\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"$any(blankNode).originalValue\"\n [useCustomFunctions]=\"false\" />\n } @else {\n -\n }\n }\n </td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\" />\n </tr>\n @for (subValue of $any(blankNode).keys; track trackBySubValue(subValue)) {\n @if (blankNode.isOpen) {\n <tr [class.has-sub-rows]=\"$any(blankNode).subValues?.length\" [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n @if (blankNode.type) {\n <a\n class=\"is-inline-block is-pre-wrap\"\n [href]=\"schemaBaseUrl + '/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n }\n @if (!blankNode.type) {\n <span class=\"is-inline-block is-align-top\">{{ subValue.key }}</span>\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\"></td>\n }\n <td class=\"has-border-right\">\n @if (subValue.originalValue !== null) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated || subValue.key === 'impactAssessment') {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n } @else {\n not recalculated\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n }\n @for (subValue of $any(blankNode).subValues; track trackBySubValue(subValue)) {\n <ng-container *ngTemplateOutlet=\"subValueRow; context: { blankNode, parent: blankNode, subValue }\" />\n }\n }\n </tbody>\n </table>\n</he-data-table>\n<div class=\"is-size-7\">\n <div class=\"is-flex is-py-2 is-px-3 is-gap-16 | status-legend\">\n <div\n class=\"is-flex is-justify-content-center is-align-items-center is-align-content-center is-flex-wrap-wrap is-gap-8\">\n @for (status of LogStatus | keyvalue; track status.value) {\n @if (logIcon[status.value]) {\n <span class=\"is-flex is-align-items-center is-gap-8\">\n <he-svg-icon [name]=\"logIcon[status.value]\" size=\"20\" class=\"has-text-{{ logColor[status.value] }}\" />\n <span class=\"is-size-7 is-capitalized\">{{ status.value }}</span>\n </span>\n }\n }\n </div>\n\n @if (filteredType()) {\n <div class=\"field is-relative\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded is-secondary\"\n [(ngModel)]=\"onlyRequired\"\n [disabled]=\"!!term()\"\n id=\"onlyRequired\" />\n <label class=\"is-size-7\" for=\"onlyRequired\">\n <span>Show only {{ filteredType() }} terms included in the default HESTIA system boundary</span>\n </label>\n </div>\n }\n </div>\n</div>\n\n<ng-template #noResultsDefaultMessage>\n <span>No original data was provided and no gap filling occurred</span>\n @if (term() && !isInSystemBoundary(term()['@id'])) {\n <span class=\"is-pl-1\">as</span>\n <i class=\"is-px-1\">{{ term().name }}</i>\n <span>is not in the HESTIA system boundary</span>\n }\n <span>.</span>\n</ng-template>\n\n<ng-template #valueContent let-value=\"value\">\n @if (isNumber(value)) {\n {{ value | precision: 3 | default: '-' }}\n } @else {\n {{ value | default: '-' }}\n }\n</ng-template>\n\n<ng-template #collapseButton let-blankNode>\n @if (blankNode.canOpen) {\n <a class=\"open-node\" (click)=\"toggleBlankNode(blankNode)\">\n <he-svg-icon [name]=\"blankNode.isOpen ? 'chevron-down' : 'chevron-right'\" />\n </a>\n }\n</ng-template>\n\n<ng-template #subValueRow let-blankNode=\"blankNode\" let-parent=\"parent\" let-subValue=\"subValue\" let-rowClass=\"rowClass\">\n @let term = subValue.term || termById(subValue.id);\n @if (parent.isOpen) {\n <tr [class.is-sub-row]=\"parent.canOpen\" [ngClass]=\"rowClass\">\n <td class=\"width-auto has-border-right\">\n <div class=\"is-flex is-align-items-flex-start is-gap-4 h-100\">\n <ng-container *ngTemplateOutlet=\"collapseButton; context: { $implicit: subValue }\" />\n <he-svg-icon class=\"sub-sub-row-icon\" name=\"chevron-double-right\" />\n <div class=\"is-flex is-align-items-flex-start is-flex-wrap-wrap is-gap-4\" [class.is-pl-3]=\"!subValue.canOpen\">\n <span>\n <span>{{ subValue.key | keyToLabel }}</span>\n @if (subValue.id) {\n <span class=\"is-inline-block\">:</span>\n }\n </span>\n @if (subValue.id) {\n @switch (subValue.key) {\n @case ('backgroundData') {\n <span class=\"is-inline-block\">{{ term?.name }}</span>\n }\n @case ('animal') {\n <span class=\"is-inline-block\">{{ subValue.id }}</span>\n }\n @default {\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-inline-block\"\n [node]=\"term\"\n [attr.title]=\"term?.name\">\n <span class=\"break-word\" [innerHtml]=\"term?.name | compound\"></span>\n </he-node-link>\n }\n }\n }\n </div>\n </div>\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">\n @if (subValue.showUnits && $any(blankNode).term) {\n <span\n class=\"is-nowrap\"\n [innerHtml]=\"$any(blankNode).term.units | compound: $any(blankNode).term.termType\"></span>\n }\n </td>\n }\n <td class=\"has-border-right\">\n @if (!isEmpty(subValue.originalValue)) {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.originalValue }\" />\n </span>\n } @else {\n -\n }\n </td>\n <td class=\"has-border-right\">\n @if (subValue.isRecalculated) {\n @if (subValue.multiGroups) {\n <span\n class=\"trigger-popover\"\n ngbPopover=\"The total value across all inputs\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow is-overflow-visible\"\n placement=\"left bottom auto\"\n container=\"body\">\n <span pointer>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n </span>\n } @else {\n <span>\n <ng-container *ngTemplateOutlet=\"valueContent; context: { value: subValue.recalculatedValue }\" />\n </span>\n }\n } @else if (!isEmpty(subValue.originalValue)) {\n not recalculated\n } @else {\n -\n }\n </td>\n @if (isBlankNodes()) {\n <td class=\"has-border-right\">-</td>\n }\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\" />\n </tr>\n }\n @if (subValue.subValues) {\n @for (sub of subValue.subValues; track trackBySubValue(sub)) {\n <ng-container\n *ngTemplateOutlet=\"\n subValueRow;\n context: { blankNode, parent: subValue, subValue: sub, rowClass: 'is-sub-sub-row' }\n \" />\n }\n }\n</ng-template>\n\n<ng-template #blankNodeOriginalValueDetails let-blankNode=\"blankNode\">\n <span class=\"is-pr-1\">The original value was reported using:</span>\n <he-node-link\n class=\"is-inline-block\"\n linkClass=\"is-dark\"\n [node]=\"$any(blankNode).original[0].methodModel\"\n [showExternalLink]=\"true\">\n <span>{{ $any(blankNode).original[0].methodModel.name }}</span>\n </he-node-link>\n</ng-template>\n\n<ng-template #blankNodeModels let-data=\"data\">\n @let extraColumns = methodModelsCount() - 1;\n\n <ng-template #notInSystemBoundary>\n <td class=\"has-border-right\">\n <span>Not in HESTIA system boundary</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n </ng-template>\n\n @if (data.canOpen && !data.isOpen && !data.configModels?.length) {\n <td class=\"has-border-right\">\n <span>Expand to see logs (</span>\n @let key = subValuesKey(data, 'sub-values');\n @if (hasCompleteSuccess(data)) {\n <span>all succeeded</span>\n <he-svg-icon class=\"is-ml-1\" name=\"checkmark\" class=\"has-text-success\" />\n } @else {\n <span>some failed</span>\n <he-svg-icon class=\"is-ml-1\" name=\"xmark\" class=\"has-text-danger\" />\n }\n <span>)</span>\n </td>\n @for (v of data | repeat: extraColumns; track repeatIndex; let repeatIndex = $index) {\n <td class=\"has-border-right\"></td>\n }\n } @else {\n @for (configModel of methodModelsCount() | times; track configModelIndex; let configModelIndex = $index) {\n <td class=\"has-border-right blank-node-index-{{ configModelIndex }}\">\n @if (getModelsAt(data, configModelIndex); as models) {\n @if ($any(models) | isArray) {\n <div>\n @for (model of $any(models); track model.methodId) {\n <p>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\" />\n </p>\n }\n </div>\n } @else {\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\" />\n }\n } @else {\n -\n }\n </td>\n }\n }\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <div class=\"is-flex is-align-self-stretch is-justify-content-center is-align-items-center is-gap-8\">\n <div class=\"is-flex is-gap-4 is-flex-grow-1 is-align-items-center\">\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }}\"\n [class.trigger-popover]=\"hasLogs()\"\n [ngbPopover]=\"logStatusDetails\"\n [disablePopover]=\"!hasLogs()\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <he-svg-icon [name]=\"logIcon[model.status]\" />\n </span>\n\n <span class=\"is-flex is-flex-grow-1 is-gap-4\">\n <span class=\"is-nowrap is-capitalized\">{{ methodName(model) }}</span>\n\n @if (model.logs?.methodTier || model.model?.methodTier) {\n <span class=\"is-nowrap\">[{{ model.logs?.methodTier || model.model?.methodTier }}]</span>\n }\n </span>\n </div>\n\n <div class=\"is-flex is-gap-4 is-flex-shrink-0 is-align-items-center\">\n @if (model.showLogs) {\n <span\n class=\"is-nowrap is-clickable\"\n [ngbPopover]=\"logDetails\"\n autoClose=\"outside\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"bottom left right auto\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"has-text-link\">Logs</span>\n </span>\n }\n\n @if (model.model) {\n @if (model.showLogs) {\n <div class=\"vertical-divider\"></div>\n }\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\" />\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <he-node-logs-models-logs [logs]=\"logs\" />\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <he-node-logs-models-logs-status [nodeType]=\"nodeType()\" [model]=\"model\" [data]=\"\" />\n</ng-template>\n\n<ng-template #docsLink let-model>\n @if (guideEnabled && model.guidePath) {\n <he-guide-overlay [pageId]=\"model.guidePath\" [width]=\"500\" />\n } @else {\n <a [href]=\"model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <he-svg-icon name=\"external-link\" class=\"ml-2\" />\n </a>\n }\n</ng-template>\n", styles: [":host{display:block}:host .vertical-divider{width:1px;height:20px;background:#dbe3ea}:host .status-legend{border:1px solid #dbe3ea;background:#f5f7f9}::ng-deep .table{background-color:transparent}::ng-deep .table td.has-border-right{box-shadow:1px 0 #4c7194}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#4c719433;height:100%;width:1px;top:0;left:14px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .is-sub-row td:first-child{padding-left:12px}::ng-deep .table .is-sub-row .sub-sub-row-icon{display:none}::ng-deep .table .is-sub-row .open-node>he-svg-icon,::ng-deep .table .is-sub-row .sub-sub-row-icon{height:16px!important;width:16px!important}::ng-deep .table .is-sub-sub-row td:first-child{padding-left:24px}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon{display:inline-block}::ng-deep .table .is-sub-sub-row .sub-sub-row-icon+div{padding-left:0!important}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}\n"] }]
|
|
8209
8160
|
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], nodeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKey", required: false }] }], originalValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "originalValues", required: false }] }], recalculatedValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "recalculatedValues", required: false }] }], terms: [{ type: i0.Input, args: [{ isSignal: true, alias: "terms", required: false }] }], filterTermTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterTermTypes", required: false }] }], filterTermTypesLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterTermTypesLabel", required: false }] }], logsKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "logsKey", required: false }] }], noDataMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataMessage", required: false }] }] } });
|
|
8210
8161
|
|
|
8211
8162
|
var View$4;
|
|
@@ -12323,7 +12274,6 @@ const getUnitsAndLabel = (terms, fallbackLabel = 'unknown term') => {
|
|
|
12323
12274
|
units
|
|
12324
12275
|
};
|
|
12325
12276
|
};
|
|
12326
|
-
|
|
12327
12277
|
const typeMapping = {
|
|
12328
12278
|
[TermTermType.endpointIndicator]: ChartNodeType.endpoint,
|
|
12329
12279
|
[TermTermType.characterisedIndicator]: ChartNodeType.midpoint,
|
|
@@ -12331,6 +12281,58 @@ const typeMapping = {
|
|
|
12331
12281
|
[TermTermType.resourceUse]: ChartNodeType.emission,
|
|
12332
12282
|
[TermTermType.operation]: ChartNodeType.operation
|
|
12333
12283
|
};
|
|
12284
|
+
const safeDivide = (numerator, denominator) => (denominator !== 0 ? numerator / denominator : 0);
|
|
12285
|
+
const sumIndicators = (data) => {
|
|
12286
|
+
const totalValues = data.reduce((acc, log) => {
|
|
12287
|
+
acc[log.indicator] = acc[log.indicator] || [];
|
|
12288
|
+
!isUndefined(log.weightedValue) && acc[log.indicator].push(log.weightedValue);
|
|
12289
|
+
return acc;
|
|
12290
|
+
}, {});
|
|
12291
|
+
return Object.fromEntries(Object.entries(totalValues).map(([key, values]) => [
|
|
12292
|
+
key,
|
|
12293
|
+
// if the total is positive, we ignore negative values
|
|
12294
|
+
sum(values) < 0 ? sum(values) : sum(values.filter(v => v >= 0))
|
|
12295
|
+
]));
|
|
12296
|
+
};
|
|
12297
|
+
const groupIndicators = (data, terms = {}, totals = {}) => data.reduce((acc, log) => {
|
|
12298
|
+
const contributorType = typeMapping[terms[log.contributor]?.termType] || ChartNodeType.input;
|
|
12299
|
+
const indicatorType = typeMapping[terms[log.indicator]?.termType];
|
|
12300
|
+
const contributorNode = {
|
|
12301
|
+
id: log.contributor,
|
|
12302
|
+
...getUnitsAndLabel(terms[log.contributor], log.contributor),
|
|
12303
|
+
type: contributorType,
|
|
12304
|
+
value: log.value,
|
|
12305
|
+
weightedValue: log.weightedValue,
|
|
12306
|
+
modelId: log.modelId,
|
|
12307
|
+
fraction: safeDivide(log.weightedValue, totals[log.indicator]),
|
|
12308
|
+
children: contributorType === ChartNodeType.emission
|
|
12309
|
+
? log.inputs.map(i => ({
|
|
12310
|
+
...i,
|
|
12311
|
+
...getUnitsAndLabel(terms[i.id], i.label),
|
|
12312
|
+
type: ChartNodeType.input,
|
|
12313
|
+
fraction: safeDivide(i.weightedValue, log.value),
|
|
12314
|
+
children: i.operations.map(o => ({
|
|
12315
|
+
...o,
|
|
12316
|
+
...getUnitsAndLabel(terms[o.id], o.label),
|
|
12317
|
+
type: ChartNodeType.operation,
|
|
12318
|
+
fraction: safeDivide(o.weightedValue, i.weightedValue)
|
|
12319
|
+
}))
|
|
12320
|
+
}))
|
|
12321
|
+
: []
|
|
12322
|
+
};
|
|
12323
|
+
acc[log.indicator]
|
|
12324
|
+
? acc[log.indicator].children.push(contributorNode)
|
|
12325
|
+
: (acc[log.indicator] = {
|
|
12326
|
+
id: log.indicator,
|
|
12327
|
+
...getUnitsAndLabel(terms[log.indicator], log.indicator),
|
|
12328
|
+
modelId: log.modelId,
|
|
12329
|
+
type: indicatorType,
|
|
12330
|
+
value: totals[log.indicator],
|
|
12331
|
+
children: [contributorNode]
|
|
12332
|
+
});
|
|
12333
|
+
return acc;
|
|
12334
|
+
}, {});
|
|
12335
|
+
|
|
12334
12336
|
const width = 800;
|
|
12335
12337
|
const margin = { top: 10, right: 20, bottom: 10, left: 20 };
|
|
12336
12338
|
const fontSize = Math.floor(width / 100);
|
|
@@ -12418,7 +12420,6 @@ const setGroupButtonXY = (selection) => selection
|
|
|
12418
12420
|
.attr('x', d => (d._groupOpen ? (nodeWidth * 2.5) / 7 : nodeWidth / 2 - groupButtonWidth / 2))
|
|
12419
12421
|
.attr('y', d => d._groupOpen ? groupOverlap + (groupNodeSpace - (lineHeight + nodePadding * 2)) / 2 : nodePadding + lineHeight + 6);
|
|
12420
12422
|
const formatNumber = (value) => (isNumber(value) ? toPrecision(value, 3) : 'N/A');
|
|
12421
|
-
const safeDivide = (numerator, denominator) => (denominator > 0 ? numerator / denominator : 0);
|
|
12422
12423
|
const isTypeWithoutValue = (nodeDatum) => [ChartNodeType.input, ChartNodeType.operation].includes(nodeDatum.data.type);
|
|
12423
12424
|
const getWeightedValueText = (nodeDatum) => `${formatNumber(nodeDatum.data.weightedValue)}${nodeDatum.parent?.data.value === null
|
|
12424
12425
|
? ''
|
|
@@ -12443,12 +12444,12 @@ const generateTipData = (nodeDatum) => ({
|
|
|
12443
12444
|
href: `${baseUrl()}/term/${term['@id']}`
|
|
12444
12445
|
}))
|
|
12445
12446
|
});
|
|
12446
|
-
const addTooltip = (selection, { tooltipOperator
|
|
12447
|
+
const addTooltip = (selection, { tooltipOperator }) => {
|
|
12447
12448
|
let hoveringTip = false;
|
|
12448
12449
|
let hoveringNode = false;
|
|
12449
12450
|
let lastNodeId;
|
|
12450
12451
|
const closeTip = () => {
|
|
12451
|
-
|
|
12452
|
+
tooltipOperator.close(false);
|
|
12452
12453
|
selectAll('.tip-target').classed('tip-target', false);
|
|
12453
12454
|
lastNodeId = null;
|
|
12454
12455
|
};
|
|
@@ -12469,7 +12470,7 @@ const addTooltip = (selection, { tooltipOperator, zone }) => {
|
|
|
12469
12470
|
closeTip();
|
|
12470
12471
|
lastNodeId = nodeDatum.data.id;
|
|
12471
12472
|
select(event.target).classed('tip-target', true);
|
|
12472
|
-
|
|
12473
|
+
tooltipOperator.open({ tipData: generateTipData(nodeDatum) });
|
|
12473
12474
|
select('.driver-chart-tooltip')
|
|
12474
12475
|
.on('pointerenter', () => {
|
|
12475
12476
|
hoveringTip = true;
|
|
@@ -12485,7 +12486,7 @@ const addTooltip = (selection, { tooltipOperator, zone }) => {
|
|
|
12485
12486
|
});
|
|
12486
12487
|
return selection;
|
|
12487
12488
|
};
|
|
12488
|
-
const mergedNodes = (selection, { tooltipOperator
|
|
12489
|
+
const mergedNodes = (selection, { tooltipOperator }) => {
|
|
12489
12490
|
selection
|
|
12490
12491
|
.selectAll('.node-box')
|
|
12491
12492
|
.classed('node-openable', d => !!d.height)
|
|
@@ -12497,7 +12498,7 @@ const mergedNodes = (selection, { tooltipOperator, zone }) => {
|
|
|
12497
12498
|
.attr('rx', '3px')
|
|
12498
12499
|
.attr('ry', '3px')
|
|
12499
12500
|
.style('user-select', window.innerWidth < 768 ? 'none' : null);
|
|
12500
|
-
selection.filter(d => !d.data.group && d.data.id !== nonLCAIndicatorsId).call(addTooltip, { tooltipOperator
|
|
12501
|
+
selection.filter(d => !d.data.group && d.data.id !== nonLCAIndicatorsId).call(addTooltip, { tooltipOperator });
|
|
12501
12502
|
selection
|
|
12502
12503
|
.selectAll('.node-label')
|
|
12503
12504
|
.attr('y', d => (d.data.showBar ? lineHeight / 2 + nodePadding / 2 : 0))
|
|
@@ -12684,49 +12685,6 @@ const groupPercentage = (node, percentage = 0.02) => {
|
|
|
12684
12685
|
node._children = notGrouped;
|
|
12685
12686
|
}
|
|
12686
12687
|
};
|
|
12687
|
-
const sumIndicators = (data) => data.reduce((acc, log) => {
|
|
12688
|
-
// ignore negative values in the total
|
|
12689
|
-
acc[log.indicator] = (acc[log.indicator] || 0) + (log.weightedValue > 0 ? log.weightedValue : 0);
|
|
12690
|
-
return acc;
|
|
12691
|
-
}, {});
|
|
12692
|
-
const groupIndicators = (data, terms = {}, totals = {}) => data.reduce((acc, log) => {
|
|
12693
|
-
const contributorType = typeMapping[terms[log.contributor]?.termType] || ChartNodeType.input;
|
|
12694
|
-
const indicatorType = typeMapping[terms[log.indicator]?.termType];
|
|
12695
|
-
const contributorNode = {
|
|
12696
|
-
id: log.contributor,
|
|
12697
|
-
...getUnitsAndLabel(terms[log.contributor], log.contributor),
|
|
12698
|
-
type: contributorType,
|
|
12699
|
-
value: log.value,
|
|
12700
|
-
weightedValue: log.weightedValue,
|
|
12701
|
-
modelId: log.modelId,
|
|
12702
|
-
fraction: safeDivide(log.weightedValue, totals[log.indicator]),
|
|
12703
|
-
children: contributorType === ChartNodeType.emission
|
|
12704
|
-
? log.inputs.map(i => ({
|
|
12705
|
-
...i,
|
|
12706
|
-
...getUnitsAndLabel(terms[i.id], i.label),
|
|
12707
|
-
type: ChartNodeType.input,
|
|
12708
|
-
fraction: safeDivide(i.weightedValue, log.value),
|
|
12709
|
-
children: i.operations.map(o => ({
|
|
12710
|
-
...o,
|
|
12711
|
-
...getUnitsAndLabel(terms[o.id], o.label),
|
|
12712
|
-
type: ChartNodeType.operation,
|
|
12713
|
-
fraction: safeDivide(o.weightedValue, i.weightedValue)
|
|
12714
|
-
}))
|
|
12715
|
-
}))
|
|
12716
|
-
: []
|
|
12717
|
-
};
|
|
12718
|
-
acc[log.indicator]
|
|
12719
|
-
? acc[log.indicator].children.push(contributorNode)
|
|
12720
|
-
: (acc[log.indicator] = {
|
|
12721
|
-
id: log.indicator,
|
|
12722
|
-
...getUnitsAndLabel(terms[log.indicator], log.indicator),
|
|
12723
|
-
modelId: log.modelId,
|
|
12724
|
-
type: indicatorType,
|
|
12725
|
-
value: totals[log.indicator],
|
|
12726
|
-
children: [contributorNode]
|
|
12727
|
-
});
|
|
12728
|
-
return acc;
|
|
12729
|
-
}, {});
|
|
12730
12688
|
const showBar = (node) => [
|
|
12731
12689
|
node.parent?.data.type !== ChartNodeType.root,
|
|
12732
12690
|
node.parent?.data.id !== nonLCAIndicatorsId,
|
|
@@ -12735,7 +12693,6 @@ const showBar = (node) => [
|
|
|
12735
12693
|
].every(Boolean);
|
|
12736
12694
|
class HierarchyChartComponent {
|
|
12737
12695
|
constructor() {
|
|
12738
|
-
this.ngZone = inject(NgZone);
|
|
12739
12696
|
this.chart = viewChild.required('chart');
|
|
12740
12697
|
this.zoomContainer = viewChild.required('zoomContainer');
|
|
12741
12698
|
this.chartContainer = viewChild.required('chartContainer');
|
|
@@ -12819,7 +12776,8 @@ class HierarchyChartComponent {
|
|
|
12819
12776
|
});
|
|
12820
12777
|
this.includedTypes.set(unique(root.descendants().map(n => n.data.type)));
|
|
12821
12778
|
this.root = root
|
|
12822
|
-
|
|
12779
|
+
// treat `0` as -infinity so they appear all the way to the bottom
|
|
12780
|
+
.sort((a, b) => (b.data.fraction || -Infinity) - (a.data.fraction || -Infinity))
|
|
12823
12781
|
.eachAfter(node => {
|
|
12824
12782
|
if (node.data.fraction === 0) {
|
|
12825
12783
|
node.children = null;
|
|
@@ -12912,8 +12870,8 @@ class HierarchyChartComponent {
|
|
|
12912
12870
|
.call(enterNodes)
|
|
12913
12871
|
.attr('opacity', 0)
|
|
12914
12872
|
.attr('transform', d => 'translate(' + (togglingGroup ? d.y : d.y - nodeWidth / 2) + ',' + d.x + ')'), update => update, exit => {
|
|
12915
|
-
this.
|
|
12916
|
-
return exit
|
|
12873
|
+
this.tooltipOperator().close(false);
|
|
12874
|
+
return (exit
|
|
12917
12875
|
.style('pointer-events', 'none')
|
|
12918
12876
|
.transition()
|
|
12919
12877
|
.duration(nodeDuration / 2)
|
|
@@ -12925,13 +12883,11 @@ class HierarchyChartComponent {
|
|
|
12925
12883
|
.attr('transform', d => 'translate(' + (togglingGroup ? d.y : d.y - nodeWidth / 2) + ',' + d.x + ')')
|
|
12926
12884
|
.attr('opacity', 0)
|
|
12927
12885
|
.remove()
|
|
12928
|
-
.on('end', () => {
|
|
12929
12886
|
// in case a tooltip was opened on a transitioning element
|
|
12930
|
-
|
|
12931
|
-
});
|
|
12887
|
+
.on('end', () => this.tooltipOperator().close(false)));
|
|
12932
12888
|
});
|
|
12933
12889
|
this.node
|
|
12934
|
-
.call(mergedNodes, { tooltipOperator: this.tooltipOperator()
|
|
12890
|
+
.call(mergedNodes, { tooltipOperator: this.tooltipOperator() })
|
|
12935
12891
|
.transition()
|
|
12936
12892
|
.delay(d => {
|
|
12937
12893
|
const groupClosing = togglingGroup && !d.parent?.children?.find(n => n.data.group)?._groupOpen;
|
|
@@ -13222,7 +13178,7 @@ const csvHeaders = [
|
|
|
13222
13178
|
'Functional Unit'
|
|
13223
13179
|
];
|
|
13224
13180
|
const logsTotalValue = (logs, includeNegativeValues) => sum((includeNegativeValues ? logs : logs.filter(curr => curr.value >= 0)).map(v => v.value));
|
|
13225
|
-
const valueRatio = (value, total) => toPrecision((value * 100) / total, 2);
|
|
13181
|
+
const valueRatio = (value, total) => total === 0 ? 0 : toPrecision((value * 100) / total, 2);
|
|
13226
13182
|
const chartLabel = (value, total) => {
|
|
13227
13183
|
const ratio = valueRatio(value, total);
|
|
13228
13184
|
return value === 0 ? '0' : `${value}, ${ratio}%`;
|
|
@@ -14173,5 +14129,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
14173
14129
|
* Generated bundle index. Do not edit.
|
|
14174
14130
|
*/
|
|
14175
14131
|
|
|
14176
|
-
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ClickOutsideDirective, ClipboardComponent, CollapsibleBoxComponent, ColorPalette, CompoundDirective, CompoundPipe, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HESvgIconComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MendeleySearchResult, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, arrayValue, availableProperties, backgroundHoverPlugin, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultSvgIconSize, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorHasError, errorHasWarning, errorText, evaluateSuccess, exportAsSVG, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterError, filterParams, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter, getColor, getDatesBetween, gitBranch, gitHome, gitlabRawUrl, glossaryBaseUrl, glossaryLink, groupChanged, groupLogsByModel, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, guidePageId, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, iconSizes, icons, ignoreKeys$2 as ignoreKeys, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isGroupVisible, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isMigrationError, isMissingOneOfError, isMissingPropertyError, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, loadSvgSprite,
|
|
14132
|
+
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ClickOutsideDirective, ClipboardComponent, CollapsibleBoxComponent, ColorPalette, CompoundDirective, CompoundPipe, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HESvgIconComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MendeleySearchResult, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, arrayValue, availableProperties, backgroundHoverPlugin, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultSvgIconSize, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorHasError, errorHasWarning, errorText, evaluateSuccess, exportAsSVG, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterError, filterParams, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter, getColor, getDatesBetween, gitBranch, gitHome, gitlabRawUrl, glossaryBaseUrl, glossaryLink, groupChanged, groupLogsByModel, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, guidePageId, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, iconSizes, icons, ignoreKeys$2 as ignoreKeys, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isGroupVisible, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isMigrationError, isMissingOneOfError, isMissingPropertyError, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, loadSvgSprite, locationQuery, logToCsv$1 as logToCsv, logValueArray, logsKey, lollipopChartPlugin, lookupUrl, mapFilterData, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchAggregatedValidatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchId, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchPrimaryProductQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, mergeDataWithHeaders, methodTierOrder, migrationErrorMessage, migrationsUrl, missingNodeErrors, modelCount, modelKeyParams, modelParams, models, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, nodeAvailableProperties, nodeById, nodeColours$1 as nodeColours, nodeDataState, nodeId, nodeIds, nodeLink, nodeLinkEnabled, nodeLinkTypeEnabled, nodeLogsUrl, nodeQualityScoreColor, nodeQualityScoreLevel, nodeQualityScoreMaxDefault, nodeQualityScoreOrder, nodeSecondaryColours, nodeToAggregationFilename, nodeType, nodeTypeDataState, nodeTypeIcon, nodeUrl, nodeUrlParams, nodeVersion, nodesByState, nodesByType, numberGte, optionsFromGroup, parentKey, parentProperty, parseColor, parseData, parseDataPath, parseLines, parseMessage$1 as parseMessage, parseNewValue, pluralize, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonToMap, polygonsFromFeature, populateWithTrackIdsFilterData, postGuideEvent, primaryProduct, productsQuery, propertyError, propertyId, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, registerChart, repeat, reportIssueLink, reportIssueUrl, safeJSONParse, safeJSONStringify, schemaBaseUrl, schemaDataBaseUrl, schemaLink, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchFilterData, searchableTypes, siblingProperty, singleProperty, siteTooBig, siteTypeToIcon, sortProperties, sortedDates, strokeColor, strokeStyle, suggestMatchQuery, suggestQuery, takeAfterViewInit, termLocation, termLocationName, termProperties, termTypeLabel, toSnakeCase, toThousands, typeToNewProperty, typeaheadFocus, uncapitalize, uniqueDatesBetween, updateProperties, valueTypeToDefault, waitFor, wildcardQuery };
|
|
14177
14133
|
//# sourceMappingURL=hestia-earth-ui-components.mjs.map
|