@hestia-earth/ui-components 0.0.4 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auth/{public-api.d.ts → index.d.ts} +0 -0
- package/bibliographies/{public-api.d.ts → index.d.ts} +0 -0
- package/bundles/hestia-earth-ui-components.umd.js +1607 -1673
- package/bundles/hestia-earth-ui-components.umd.js.map +1 -1
- package/common/blank-node-state/blank-node-state.component.d.ts +1 -1
- package/common/blank-node-value-delta/blank-node-value-delta.component.d.ts +2 -2
- package/common/common.service.d.ts +1 -2
- package/common/delta-utils.d.ts +20 -0
- package/common/{public-api.d.ts → index.d.ts} +2 -0
- package/common/toast/toast.component.d.ts +2 -2
- package/common/toast.service.d.ts +3 -3
- package/common/utils.d.ts +8 -26
- package/cycles/{public-api.d.ts → index.d.ts} +1 -0
- package/engine/aggregation-engine.service.d.ts +13 -25
- package/engine/engine.service.d.ts +2 -6
- package/engine/index.d.ts +2 -0
- package/esm2015/auth/index.js +2 -0
- package/esm2015/bibliographies/index.js +3 -0
- package/esm2015/common/blank-node-diffs/blank-node-diffs.component.js +3 -4
- package/esm2015/common/blank-node-value-delta/blank-node-value-delta.component.js +4 -4
- package/esm2015/common/common.service.js +1 -7
- package/esm2015/common/delta-utils.js +54 -0
- package/esm2015/common/index.js +33 -0
- package/esm2015/common/toast/toast.component.js +3 -3
- package/esm2015/common/toast.service.js +5 -5
- package/esm2015/common/utils.js +20 -84
- package/esm2015/cycles/index.js +12 -0
- package/esm2015/engine/aggregation-engine.service.js +11 -47
- package/esm2015/engine/engine.service.js +9 -15
- package/esm2015/engine/index.js +3 -0
- package/esm2015/files/index.js +5 -0
- package/esm2015/fontawesome/index.js +2 -0
- package/esm2015/impact-assessments/impact-assessments-products/impact-assessments-products.component.js +3 -3
- package/esm2015/impact-assessments/index.js +7 -0
- package/esm2015/mendeley/index.js +2 -0
- package/esm2015/mendeley/mendeley.service.js +1 -1
- package/esm2015/node/index.js +14 -0
- package/esm2015/node/node-csv.service.js +1 -1
- package/esm2015/node/node-diffs/node-diffs.component.js +5 -5
- package/esm2015/node/node-diffs/node-diffs.model.js +6 -6
- package/esm2015/node/node.service.js +26 -16
- package/esm2015/public-api.js +16 -16
- package/esm2015/schema/index.js +2 -0
- package/esm2015/schema/schema.service.js +1 -1
- package/esm2015/search/index.js +4 -0
- package/esm2015/search/search.service.js +1 -1
- package/esm2015/sites/index.js +6 -0
- package/esm2015/terms/index.js +2 -0
- package/esm2015/users/index.js +2 -0
- package/fesm2015/hestia-earth-ui-components.js +827 -919
- package/fesm2015/hestia-earth-ui-components.js.map +1 -1
- package/files/{public-api.d.ts → index.d.ts} +2 -0
- package/fontawesome/{public-api.d.ts → index.d.ts} +0 -0
- package/impact-assessments/impact-assessments-products/impact-assessments-products.component.d.ts +2 -2
- package/impact-assessments/{public-api.d.ts → index.d.ts} +0 -0
- package/mendeley/{public-api.d.ts → index.d.ts} +0 -0
- package/mendeley/mendeley.service.d.ts +2 -2
- package/node/{public-api.d.ts → index.d.ts} +1 -0
- package/node/node-csv.service.d.ts +1 -1
- package/node/node-diffs/node-diffs.component.d.ts +3 -3
- package/node/node-diffs/node-diffs.model.d.ts +1 -1
- package/node/node.service.d.ts +16 -7
- package/package.json +1 -1
- package/public-api.d.ts +15 -15
- package/schema/{public-api.d.ts → index.d.ts} +0 -0
- package/schema/schema.service.d.ts +1 -1
- package/search/{public-api.d.ts → index.d.ts} +0 -0
- package/search/search.service.d.ts +2 -2
- package/sites/{public-api.d.ts → index.d.ts} +0 -0
- package/terms/{public-api.d.ts → index.d.ts} +0 -0
- package/users/{public-api.d.ts → index.d.ts} +0 -0
- package/common/blank-node-diffs/blank-node-diffs.service.d.ts +0 -5
- package/common/blank-node-value-delta/blank-node-value-delta.service.d.ts +0 -6
- package/engine/public-api.d.ts +0 -2
- package/esm2015/auth/public-api.js +0 -2
- package/esm2015/bibliographies/public-api.js +0 -3
- package/esm2015/common/blank-node-diffs/blank-node-diffs.service.js +0 -20
- package/esm2015/common/blank-node-value-delta/blank-node-value-delta.service.js +0 -31
- package/esm2015/common/public-api.js +0 -31
- package/esm2015/cycles/public-api.js +0 -11
- package/esm2015/engine/public-api.js +0 -3
- package/esm2015/files/public-api.js +0 -3
- package/esm2015/fontawesome/public-api.js +0 -2
- package/esm2015/impact-assessments/public-api.js +0 -7
- package/esm2015/mendeley/public-api.js +0 -2
- package/esm2015/node/public-api.js +0 -13
- package/esm2015/schema/public-api.js +0 -2
- package/esm2015/search/public-api.js +0 -4
- package/esm2015/sites/public-api.js +0 -6
- package/esm2015/terms/public-api.js +0 -2
- package/esm2015/users/public-api.js +0 -2
|
@@ -14,10 +14,10 @@ import * as i1 from '@fortawesome/angular-fontawesome';
|
|
|
14
14
|
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
15
15
|
import { faClone, faCircle, faIdBadge } from '@fortawesome/free-regular-svg-icons';
|
|
16
16
|
import { faAngleDoubleLeft, faAngleDoubleRight, faAngleDown, faAngleLeft, faAngleRight, faBookOpen, faBuilding, faCalculator, faChartBar, faCheck, faClipboard, faClipboardList, faClone as faClone$1, faComments, faDownload, faDrawPolygon, faEdit, faExclamationTriangle, faExternalLinkAlt, faFilter, faList, faLongArrowAltDown, faLongArrowAltUp, faLongArrowAltLeft, faLongArrowAltRight, faMap, faMapMarked, faMapMarkedAlt, faPlus, faPlusCircle, faSearch, faSeedling, faSpellCheck, faSpinner, faTimes, faUser } from '@fortawesome/free-solid-svg-icons';
|
|
17
|
-
import { isEmpty, unique, isUndefined, isNumber, toPrecision, isBoolean, ConvertUnits, converters, convertValue, isEqual, diffInDays } from '@hestia-earth/utils';
|
|
18
17
|
import { getColor } from 'random-material-color';
|
|
19
|
-
import { EmissionMethodTier, NodeType, TermTermType, nestedSearchableKeys,
|
|
18
|
+
import { EmissionMethodTier, NodeType, isExpandable, TermTermType, nestedSearchableKeys, SchemaType, SCHEMA_VERSION, sortKeysByType, CycleFunctionalUnit, SiteSiteType, isTypeValid, isTypeNode, typeToSchemaType } from '@hestia-earth/schema';
|
|
20
19
|
import { fileToExt, nodeTypeToParam, DataState, SupportedExtensions } from '@hestia-earth/api';
|
|
20
|
+
import { unique, isEmpty, isUndefined, isNumber, toPrecision, isBoolean, ConvertUnits, converters, convertValue, isEqual, diffInDays } from '@hestia-earth/utils';
|
|
21
21
|
import { of, ReplaySubject, forkJoin, from, zip } from 'rxjs';
|
|
22
22
|
import { catchError, map, take, mergeMap, debounceTime, distinctUntilChanged, tap, switchMap, reduce, filter, distinct, toArray, mergeAll, groupBy } from 'rxjs/operators';
|
|
23
23
|
import { __rest, __awaiter } from 'tslib';
|
|
@@ -33,10 +33,10 @@ import { headersFromCsv, toCsv as toCsv$2, toJson } from '@hestia-earth/schema-c
|
|
|
33
33
|
import { isCSVIncluded, isDefaultCSVSelected } from '@hestia-earth/json-schema/schema-utils';
|
|
34
34
|
import { create, formatters } from 'jsondiffpatch';
|
|
35
35
|
import { Chart } from 'chart.js';
|
|
36
|
-
import MarkerClusterer from '@google/markerclustererplus';
|
|
37
36
|
import * as moment from 'moment';
|
|
38
37
|
import 'moment/locale/en-gb';
|
|
39
38
|
import { v4 } from 'uuid';
|
|
39
|
+
import MarkerClusterer from '@google/markerclustererplus';
|
|
40
40
|
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
|
41
41
|
|
|
42
42
|
class HeAuthService {
|
|
@@ -85,9 +85,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
85
85
|
}]
|
|
86
86
|
}], ctorParameters: function () { return [{ type: i1.FaIconLibrary }]; } });
|
|
87
87
|
|
|
88
|
-
const get$
|
|
88
|
+
const get$4 = require('lodash.get');
|
|
89
89
|
const gitHome = 'https://gitlab.com/hestia-earth';
|
|
90
90
|
const gitRawBaseUrl = 'https://glcdn.githack.com/hestia-earth';
|
|
91
|
+
const gitBranch = () => ['dev', 'staging'].some(env => baseUrl().includes(env)) ? 'develop' : 'master';
|
|
91
92
|
const isChrome = () => window.navigator.userAgent.includes('Chrome');
|
|
92
93
|
const baseUrl = () => window.location.origin.includes('localhost') ?
|
|
93
94
|
'https://www-dev.hestia.earth' :
|
|
@@ -96,18 +97,8 @@ const baseUrl = () => window.location.origin.includes('localhost') ?
|
|
|
96
97
|
'https://www.hestia.earth';
|
|
97
98
|
const isExternal = () => baseUrl() !== window.location.origin;
|
|
98
99
|
;
|
|
99
|
-
const loadScript = (src) => new Promise((resolve, reject) => {
|
|
100
|
-
if (!src || document.body.querySelectorAll('script[src="' + src + '"]').length > 0) {
|
|
101
|
-
return resolve({});
|
|
102
|
-
}
|
|
103
|
-
const script = document.createElement('script');
|
|
104
|
-
script.onload = resolve;
|
|
105
|
-
script.onerror = reject;
|
|
106
|
-
script.src = src;
|
|
107
|
-
document.body.appendChild(script);
|
|
108
|
-
});
|
|
109
100
|
const parseErrorStatus = (error) => ((error === null || error === void 0 ? void 0 : error.statusText) || '').toLowerCase().replace(/\s/g, '-');
|
|
110
|
-
const parseErrorMessage = (error) => get$
|
|
101
|
+
const parseErrorMessage = (error) => get$4(error, 'error.error', get$4(error, 'error.message', get$4(error, 'error', get$4(error, 'message', error))));
|
|
111
102
|
const handleAPIError = (error) => {
|
|
112
103
|
try {
|
|
113
104
|
error = parseErrorMessage(error);
|
|
@@ -122,20 +113,6 @@ const errorText = (error) => {
|
|
|
122
113
|
const err = parseErrorMessage(error);
|
|
123
114
|
return parseErrorStatus(err) || err;
|
|
124
115
|
};
|
|
125
|
-
const toFormData = (data, formData = new FormData()) => {
|
|
126
|
-
for (const key in data) {
|
|
127
|
-
if (data.hasOwnProperty(key)) {
|
|
128
|
-
const value = data[key];
|
|
129
|
-
if (typeof value === 'object') {
|
|
130
|
-
formData.append(key, JSON.stringify(value));
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
formData.append(key, value);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return formData;
|
|
138
|
-
};
|
|
139
116
|
const filterParams = (obj) => {
|
|
140
117
|
const res = {};
|
|
141
118
|
Object.keys(obj).sort().forEach(key => {
|
|
@@ -146,13 +123,6 @@ const filterParams = (obj) => {
|
|
|
146
123
|
});
|
|
147
124
|
return res;
|
|
148
125
|
};
|
|
149
|
-
const toSearchParams = (params = {}) => {
|
|
150
|
-
const searchParams = new URLSearchParams();
|
|
151
|
-
Object.keys(params)
|
|
152
|
-
.filter(key => typeof params[key] !== 'undefined')
|
|
153
|
-
.forEach(key => searchParams.append(key, `${params[key]}`));
|
|
154
|
-
return searchParams;
|
|
155
|
-
};
|
|
156
126
|
const waitFor = (variable, callback) => {
|
|
157
127
|
if (variable in window) {
|
|
158
128
|
return callback();
|
|
@@ -166,23 +136,6 @@ const scrollToEl = (id, retries = 0) => {
|
|
|
166
136
|
setTimeout(() => el ? el.scrollIntoView() : (retries < 10 ? scrollToEl(id, retries + 1) : null), 100);
|
|
167
137
|
};
|
|
168
138
|
const scrollTop = () => window.scrollTo(0, 0);
|
|
169
|
-
const animateCounter = (total, callback) => {
|
|
170
|
-
let animationDuration = 10;
|
|
171
|
-
const step = Math.pow(10, `${total}`.length - 1);
|
|
172
|
-
const maxSteps = parseInt(`${total / step}`, 10);
|
|
173
|
-
let current = 0;
|
|
174
|
-
const interval = setInterval(() => {
|
|
175
|
-
callback(current);
|
|
176
|
-
current += (step / animationDuration);
|
|
177
|
-
if (current > maxSteps * step) {
|
|
178
|
-
animationDuration = 100;
|
|
179
|
-
}
|
|
180
|
-
if (current > total) {
|
|
181
|
-
callback(total);
|
|
182
|
-
clearInterval(interval);
|
|
183
|
-
}
|
|
184
|
-
}, animationDuration);
|
|
185
|
-
};
|
|
186
139
|
const safeJSONParse = (value, defaultValue) => {
|
|
187
140
|
try {
|
|
188
141
|
return typeof value === 'string' ? JSON.parse(value) : value;
|
|
@@ -241,7 +194,7 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
|
|
|
241
194
|
group[termId].values[nodeId].nodes.push(blankNode);
|
|
242
195
|
group[termId].values[nodeId].value = concatBlankNodeValue(group[termId].values[nodeId].value, blankNode.value);
|
|
243
196
|
grouppedValueKeys.forEach(arrayKey => {
|
|
244
|
-
const newValue = get$
|
|
197
|
+
const newValue = get$4(blankNode, arrayKey, []);
|
|
245
198
|
group[termId].values[nodeId][arrayKey] = [
|
|
246
199
|
...(group[termId].values[nodeId][arrayKey] || []),
|
|
247
200
|
...(Array.isArray(newValue) ? newValue : [newValue])
|
|
@@ -254,7 +207,7 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
|
|
|
254
207
|
Object.keys(group.values).map(nodeId => {
|
|
255
208
|
const { index } = group.values[nodeId];
|
|
256
209
|
const termId = group.term['@id'];
|
|
257
|
-
const originalValue = get$
|
|
210
|
+
const originalValue = get$4(originalValues, `[${index}].${key}`, []).filter((val) => val.term['@id'] === termId);
|
|
258
211
|
if (originalValue.length > 0) {
|
|
259
212
|
const value = originalValue.reduce((array, curr) => concatBlankNodeValue(array, curr.value), []);
|
|
260
213
|
group.originalValues[nodeId] = { value: propertyValue$1(value) };
|
|
@@ -263,7 +216,6 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
|
|
|
263
216
|
});
|
|
264
217
|
return groups;
|
|
265
218
|
};
|
|
266
|
-
const sortByFn = (key, asc) => (a, b) => asc ? get$5(a, key, '').localeCompare(get$5(b, key, '')) : get$5(b, key, '').localeCompare(get$5(a, key, ''));
|
|
267
219
|
const ellipsis = (text = '', maxlength = 20) => text.length > maxlength ? `${text.substring(0, maxlength)}...` : text;
|
|
268
220
|
const mapsQuery = 'https://www.google.com/maps/search/?api=1&query=';
|
|
269
221
|
const mapsUrl = (location) => location ? (location.lat && location.lng ?
|
|
@@ -283,8 +235,6 @@ const toDashCase = (value) => value ?
|
|
|
283
235
|
// handle years
|
|
284
236
|
.replace(/([0-9]{4})/g, g => `-${g}`) :
|
|
285
237
|
null;
|
|
286
|
-
const nodeTypeToString = (type) => `${type.charAt(0).toLowerCase()}${type.substring(1)}`;
|
|
287
|
-
const parseNodeType = (type) => Object.values(NodeType).find(v => v.toString().toLowerCase() === (type || '').toLowerCase());
|
|
288
238
|
const nodeDefaultLabel = {
|
|
289
239
|
[NodeType.ImpactAssessment]: ({ name, country, endDate, product }) => name ? name.replace(`${product === null || product === void 0 ? void 0 : product.name}, `, '') : [
|
|
290
240
|
product === null || product === void 0 ? void 0 : product.name,
|
|
@@ -296,47 +246,8 @@ const nodeDefaultLabel = {
|
|
|
296
246
|
const defaultLabel = (node) => node ? (node['@type'] in nodeDefaultLabel ? nodeDefaultLabel[node['@type']](node) : node.name) || node['@id'] || node.id : '';
|
|
297
247
|
const itemColor = (index) => getColor({ text: `${index}` });
|
|
298
248
|
const listColor = (_v, index) => itemColor(index);
|
|
299
|
-
const minutesBefore = (date, minutes = 1) => {
|
|
300
|
-
date.setMinutes(date.getMinutes() - minutes);
|
|
301
|
-
return date;
|
|
302
|
-
};
|
|
303
|
-
const hoursBefore = (date, hours = 1) => {
|
|
304
|
-
date.setHours(date.getHours() - hours);
|
|
305
|
-
return date;
|
|
306
|
-
};
|
|
307
|
-
const repeat = (times = 0) => (Array.from(Array(times), Math.random));
|
|
308
|
-
var DeltaDisplayType;
|
|
309
|
-
(function (DeltaDisplayType) {
|
|
310
|
-
DeltaDisplayType["absolute"] = "absolute";
|
|
311
|
-
DeltaDisplayType["percent"] = "percent";
|
|
312
|
-
})(DeltaDisplayType || (DeltaDisplayType = {}));
|
|
313
|
-
const deltaPerType = {
|
|
314
|
-
[DeltaDisplayType.absolute]: (value, original) => value - original,
|
|
315
|
-
[DeltaDisplayType.percent]: (value, original) => ((value - original) / original) * 100
|
|
316
|
-
};
|
|
317
|
-
const roundValue = (value) => +`${value}`.substring(0, 10);
|
|
318
|
-
const delta = (value, originalValue, displayType = DeltaDisplayType.percent, customDeltaFuncs) => {
|
|
319
|
-
const vvalue = roundValue(propertyValue$1(value));
|
|
320
|
-
const voriginalValue = roundValue(propertyValue$1(originalValue));
|
|
321
|
-
const deltaFuncs = Object.assign(Object.assign({}, deltaPerType), customDeltaFuncs);
|
|
322
|
-
const diff = vvalue === voriginalValue ? 0 : deltaFuncs[displayType](vvalue, voriginalValue);
|
|
323
|
-
return Number.isFinite(diff) ? (diff === -0 ? 0 : diff) : 0;
|
|
324
|
-
};
|
|
325
|
-
var DeltaColour;
|
|
326
|
-
(function (DeltaColour) {
|
|
327
|
-
DeltaColour["Success"] = "success";
|
|
328
|
-
DeltaColour["Warning"] = "warning";
|
|
329
|
-
DeltaColour["Danger"] = "danger";
|
|
330
|
-
})(DeltaColour || (DeltaColour = {}));
|
|
331
|
-
const emptyValue = (value) => isEmpty(value) || isNaN(propertyValue$1(value));
|
|
332
|
-
const filenameWithoutExt = (filename = '') => {
|
|
333
|
-
const file = fileToExt(filename, '');
|
|
334
|
-
// remove last .
|
|
335
|
-
return file.endsWith('.') ? file.substring(0, file.length - 1) : file;
|
|
336
|
-
};
|
|
337
|
-
|
|
338
249
|
const reduceValues$1 = (values) => values.length ? values.reduce((p, v) => p + propertyValue$1(v.value), 0) : undefined;
|
|
339
|
-
const
|
|
250
|
+
const formatDiffValues = (originalValues = [], recalculatedValues = []) => {
|
|
340
251
|
const originalValuesFiltered = originalValues.filter((value) => !value.deleted);
|
|
341
252
|
const recalculatedValuesFiltered = recalculatedValues.filter((value) => !value.deleted);
|
|
342
253
|
const terms = unique([...originalValuesFiltered, ...recalculatedValuesFiltered].map((v) => v.term['@id'])).sort();
|
|
@@ -352,9 +263,39 @@ const formatValues = (originalValues = [], recalculatedValues = []) => {
|
|
|
352
263
|
});
|
|
353
264
|
return values;
|
|
354
265
|
};
|
|
266
|
+
const emptyValue = (value) => isEmpty(value) || isNaN(propertyValue$1(value));
|
|
267
|
+
const repeat = (times = 0) => (Array.from(Array(times), Math.random));
|
|
268
|
+
const filenameWithoutExt = (filename = '') => {
|
|
269
|
+
const file = fileToExt(filename, '');
|
|
270
|
+
// remove last .
|
|
271
|
+
return file.endsWith('.') ? file.substring(0, file.length - 1) : file;
|
|
272
|
+
};
|
|
355
273
|
|
|
356
274
|
const SUCCESS_CRITERION_MAX_DELTA_PERCENT = 5;
|
|
357
275
|
const WARNING_CRITERION_MAX_DELTA_PERCENT = 20;
|
|
276
|
+
var DeltaColour;
|
|
277
|
+
(function (DeltaColour) {
|
|
278
|
+
DeltaColour["Success"] = "success";
|
|
279
|
+
DeltaColour["Warning"] = "warning";
|
|
280
|
+
DeltaColour["Danger"] = "danger";
|
|
281
|
+
})(DeltaColour || (DeltaColour = {}));
|
|
282
|
+
var DeltaDisplayType;
|
|
283
|
+
(function (DeltaDisplayType) {
|
|
284
|
+
DeltaDisplayType["absolute"] = "absolute";
|
|
285
|
+
DeltaDisplayType["percent"] = "percent";
|
|
286
|
+
})(DeltaDisplayType || (DeltaDisplayType = {}));
|
|
287
|
+
const deltaPerType = {
|
|
288
|
+
[DeltaDisplayType.absolute]: (value, original) => value - original,
|
|
289
|
+
[DeltaDisplayType.percent]: (value, original) => ((value - original) / original) * 100
|
|
290
|
+
};
|
|
291
|
+
const roundValue = (value) => +`${value}`.substring(0, 10);
|
|
292
|
+
const delta = (value, originalValue, displayType = DeltaDisplayType.percent, mapping) => {
|
|
293
|
+
const vvalue = roundValue(propertyValue$1(value));
|
|
294
|
+
const voriginalValue = roundValue(propertyValue$1(originalValue));
|
|
295
|
+
const deltaFuncs = Object.assign(Object.assign({}, deltaPerType), mapping);
|
|
296
|
+
const diff = vvalue === voriginalValue ? 0 : deltaFuncs[displayType](vvalue, voriginalValue);
|
|
297
|
+
return Number.isFinite(diff) ? (diff === -0 ? 0 : diff) : 0;
|
|
298
|
+
};
|
|
358
299
|
var PercentDeltaConditions;
|
|
359
300
|
(function (PercentDeltaConditions) {
|
|
360
301
|
PercentDeltaConditions["recalculated0"] = "recalculated should be 0";
|
|
@@ -377,9 +318,9 @@ const calculatePercentDelta = (recalculated, original) => {
|
|
|
377
318
|
const customDeltaFuncs = {
|
|
378
319
|
[DeltaDisplayType.percent]: calculatePercentDelta
|
|
379
320
|
};
|
|
380
|
-
const evaluateSuccess = (
|
|
321
|
+
const evaluateSuccess = (deltaValue) => Math.abs(deltaValue) < SUCCESS_CRITERION_MAX_DELTA_PERCENT
|
|
381
322
|
? DeltaColour.Success
|
|
382
|
-
: Math.abs(
|
|
323
|
+
: Math.abs(deltaValue) < WARNING_CRITERION_MAX_DELTA_PERCENT
|
|
383
324
|
? DeltaColour.Warning
|
|
384
325
|
: DeltaColour.Danger;
|
|
385
326
|
|
|
@@ -461,7 +402,7 @@ class BlankNodeDiffsComponent {
|
|
|
461
402
|
this.values = [];
|
|
462
403
|
}
|
|
463
404
|
ngOnInit() {
|
|
464
|
-
this.values =
|
|
405
|
+
this.values = formatDiffValues(this.originalValues, this.recalculatedValues);
|
|
465
406
|
}
|
|
466
407
|
}
|
|
467
408
|
BlankNodeDiffsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: BlankNodeDiffsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -479,210 +420,187 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
479
420
|
type: Input
|
|
480
421
|
}] } });
|
|
481
422
|
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const deserializeSearchFilters = (filters) => (filters || '').split(';').reduce((prev, curr) => {
|
|
491
|
-
const [key, values] = curr.split('=');
|
|
492
|
-
prev[key] = (values || '').split('|').filter(Boolean);
|
|
493
|
-
return prev;
|
|
494
|
-
}, {});
|
|
495
|
-
const matchType = (type) => Object.freeze({
|
|
496
|
-
match: { '@type': type }
|
|
497
|
-
});
|
|
498
|
-
const matchTermType = (termType) => Object.freeze({
|
|
499
|
-
match: { termType }
|
|
500
|
-
});
|
|
501
|
-
const matchRegex = (key, value) => Object.freeze({
|
|
502
|
-
regexp: { [key]: { value: value.toString() } }
|
|
503
|
-
});
|
|
504
|
-
const matchQuery = (key, value, boost) => Object.freeze({
|
|
505
|
-
match: {
|
|
506
|
-
[key]: Object.assign({ query: value }, (boost ? { boost } : {}))
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
const matchExactQuery = (key, value, boost) => matchQuery(`${key}.keyword`, value, boost);
|
|
510
|
-
const matchNameNormalized = (query, boost = 20) => Object.freeze({
|
|
511
|
-
match: { nameNormalized: { query, boost } }
|
|
512
|
-
});
|
|
513
|
-
const numberGte = (key, value) => Object.freeze({
|
|
514
|
-
range: { [key]: { gte: value } }
|
|
423
|
+
const termProperties = (term) => Object.keys(term).filter(key => !isExpandable(term[key]) && ![
|
|
424
|
+
'pinned', 'expanded', 'extended', 'selected', 'loading',
|
|
425
|
+
'_score', '@type', '@id', '@context', 'createdAt',
|
|
426
|
+
'name', 'synonyms', 'termType', 'location', 'properties', 'schemaVersion'
|
|
427
|
+
].includes(key));
|
|
428
|
+
const findPropertyById = ({ defaultProperties }, key) => (defaultProperties || []).find(({ term }) => term['@id'] === key);
|
|
429
|
+
const termLocationName = ({ gadmFullName }) => ({
|
|
430
|
+
name: gadmFullName || ''
|
|
515
431
|
});
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
type }, (boost ? { boost } : {})), (analyzer ? { analyzer } : {}))
|
|
432
|
+
const termLocation = ({ latitude, longitude }) => ({
|
|
433
|
+
lat: latitude,
|
|
434
|
+
lng: longitude
|
|
520
435
|
});
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
436
|
+
const termTypeToLabel = {
|
|
437
|
+
[TermTermType.methodEmissionResourceUse]: 'Method (Emissions)',
|
|
438
|
+
[TermTermType.methodMeasurement]: 'Method (Measurement)',
|
|
439
|
+
[TermTermType.pesticideAI]: 'Pesticide Active Ingredient',
|
|
440
|
+
[TermTermType.standardsLabels]: 'Standards & Labels',
|
|
441
|
+
[TermTermType.usdaSoilType]: 'USDA Soil Type'
|
|
442
|
+
};
|
|
443
|
+
const termTypeLabel = (type = 'N/A') => type in termTypeToLabel ? termTypeToLabel[type] : keyToLabel(type);
|
|
444
|
+
const termTypesToChildren = (termTypes) => termTypes.map(termType => ({ label: termTypeLabel(termType), termType }));
|
|
445
|
+
const groups = Object.freeze({
|
|
446
|
+
[TermTermType.emission]: {
|
|
447
|
+
label: 'Emissions & Resource Use',
|
|
448
|
+
termType: 'Emissions & Resource Use',
|
|
449
|
+
children: termTypesToChildren([
|
|
450
|
+
TermTermType.emission,
|
|
451
|
+
TermTermType.resourceUse,
|
|
452
|
+
TermTermType.model,
|
|
453
|
+
TermTermType.characterisedIndicator,
|
|
454
|
+
TermTermType.endpointIndicator,
|
|
455
|
+
TermTermType.methodEmissionResourceUse
|
|
456
|
+
])
|
|
457
|
+
},
|
|
458
|
+
[TermTermType.region]: {
|
|
459
|
+
label: termTypeLabel(TermTermType.region),
|
|
460
|
+
termType: TermTermType.region,
|
|
461
|
+
children: []
|
|
462
|
+
},
|
|
463
|
+
infrastructure: {
|
|
464
|
+
label: 'Infrastructure & Equipment',
|
|
465
|
+
termType: 'Infrastructure & Equipment',
|
|
466
|
+
children: termTypesToChildren([
|
|
467
|
+
TermTermType.building,
|
|
468
|
+
TermTermType.cropProtection,
|
|
469
|
+
TermTermType.cropSupport,
|
|
470
|
+
TermTermType.irrigation,
|
|
471
|
+
TermTermType.machinery
|
|
472
|
+
])
|
|
473
|
+
},
|
|
474
|
+
input: {
|
|
475
|
+
label: 'Inputs',
|
|
476
|
+
termType: 'Inputs',
|
|
477
|
+
children: termTypesToChildren([
|
|
478
|
+
TermTermType.antibiotic,
|
|
479
|
+
TermTermType.electricity,
|
|
480
|
+
TermTermType.fuel,
|
|
481
|
+
TermTermType.material,
|
|
482
|
+
TermTermType.inorganicFertilizer,
|
|
483
|
+
TermTermType.organicFertilizer,
|
|
484
|
+
TermTermType.other,
|
|
485
|
+
TermTermType.pesticideAI,
|
|
486
|
+
TermTermType.pesticideBrandName,
|
|
487
|
+
TermTermType.soilAmendment,
|
|
488
|
+
TermTermType.transport,
|
|
489
|
+
TermTermType.water
|
|
490
|
+
])
|
|
491
|
+
},
|
|
492
|
+
[TermTermType.measurement]: {
|
|
493
|
+
label: 'Measurements',
|
|
494
|
+
termType: 'Measurements',
|
|
495
|
+
children: termTypesToChildren([
|
|
496
|
+
TermTermType.measurement,
|
|
497
|
+
TermTermType.soilTexture,
|
|
498
|
+
TermTermType.soilType,
|
|
499
|
+
TermTermType.usdaSoilType,
|
|
500
|
+
TermTermType.methodMeasurement
|
|
501
|
+
])
|
|
502
|
+
},
|
|
503
|
+
practice: {
|
|
504
|
+
label: 'Practices',
|
|
505
|
+
termType: 'Production Practices',
|
|
506
|
+
children: termTypesToChildren([
|
|
507
|
+
TermTermType.animalManagement,
|
|
508
|
+
TermTermType.aquacultureManagement,
|
|
509
|
+
TermTermType.biodiversity,
|
|
510
|
+
TermTermType.cropEstablishment,
|
|
511
|
+
TermTermType.cropResidueManagement,
|
|
512
|
+
TermTermType.excretaManagement,
|
|
513
|
+
TermTermType.landUseManagement,
|
|
514
|
+
TermTermType.operation,
|
|
515
|
+
TermTermType.standardsLabels,
|
|
516
|
+
TermTermType.system,
|
|
517
|
+
TermTermType.tillage,
|
|
518
|
+
TermTermType.waterRegime,
|
|
519
|
+
])
|
|
520
|
+
},
|
|
521
|
+
product: {
|
|
522
|
+
label: 'Products',
|
|
523
|
+
termType: 'Products',
|
|
524
|
+
children: termTypesToChildren([
|
|
525
|
+
TermTermType.crop,
|
|
526
|
+
TermTermType.cropResidue,
|
|
527
|
+
TermTermType.excreta,
|
|
528
|
+
TermTermType.liveAnimal,
|
|
529
|
+
TermTermType.liveAquaticSpecies,
|
|
530
|
+
TermTermType.animalProduct,
|
|
531
|
+
TermTermType.processedFood
|
|
532
|
+
])
|
|
533
|
+
},
|
|
534
|
+
[TermTermType.property]: {
|
|
535
|
+
label: termTypeLabel(TermTermType.property),
|
|
536
|
+
termType: TermTermType.property,
|
|
537
|
+
children: []
|
|
548
538
|
}
|
|
549
539
|
});
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
must: [
|
|
564
|
-
matchType(NodeType.Term),
|
|
565
|
-
matchTermType(TermTermType.region),
|
|
566
|
-
matchCountryLevel
|
|
567
|
-
]
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
const allCountriesQuery = Object.freeze({
|
|
571
|
-
bool: Object.assign({ must: [
|
|
572
|
-
matchType(NodeType.Term),
|
|
573
|
-
matchTermType(TermTermType.region)
|
|
574
|
-
] }, matchCountry.bool)
|
|
575
|
-
});
|
|
576
|
-
const matchRegion = numberGte('gadmLevel', 1);
|
|
577
|
-
const regionsQuery = Object.freeze({
|
|
578
|
-
bool: {
|
|
579
|
-
must: [
|
|
580
|
-
matchType(NodeType.Term),
|
|
581
|
-
matchTermType(TermTermType.region),
|
|
582
|
-
matchRegion
|
|
583
|
-
]
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
const worldRegion = Object.freeze({
|
|
587
|
-
'@id': 'region-world',
|
|
588
|
-
name: 'World'
|
|
589
|
-
});
|
|
590
|
-
const cropsQuery = Object.freeze({
|
|
591
|
-
bool: {
|
|
592
|
-
must: [
|
|
593
|
-
matchType(NodeType.Term),
|
|
594
|
-
matchTermType(TermTermType.crop)
|
|
595
|
-
]
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
const matchAggregatedQuery = matchQuery('aggregated', true);
|
|
599
|
-
const isNestedKey = (key) => nestedSearchableKeys.includes(key.split('.')[0]);
|
|
600
|
-
const matchNestedKey = (key, query) => isNestedKey(key) ? {
|
|
601
|
-
nested: { path: key.split('.')[0], query }
|
|
602
|
-
} : query;
|
|
603
|
-
/**
|
|
604
|
-
* List of fields to return in the search results.
|
|
605
|
-
*/
|
|
606
|
-
const searchResultsFields = Object.freeze({
|
|
607
|
-
[NodeType.Cycle]: [
|
|
608
|
-
'description', 'dataDescription', 'endDate',
|
|
609
|
-
'emissionsCount', 'inputsCount', 'productsCount',
|
|
610
|
-
'site.location', 'site.country.name', 'site.region.name'
|
|
611
|
-
],
|
|
612
|
-
[NodeType.Source]: ['bibliography.title', 'bibliography.documentDOI'],
|
|
613
|
-
[NodeType.ImpactAssessment]: ['emissionsResourceUseCount', 'impactsCount', 'country.name']
|
|
614
|
-
});
|
|
615
|
-
/**
|
|
616
|
-
* List of fields to search in.
|
|
617
|
-
*/
|
|
618
|
-
const searchFields = Object.freeze({
|
|
619
|
-
[NodeType.Cycle]: ['name', 'description', 'dataDescription'],
|
|
620
|
-
[NodeType.Source]: ['name', 'bibliography.title'],
|
|
621
|
-
[NodeType.ImpactAssessment]: ['name', 'product.name', 'country.name']
|
|
622
|
-
});
|
|
623
|
-
const searchFieldsNested = Object.freeze({
|
|
624
|
-
[NodeType.Cycle]: [
|
|
625
|
-
'inputs.term.name',
|
|
626
|
-
'emissions.term.name',
|
|
627
|
-
'practices.term.name'
|
|
628
|
-
],
|
|
629
|
-
[NodeType.Source]: [],
|
|
630
|
-
[NodeType.ImpactAssessment]: [
|
|
631
|
-
'emissionsResourceUse.term.name',
|
|
632
|
-
'impacts.term.name'
|
|
633
|
-
]
|
|
634
|
-
});
|
|
635
|
-
/**
|
|
636
|
-
* Specific strict queries per type.
|
|
637
|
-
*/
|
|
638
|
-
const searchQueries = {
|
|
639
|
-
[NodeType.Cycle]: { must: [], must_not: [matchAggregatedQuery] },
|
|
640
|
-
[NodeType.Source]: { must: [], must_not: [matchAggregatedQuery] }
|
|
641
|
-
};
|
|
642
|
-
const searchFiltersKeys = {
|
|
643
|
-
[NodeType.Cycle]: key => key,
|
|
644
|
-
[NodeType.Source]: key => key
|
|
645
|
-
};
|
|
646
|
-
/* eslint-disable complexity */
|
|
647
|
-
const searchQuery = (type, query, filters, aggregated) => {
|
|
648
|
-
const boolQuery = (Object.assign(Object.assign({ must: [
|
|
649
|
-
matchType(type),
|
|
650
|
-
aggregated ? matchAggregatedQuery : null
|
|
651
|
-
].filter(Boolean) }, (query ? {
|
|
652
|
-
should: [
|
|
653
|
-
matchPhraseQuery(query, 100, ...searchFields[type]),
|
|
654
|
-
matchPhrasePrefixQuery(query, 20, ...searchFields[type]),
|
|
655
|
-
matchBoolPrefixQuery(query, 10, ...searchFields[type]),
|
|
656
|
-
...searchFieldsNested[type].map(field => matchNestedKey(field, matchBoolPrefixQuery(query, 1, field)))
|
|
657
|
-
],
|
|
658
|
-
minimum_should_match: 1
|
|
659
|
-
} : {})), { must_not: [
|
|
660
|
-
aggregated ? null : matchAggregatedQuery
|
|
661
|
-
].filter(Boolean) }));
|
|
662
|
-
const keys = Object.keys(filters || {}).filter(key => filters[key].length);
|
|
663
|
-
return {
|
|
664
|
-
bool: keys.length ? {
|
|
665
|
-
must: keys.map(key => {
|
|
666
|
-
const filterKey = searchFiltersKeys[type](key);
|
|
667
|
-
return {
|
|
668
|
-
bool: {
|
|
669
|
-
should: filters[key]
|
|
670
|
-
.map(value => matchNestedKey(filterKey, matchExactQuery(filterKey, value)))
|
|
671
|
-
.map(must => {
|
|
672
|
-
const localQuery = JSON.parse(JSON.stringify(boolQuery));
|
|
673
|
-
localQuery.must.push(must);
|
|
674
|
-
return { bool: localQuery };
|
|
675
|
-
}),
|
|
676
|
-
minimum_should_match: 1
|
|
677
|
-
}
|
|
678
|
-
};
|
|
679
|
-
})
|
|
680
|
-
} : boolQuery
|
|
681
|
-
};
|
|
540
|
+
const termTypeGroups = [
|
|
541
|
+
groups.property,
|
|
542
|
+
groups.region,
|
|
543
|
+
groups.input,
|
|
544
|
+
groups.emission,
|
|
545
|
+
groups.product,
|
|
546
|
+
groups.practice,
|
|
547
|
+
groups.measurement,
|
|
548
|
+
groups.infrastructure
|
|
549
|
+
];
|
|
550
|
+
const termToParent = {
|
|
551
|
+
[TermTermType.property]: 'Properties',
|
|
552
|
+
[TermTermType.region]: 'Geographies'
|
|
682
553
|
};
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
const
|
|
554
|
+
const termChildToParent = (termType) => termTypeGroups.find(({ children }) => (children || []).some(child => child.termType === termType)) ||
|
|
555
|
+
{ termType: termToParent[termType] };
|
|
556
|
+
const sortOrder = [
|
|
557
|
+
TermTermType.property,
|
|
558
|
+
TermTermType.crop,
|
|
559
|
+
TermTermType.cropResidue,
|
|
560
|
+
TermTermType.animalProduct,
|
|
561
|
+
TermTermType.liveAnimal,
|
|
562
|
+
TermTermType.liveAquaticSpecies,
|
|
563
|
+
TermTermType.processedFood,
|
|
564
|
+
TermTermType.emission,
|
|
565
|
+
TermTermType.resourceUse,
|
|
566
|
+
TermTermType.inorganicFertilizer,
|
|
567
|
+
TermTermType.organicFertilizer,
|
|
568
|
+
TermTermType.soilAmendment,
|
|
569
|
+
TermTermType.soilTexture,
|
|
570
|
+
TermTermType.water,
|
|
571
|
+
TermTermType.material,
|
|
572
|
+
TermTermType.antibiotic,
|
|
573
|
+
TermTermType.electricity,
|
|
574
|
+
TermTermType.fuel,
|
|
575
|
+
TermTermType.aquacultureManagement,
|
|
576
|
+
TermTermType.biodiversity,
|
|
577
|
+
TermTermType.cropResidueManagement,
|
|
578
|
+
TermTermType.animalManagement,
|
|
579
|
+
TermTermType.waterRegime,
|
|
580
|
+
TermTermType.system,
|
|
581
|
+
TermTermType.tillage,
|
|
582
|
+
TermTermType.landUseManagement,
|
|
583
|
+
TermTermType.operation,
|
|
584
|
+
TermTermType.cropEstablishment,
|
|
585
|
+
TermTermType.measurement,
|
|
586
|
+
TermTermType.soilType,
|
|
587
|
+
TermTermType.usdaSoilType,
|
|
588
|
+
TermTermType.methodMeasurement,
|
|
589
|
+
TermTermType.building,
|
|
590
|
+
TermTermType.cropProtection,
|
|
591
|
+
TermTermType.cropSupport,
|
|
592
|
+
TermTermType.irrigation,
|
|
593
|
+
TermTermType.machinery,
|
|
594
|
+
TermTermType.model,
|
|
595
|
+
TermTermType.characterisedIndicator,
|
|
596
|
+
TermTermType.endpointIndicator,
|
|
597
|
+
TermTermType.methodEmissionResourceUse,
|
|
598
|
+
TermTermType.other,
|
|
599
|
+
TermTermType.region,
|
|
600
|
+
TermTermType.pesticideAI,
|
|
601
|
+
TermTermType.pesticideBrandName,
|
|
602
|
+
TermTermType.standardsLabels
|
|
603
|
+
];
|
|
686
604
|
|
|
687
605
|
const HE_API_BASE_URL = new InjectionToken('HE_API_BASE_URL');
|
|
688
606
|
class HeCommonService {
|
|
@@ -692,11 +610,6 @@ class HeCommonService {
|
|
|
692
610
|
get apiBaseUrl() {
|
|
693
611
|
return this._apiBaseUrl || '/api';
|
|
694
612
|
}
|
|
695
|
-
get gitBranch() {
|
|
696
|
-
return ['dev', 'staging'].some((env) => baseUrl().includes(env))
|
|
697
|
-
? 'develop'
|
|
698
|
-
: 'master';
|
|
699
|
-
}
|
|
700
613
|
}
|
|
701
614
|
HeCommonService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, deps: [{ token: HE_API_BASE_URL }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
702
615
|
HeCommonService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, providedIn: 'root' });
|
|
@@ -710,188 +623,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
710
623
|
args: [HE_API_BASE_URL]
|
|
711
624
|
}] }]; } });
|
|
712
625
|
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
lng: longitude
|
|
725
|
-
});
|
|
726
|
-
const termTypeToLabel = {
|
|
727
|
-
[TermTermType.methodEmissionResourceUse]: 'Method (Emissions)',
|
|
728
|
-
[TermTermType.methodMeasurement]: 'Method (Measurement)',
|
|
729
|
-
[TermTermType.pesticideAI]: 'Pesticide Active Ingredient',
|
|
730
|
-
[TermTermType.standardsLabels]: 'Standards & Labels',
|
|
731
|
-
[TermTermType.usdaSoilType]: 'USDA Soil Type'
|
|
626
|
+
const nodeTypeUrl = (apiBaseUrl, type) => type ? `${apiBaseUrl}/${nodeTypeToParam(type)}` : '';
|
|
627
|
+
/**
|
|
628
|
+
* Get the full url to fetch the node data.
|
|
629
|
+
*
|
|
630
|
+
* @param apiBaseUrl The url of the API hosting the data.
|
|
631
|
+
* @param node The node with a type, id and optionally a dataState
|
|
632
|
+
* @returns The full url.
|
|
633
|
+
*/
|
|
634
|
+
const nodeUrl = (apiBaseUrl, _a) => {
|
|
635
|
+
var { dataState } = _a, node = __rest(_a, ["dataState"]);
|
|
636
|
+
return `${nodeTypeUrl(apiBaseUrl, node['@type'] || node.type)}/${node['@id'] || node.id}${dataState ? `?dataState=${dataState}` : ''}`;
|
|
732
637
|
};
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
[TermTermType.emission]: {
|
|
737
|
-
label: 'Emissions & Resource Use',
|
|
738
|
-
termType: 'Emissions & Resource Use',
|
|
739
|
-
children: termTypesToChildren([
|
|
740
|
-
TermTermType.emission,
|
|
741
|
-
TermTermType.resourceUse,
|
|
742
|
-
TermTermType.model,
|
|
743
|
-
TermTermType.characterisedIndicator,
|
|
744
|
-
TermTermType.endpointIndicator,
|
|
745
|
-
TermTermType.methodEmissionResourceUse
|
|
746
|
-
])
|
|
747
|
-
},
|
|
748
|
-
[TermTermType.region]: {
|
|
749
|
-
label: termTypeLabel(TermTermType.region),
|
|
750
|
-
termType: TermTermType.region,
|
|
751
|
-
children: []
|
|
752
|
-
},
|
|
753
|
-
infrastructure: {
|
|
754
|
-
label: 'Infrastructure & Equipment',
|
|
755
|
-
termType: 'Infrastructure & Equipment',
|
|
756
|
-
children: termTypesToChildren([
|
|
757
|
-
TermTermType.building,
|
|
758
|
-
TermTermType.cropProtection,
|
|
759
|
-
TermTermType.cropSupport,
|
|
760
|
-
TermTermType.irrigation,
|
|
761
|
-
TermTermType.machinery
|
|
762
|
-
])
|
|
763
|
-
},
|
|
764
|
-
input: {
|
|
765
|
-
label: 'Inputs',
|
|
766
|
-
termType: 'Inputs',
|
|
767
|
-
children: termTypesToChildren([
|
|
768
|
-
TermTermType.antibiotic,
|
|
769
|
-
TermTermType.electricity,
|
|
770
|
-
TermTermType.fuel,
|
|
771
|
-
TermTermType.material,
|
|
772
|
-
TermTermType.inorganicFertilizer,
|
|
773
|
-
TermTermType.organicFertilizer,
|
|
774
|
-
TermTermType.other,
|
|
775
|
-
TermTermType.pesticideAI,
|
|
776
|
-
TermTermType.pesticideBrandName,
|
|
777
|
-
TermTermType.soilAmendment,
|
|
778
|
-
TermTermType.transport,
|
|
779
|
-
TermTermType.water
|
|
780
|
-
])
|
|
781
|
-
},
|
|
782
|
-
[TermTermType.measurement]: {
|
|
783
|
-
label: 'Measurements',
|
|
784
|
-
termType: 'Measurements',
|
|
785
|
-
children: termTypesToChildren([
|
|
786
|
-
TermTermType.measurement,
|
|
787
|
-
TermTermType.soilTexture,
|
|
788
|
-
TermTermType.soilType,
|
|
789
|
-
TermTermType.usdaSoilType,
|
|
790
|
-
TermTermType.methodMeasurement
|
|
791
|
-
])
|
|
792
|
-
},
|
|
793
|
-
practice: {
|
|
794
|
-
label: 'Practices',
|
|
795
|
-
termType: 'Production Practices',
|
|
796
|
-
children: termTypesToChildren([
|
|
797
|
-
TermTermType.animalManagement,
|
|
798
|
-
TermTermType.aquacultureManagement,
|
|
799
|
-
TermTermType.biodiversity,
|
|
800
|
-
TermTermType.cropEstablishment,
|
|
801
|
-
TermTermType.cropResidueManagement,
|
|
802
|
-
TermTermType.excretaManagement,
|
|
803
|
-
TermTermType.landUseManagement,
|
|
804
|
-
TermTermType.operation,
|
|
805
|
-
TermTermType.standardsLabels,
|
|
806
|
-
TermTermType.system,
|
|
807
|
-
TermTermType.tillage,
|
|
808
|
-
TermTermType.waterRegime,
|
|
809
|
-
])
|
|
810
|
-
},
|
|
811
|
-
product: {
|
|
812
|
-
label: 'Products',
|
|
813
|
-
termType: 'Products',
|
|
814
|
-
children: termTypesToChildren([
|
|
815
|
-
TermTermType.crop,
|
|
816
|
-
TermTermType.cropResidue,
|
|
817
|
-
TermTermType.excreta,
|
|
818
|
-
TermTermType.liveAnimal,
|
|
819
|
-
TermTermType.liveAquaticSpecies,
|
|
820
|
-
TermTermType.animalProduct,
|
|
821
|
-
TermTermType.processedFood
|
|
822
|
-
])
|
|
823
|
-
},
|
|
824
|
-
[TermTermType.property]: {
|
|
825
|
-
label: termTypeLabel(TermTermType.property),
|
|
826
|
-
termType: TermTermType.property,
|
|
827
|
-
children: []
|
|
828
|
-
}
|
|
829
|
-
});
|
|
830
|
-
const termTypeGroups = [
|
|
831
|
-
groups.property,
|
|
832
|
-
groups.region,
|
|
833
|
-
groups.input,
|
|
834
|
-
groups.emission,
|
|
835
|
-
groups.product,
|
|
836
|
-
groups.practice,
|
|
837
|
-
groups.measurement,
|
|
838
|
-
groups.infrastructure
|
|
839
|
-
];
|
|
840
|
-
const termToParent = {
|
|
841
|
-
[TermTermType.property]: 'Properties',
|
|
842
|
-
[TermTermType.region]: 'Geographies'
|
|
638
|
+
const nodeLogsUrl = (apiBaseUrl, _a) => {
|
|
639
|
+
var { dataState } = _a, node = __rest(_a, ["dataState"]);
|
|
640
|
+
return `${nodeUrl(apiBaseUrl, node)}/log${dataState ? `?dataState=${dataState}` : ''}`;
|
|
843
641
|
};
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
const sortOrder = [
|
|
847
|
-
TermTermType.property,
|
|
848
|
-
TermTermType.crop,
|
|
849
|
-
TermTermType.cropResidue,
|
|
850
|
-
TermTermType.animalProduct,
|
|
851
|
-
TermTermType.liveAnimal,
|
|
852
|
-
TermTermType.liveAquaticSpecies,
|
|
853
|
-
TermTermType.processedFood,
|
|
854
|
-
TermTermType.emission,
|
|
855
|
-
TermTermType.resourceUse,
|
|
856
|
-
TermTermType.inorganicFertilizer,
|
|
857
|
-
TermTermType.organicFertilizer,
|
|
858
|
-
TermTermType.soilAmendment,
|
|
859
|
-
TermTermType.soilTexture,
|
|
860
|
-
TermTermType.water,
|
|
861
|
-
TermTermType.material,
|
|
862
|
-
TermTermType.antibiotic,
|
|
863
|
-
TermTermType.electricity,
|
|
864
|
-
TermTermType.fuel,
|
|
865
|
-
TermTermType.aquacultureManagement,
|
|
866
|
-
TermTermType.biodiversity,
|
|
867
|
-
TermTermType.cropResidueManagement,
|
|
868
|
-
TermTermType.animalManagement,
|
|
869
|
-
TermTermType.waterRegime,
|
|
870
|
-
TermTermType.system,
|
|
871
|
-
TermTermType.tillage,
|
|
872
|
-
TermTermType.landUseManagement,
|
|
873
|
-
TermTermType.operation,
|
|
874
|
-
TermTermType.cropEstablishment,
|
|
875
|
-
TermTermType.measurement,
|
|
876
|
-
TermTermType.soilType,
|
|
877
|
-
TermTermType.usdaSoilType,
|
|
878
|
-
TermTermType.methodMeasurement,
|
|
879
|
-
TermTermType.building,
|
|
880
|
-
TermTermType.cropProtection,
|
|
881
|
-
TermTermType.cropSupport,
|
|
882
|
-
TermTermType.irrigation,
|
|
883
|
-
TermTermType.machinery,
|
|
884
|
-
TermTermType.model,
|
|
885
|
-
TermTermType.characterisedIndicator,
|
|
886
|
-
TermTermType.endpointIndicator,
|
|
887
|
-
TermTermType.methodEmissionResourceUse,
|
|
888
|
-
TermTermType.other,
|
|
889
|
-
TermTermType.region,
|
|
890
|
-
TermTermType.pesticideAI,
|
|
891
|
-
TermTermType.pesticideBrandName,
|
|
892
|
-
TermTermType.standardsLabels
|
|
893
|
-
];
|
|
894
|
-
|
|
642
|
+
const lookupUrl = (filename) => filename.startsWith('http') ? filename : `${baseUrl()}/glossary/lookups/${filename}.csv`;
|
|
643
|
+
const termTypeLookupUrl = (termType) => `${baseUrl()}/glossary/${termChildToParent(termType).termType}/${termType}.csv`;
|
|
895
644
|
class HeNodeService {
|
|
896
645
|
constructor(http, authService, commonService) {
|
|
897
646
|
this.http = http;
|
|
@@ -944,26 +693,18 @@ class HeNodeService {
|
|
|
944
693
|
.catch(() => (responseType === 'json' ? ({}) : ''));
|
|
945
694
|
}
|
|
946
695
|
nodeTypeUrl(type) {
|
|
947
|
-
return
|
|
696
|
+
return nodeTypeUrl(this.commonService.apiBaseUrl, type);
|
|
948
697
|
}
|
|
949
|
-
nodeUrl(
|
|
950
|
-
|
|
951
|
-
return `${this.nodeTypeUrl(node['@type'] || node.type)}/${node['@id'] || node.id}${dataState ? `?dataState=${dataState}` : ''}`;
|
|
952
|
-
}
|
|
953
|
-
nodeLogsUrl(_a) {
|
|
954
|
-
var { dataState } = _a, node = __rest(_a, ["dataState"]);
|
|
955
|
-
return `${this.nodeUrl(node)}/log${dataState ? `?dataState=${dataState}` : ''}`;
|
|
956
|
-
}
|
|
957
|
-
lookupUrl(filename) {
|
|
958
|
-
return filename.startsWith('http') ? filename : `${baseUrl()}/glossary/lookups/${filename}.csv`;
|
|
698
|
+
nodeUrl(node) {
|
|
699
|
+
return nodeUrl(this.commonService.apiBaseUrl, node);
|
|
959
700
|
}
|
|
960
|
-
|
|
961
|
-
return
|
|
701
|
+
nodeLogsUrl(node) {
|
|
702
|
+
return nodeLogsUrl(this.commonService.apiBaseUrl, node);
|
|
962
703
|
}
|
|
963
704
|
downloadLookup(filename) {
|
|
964
705
|
return __awaiter(this, void 0, void 0, function* () {
|
|
965
706
|
try {
|
|
966
|
-
const url =
|
|
707
|
+
const url = lookupUrl(filename);
|
|
967
708
|
return this.downloadRaw(url, 'text');
|
|
968
709
|
}
|
|
969
710
|
catch (_err) {
|
|
@@ -975,7 +716,7 @@ class HeNodeService {
|
|
|
975
716
|
return __awaiter(this, void 0, void 0, function* () {
|
|
976
717
|
try {
|
|
977
718
|
const data = yield this.downloadLookup(termType);
|
|
978
|
-
return (data === null || data === void 0 ? void 0 : data.startsWith('term.id')) ?
|
|
719
|
+
return (data === null || data === void 0 ? void 0 : data.startsWith('term.id')) ? lookupUrl(termType) : null;
|
|
979
720
|
}
|
|
980
721
|
catch (_err) {
|
|
981
722
|
return null;
|
|
@@ -992,42 +733,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
992
733
|
}]
|
|
993
734
|
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeAuthService }, { type: HeCommonService }]; } });
|
|
994
735
|
|
|
995
|
-
const
|
|
736
|
+
const gitUrl$1 = () => `${gitHome}/hestia-aggregation-engine/-/blob/${gitBranch()}`;
|
|
737
|
+
const rawUrl$1 = () => `${gitRawBaseUrl}/hestia-aggregation-engine/-/raw/${gitBranch()}`;
|
|
996
738
|
const lookups = Object.freeze({
|
|
997
739
|
cropYield: 'region-crop-cropGroupingFaostatProduction-yield',
|
|
998
740
|
cropGroupingColumn: 'cropGroupingFaostatProduction'
|
|
999
741
|
});
|
|
1000
|
-
const extractGroupedDataClosesDate = (data, year) => {
|
|
1001
|
-
const dataByDate = (data || '').split(';').reduce((prev, curr) => (Object.assign(Object.assign({}, prev), (curr.length > 0 && curr.split(':')[1] !== '-' ? { [curr.split(':')[0]]: curr.split(':')[1] } : {}))), {});
|
|
1002
|
-
const years = Object.keys(dataByDate).map(v => +v);
|
|
1003
|
-
const closestYear = years.reduce((prev, curr) => Math.abs(curr - year) < Math.abs(prev - year) ? curr : prev, 0);
|
|
1004
|
-
return closestYear ? +dataByDate[closestYear] / 10 : null;
|
|
1005
|
-
};
|
|
1006
|
-
const cropGrouping = (lookup, product) => (lookup.find(({ term }) => term.id === (product === null || product === void 0 ? void 0 : product.term['@id'])) || {})[lookups.cropGroupingColumn];
|
|
1007
|
-
const cropYieldCountry = (cropYield, cycle) => cropYield.find(({ term }) => term.id === get$4(cycle, 'site.country.@id', worldRegion['@id'])) || {};
|
|
1008
|
-
const extendCycle = ({ crop, cropYield }) => (cycle) => {
|
|
1009
|
-
var _a, _b, _c;
|
|
1010
|
-
const product = primaryProduct(cycle);
|
|
1011
|
-
const grouping = cropGrouping(crop, product);
|
|
1012
|
-
const countryData = cropYieldCountry(cropYield, cycle)[grouping];
|
|
1013
|
-
const countryValue = extractGroupedDataClosesDate(countryData, +(cycle.endDate || ''));
|
|
1014
|
-
const productValue = propertyValue$1(product === null || product === void 0 ? void 0 : product.value);
|
|
1015
|
-
return {
|
|
1016
|
-
cycle,
|
|
1017
|
-
name: (_a = product === null || product === void 0 ? void 0 : product.term) === null || _a === void 0 ? void 0 : _a.name,
|
|
1018
|
-
startDate: cycle.startDate,
|
|
1019
|
-
endDate: cycle.endDate,
|
|
1020
|
-
country: ((_c = (_b = cycle.site) === null || _b === void 0 ? void 0 : _b.country) === null || _c === void 0 ? void 0 : _c.name) || worldRegion.name,
|
|
1021
|
-
observations: propertyValue$1(product === null || product === void 0 ? void 0 : product.observations) || 0,
|
|
1022
|
-
yield: productValue,
|
|
1023
|
-
faoYield: countryValue || undefined,
|
|
1024
|
-
diff: delta(productValue, countryValue)
|
|
1025
|
-
};
|
|
1026
|
-
};
|
|
1027
742
|
class HeAggregationEngineService {
|
|
1028
|
-
constructor(http,
|
|
743
|
+
constructor(http, nodeService) {
|
|
1029
744
|
this.http = http;
|
|
1030
|
-
this.commonService = commonService;
|
|
1031
745
|
this.nodeService = nodeService;
|
|
1032
746
|
this.modelsLoading = false;
|
|
1033
747
|
this.modelsLoaded = false;
|
|
@@ -1042,18 +756,12 @@ class HeAggregationEngineService {
|
|
|
1042
756
|
yield this.loadModels().toPromise();
|
|
1043
757
|
});
|
|
1044
758
|
}
|
|
1045
|
-
get gitUrl() {
|
|
1046
|
-
return `${gitHome}/hestia-aggregation-engine/-/blob/${this.commonService.gitBranch}`;
|
|
1047
|
-
}
|
|
1048
|
-
get rawUrl() {
|
|
1049
|
-
return `${gitRawBaseUrl}/hestia-aggregation-engine/-/raw/${this.commonService.gitBranch}`;
|
|
1050
|
-
}
|
|
1051
759
|
loadModels() {
|
|
1052
760
|
this.modelsLoading = true;
|
|
1053
|
-
return this.http.get(`${
|
|
761
|
+
return this.http.get(`${rawUrl$1()}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
|
|
1054
762
|
this._models.next(links.map((_a) => {
|
|
1055
763
|
var { path: modelPath, docPath } = _a, link = __rest(_a, ["path", "docPath"]);
|
|
1056
|
-
return (Object.assign(Object.assign({}, link), { path: `${
|
|
764
|
+
return (Object.assign(Object.assign({}, link), { path: `${gitUrl$1()}/${modelPath}`, docPath: `${gitUrl$1()}/${docPath}` }));
|
|
1057
765
|
}));
|
|
1058
766
|
this.modelsLoading = false;
|
|
1059
767
|
this.modelsLoaded = true;
|
|
@@ -1096,16 +804,18 @@ class HeAggregationEngineService {
|
|
|
1096
804
|
return this.lookups$.pipe(take(1)).toPromise();
|
|
1097
805
|
}
|
|
1098
806
|
}
|
|
1099
|
-
HeAggregationEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, deps: [{ token: i1$1.HttpClient }, { token:
|
|
807
|
+
HeAggregationEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, deps: [{ token: i1$1.HttpClient }, { token: HeNodeService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1100
808
|
HeAggregationEngineService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, providedIn: 'root' });
|
|
1101
809
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, decorators: [{
|
|
1102
810
|
type: Injectable,
|
|
1103
811
|
args: [{
|
|
1104
812
|
providedIn: 'root'
|
|
1105
813
|
}]
|
|
1106
|
-
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type:
|
|
814
|
+
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeNodeService }]; } });
|
|
1107
815
|
|
|
1108
816
|
const HE_ORCHESTRATOR_BASE_URL = new InjectionToken('HE_ORCHESTRATOR_BASE_URL');
|
|
817
|
+
const gitUrl = () => `${gitHome}/hestia-engine-models/-/blob/${gitBranch()}`;
|
|
818
|
+
const rawUrl = () => `${gitRawBaseUrl}/hestia-engine-models/-/raw/${gitBranch()}`;
|
|
1109
819
|
const findConfigModels = ({ models }, modelId, modelKey) => models.flat().filter(({ value, key }) => modelId.startsWith(value) && (!modelKey || key === modelKey));
|
|
1110
820
|
const pathToApiDocsPath = (model, term) => [
|
|
1111
821
|
baseUrl(),
|
|
@@ -1117,9 +827,8 @@ const pathToApiDocsPath = (model, term) => [
|
|
|
1117
827
|
].filter(Boolean).join('-')
|
|
1118
828
|
].join('/');
|
|
1119
829
|
class HeEngineService {
|
|
1120
|
-
constructor(http
|
|
830
|
+
constructor(http) {
|
|
1121
831
|
this.http = http;
|
|
1122
|
-
this.commonService = commonService;
|
|
1123
832
|
this.modelsLoading = false;
|
|
1124
833
|
this.modelsLoaded = false;
|
|
1125
834
|
this._models = new ReplaySubject(1);
|
|
@@ -1130,18 +839,12 @@ class HeEngineService {
|
|
|
1130
839
|
yield this.loadModels().toPromise();
|
|
1131
840
|
});
|
|
1132
841
|
}
|
|
1133
|
-
get gitUrl() {
|
|
1134
|
-
return `${gitHome}/hestia-engine-models/-/blob/${this.commonService.gitBranch}`;
|
|
1135
|
-
}
|
|
1136
|
-
get rawUrl() {
|
|
1137
|
-
return `${gitRawBaseUrl}/hestia-engine-models/-/raw/${this.commonService.gitBranch}`;
|
|
1138
|
-
}
|
|
1139
842
|
loadModels() {
|
|
1140
843
|
this.modelsLoading = true;
|
|
1141
|
-
return this.http.get(`${
|
|
844
|
+
return this.http.get(`${rawUrl()}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
|
|
1142
845
|
this._models.next(links.map((_a) => {
|
|
1143
846
|
var { path, docPath } = _a, link = __rest(_a, ["path", "docPath"]);
|
|
1144
|
-
return (Object.assign(Object.assign({}, link), { path: `${
|
|
847
|
+
return (Object.assign(Object.assign({}, link), { path: `${gitUrl()}/${path}`, docPath: `${gitUrl()}/${docPath}`, apiDocsPath: pathToApiDocsPath(link.model, link.term || link.modelKey) }));
|
|
1145
848
|
}));
|
|
1146
849
|
this.modelsLoading = false;
|
|
1147
850
|
this.modelsLoaded = true;
|
|
@@ -1166,14 +869,14 @@ class HeEngineService {
|
|
|
1166
869
|
}).toPromise();
|
|
1167
870
|
}
|
|
1168
871
|
}
|
|
1169
|
-
HeEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, deps: [{ token: i1$1.HttpClient }
|
|
872
|
+
HeEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1170
873
|
HeEngineService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, providedIn: 'root' });
|
|
1171
874
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, decorators: [{
|
|
1172
875
|
type: Injectable,
|
|
1173
876
|
args: [{
|
|
1174
877
|
providedIn: 'root'
|
|
1175
878
|
}]
|
|
1176
|
-
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }
|
|
879
|
+
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }]; } });
|
|
1177
880
|
|
|
1178
881
|
var NodeKeyState;
|
|
1179
882
|
(function (NodeKeyState) {
|
|
@@ -1749,7 +1452,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
1749
1452
|
}] } });
|
|
1750
1453
|
|
|
1751
1454
|
let toastId = 0;
|
|
1752
|
-
class
|
|
1455
|
+
class HeToastService {
|
|
1753
1456
|
constructor() {
|
|
1754
1457
|
this.toasts = new ReplaySubject(1);
|
|
1755
1458
|
}
|
|
@@ -1772,9 +1475,9 @@ class ToastService {
|
|
|
1772
1475
|
});
|
|
1773
1476
|
}
|
|
1774
1477
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type:
|
|
1478
|
+
HeToastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1479
|
+
HeToastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, providedIn: 'root' });
|
|
1480
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, decorators: [{
|
|
1778
1481
|
type: Injectable,
|
|
1779
1482
|
args: [{
|
|
1780
1483
|
providedIn: 'root'
|
|
@@ -1803,7 +1506,7 @@ class ToastComponent {
|
|
|
1803
1506
|
this.toasts.splice(this.toasts.findIndex(val => val.id === toast.id), 1);
|
|
1804
1507
|
}
|
|
1805
1508
|
}
|
|
1806
|
-
ToastComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, deps: [{ token:
|
|
1509
|
+
ToastComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, deps: [{ token: HeToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1807
1510
|
ToastComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ToastComponent, selector: "he-toast", ngImport: i0, template: "<div class=\"mb-3 columns is-centered is-vcentered\">\n <div class=\"notification is-{{toast.color}}\" role=\"alert\" *ngFor=\"let toast of toasts\">\n <button class=\"delete\" aria-label=\"delete\" (click)=\"dismiss(toast)\">\n <span aria-hidden=\"true\">×</span>\n </button>\n <strong [ngSwitch]=\"toast.color\">\n <ng-container *ngSwitchCase=\"'danger'\">\n <ng-container [ngSwitch]=\"toast.message\">\n <span *ngSwitchCase=\"'Unauthorized'\">You are not allowed to perform this action.</span>\n <span *ngSwitchCase=\"'form-invalid'\">Please fix all the errors on this page.</span>\n <span *ngSwitchCase=\"'users-email-already-taken'\">Email already taken.</span>\n <span *ngSwitchCase=\"'users-auth-already-taken'\">Account already connected.</span>\n <span *ngSwitchDefault>\n <span *ngIf=\"toast.showRawMessage\">{{toast.message}}</span>\n <span [class.is-hidden]=\"toast.showRawMessage\">An unknown error occurred. Please try again later.</span>\n </span>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <span *ngIf=\"toast.showRawMessage\">{{toast.message}}</span>\n <span [class.is-hidden]=\"toast.showRawMessage\">An unknown error occurred. Please try again later.</span>\n </ng-container>\n </strong>\n </div>\n</div>\n", styles: [":host{bottom:0;position:fixed;width:100%}\n"], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
1808
1511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, decorators: [{
|
|
1809
1512
|
type: Component,
|
|
@@ -1812,7 +1515,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
1812
1515
|
templateUrl: './toast.component.html',
|
|
1813
1516
|
styleUrls: ['./toast.component.scss']
|
|
1814
1517
|
}]
|
|
1815
|
-
}], ctorParameters: function () { return [{ type:
|
|
1518
|
+
}], ctorParameters: function () { return [{ type: HeToastService }]; } });
|
|
1816
1519
|
|
|
1817
1520
|
class KeysPipe {
|
|
1818
1521
|
transform(value, sort = false) {
|
|
@@ -2228,58 +1931,261 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
2228
1931
|
}]
|
|
2229
1932
|
}], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeCommonService }]; } });
|
|
2230
1933
|
|
|
2231
|
-
const
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
results: []
|
|
2235
|
-
});
|
|
2236
|
-
const MAX_RESULTS = 10000;
|
|
2237
|
-
const suggestMatchQuery = (query) => [
|
|
2238
|
-
matchPhraseQuery(query, 10),
|
|
2239
|
-
matchQuery('nameNormalized', query, 8),
|
|
2240
|
-
matchPhrasePrefixQuery(query, 2)
|
|
1934
|
+
const searchableTypes = [
|
|
1935
|
+
NodeType.Cycle,
|
|
1936
|
+
NodeType.Source
|
|
2241
1937
|
];
|
|
2242
|
-
const
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
1938
|
+
const serializeSearchFilters = (filters) => Object.keys(filters || {})
|
|
1939
|
+
.filter(key => filters[key].length)
|
|
1940
|
+
.map(key => `${key}=${filters[key].filter(Boolean).join('|')}`)
|
|
1941
|
+
.join(';');
|
|
1942
|
+
const deserializeSearchFilters = (filters) => (filters || '').split(';').reduce((prev, curr) => {
|
|
1943
|
+
const [key, values] = curr.split('=');
|
|
1944
|
+
prev[key] = (values || '').split('|').filter(Boolean);
|
|
1945
|
+
return prev;
|
|
1946
|
+
}, {});
|
|
1947
|
+
const matchType = (type) => Object.freeze({
|
|
1948
|
+
match: { '@type': type }
|
|
1949
|
+
});
|
|
1950
|
+
const matchTermType = (termType) => Object.freeze({
|
|
1951
|
+
match: { termType }
|
|
1952
|
+
});
|
|
1953
|
+
const matchRegex = (key, value) => Object.freeze({
|
|
1954
|
+
regexp: { [key]: { value: value.toString() } }
|
|
1955
|
+
});
|
|
1956
|
+
const matchQuery = (key, value, boost) => Object.freeze({
|
|
1957
|
+
match: {
|
|
1958
|
+
[key]: Object.assign({ query: value }, (boost ? { boost } : {}))
|
|
1959
|
+
}
|
|
1960
|
+
});
|
|
1961
|
+
const matchExactQuery = (key, value, boost) => matchQuery(`${key}.keyword`, value, boost);
|
|
1962
|
+
const matchNameNormalized = (query, boost = 20) => Object.freeze({
|
|
1963
|
+
match: { nameNormalized: { query, boost } }
|
|
1964
|
+
});
|
|
1965
|
+
const numberGte = (key, value) => Object.freeze({
|
|
1966
|
+
range: { [key]: { gte: value } }
|
|
1967
|
+
});
|
|
1968
|
+
const multiMatchQuery = (query, fields, type = 'best_fields', boost, analyzer) => Object.freeze({
|
|
1969
|
+
multi_match: Object.assign(Object.assign({ query,
|
|
1970
|
+
fields,
|
|
1971
|
+
type }, (boost ? { boost } : {})), (analyzer ? { analyzer } : {}))
|
|
1972
|
+
});
|
|
1973
|
+
const matchPhraseQuery = (query, boost, ...fields) => fields.length ? multiMatchQuery(query, fields, 'phrase', boost) : matchExactQuery('name', query, boost);
|
|
1974
|
+
const matchPhrasePrefixQuery = (query, boost = 2, ...fields) => fields.length ?
|
|
1975
|
+
multiMatchQuery(query, fields, 'phrase_prefix', boost) :
|
|
1976
|
+
Object.freeze({
|
|
1977
|
+
match_phrase_prefix: {
|
|
1978
|
+
nameSearchAsYouType: {
|
|
1979
|
+
query,
|
|
1980
|
+
boost
|
|
2250
1981
|
}
|
|
2251
|
-
}
|
|
2252
|
-
|
|
1982
|
+
}
|
|
1983
|
+
});
|
|
1984
|
+
const matchBoolPrefixQuery = (query, boost = 1, ...fields) => fields.length ?
|
|
1985
|
+
multiMatchQuery(query, fields, 'bool_prefix', boost) :
|
|
1986
|
+
Object.freeze({
|
|
1987
|
+
match_bool_prefix: {
|
|
1988
|
+
name: {
|
|
1989
|
+
query,
|
|
1990
|
+
boost
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
const wildcardQuery = (query, boost = 3, ...fields) => Object.freeze({
|
|
1995
|
+
simple_query_string: {
|
|
1996
|
+
query: `*${query}*`,
|
|
1997
|
+
fields,
|
|
1998
|
+
analyze_wildcard: true,
|
|
1999
|
+
boost
|
|
2253
2000
|
}
|
|
2254
2001
|
});
|
|
2255
|
-
const
|
|
2002
|
+
const matchCountryLevel = { match: { gadmLevel: 0 } };
|
|
2003
|
+
const matchGlobalRegion = { regexp: { '@id': 'region-*' } };
|
|
2004
|
+
const matchCountry = Object.freeze({
|
|
2256
2005
|
bool: {
|
|
2257
|
-
must: [matchType(NodeType.Source)],
|
|
2258
2006
|
should: [
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
matchBoolPrefixQuery(query, 10, ...fields)
|
|
2007
|
+
matchCountryLevel,
|
|
2008
|
+
matchGlobalRegion
|
|
2262
2009
|
],
|
|
2263
2010
|
minimum_should_match: 1
|
|
2264
2011
|
}
|
|
2265
2012
|
});
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
.pipe(catchError(() => of(emptySearchResult())))
|
|
2274
|
-
.toPromise();
|
|
2275
|
-
}
|
|
2276
|
-
count(params = {}) {
|
|
2277
|
-
return this.http.post(`${this.commonService.apiBaseUrl}/count`, params).toPromise().catch(() => 0);
|
|
2013
|
+
const countriesQuery = Object.freeze({
|
|
2014
|
+
bool: {
|
|
2015
|
+
must: [
|
|
2016
|
+
matchType(NodeType.Term),
|
|
2017
|
+
matchTermType(TermTermType.region),
|
|
2018
|
+
matchCountryLevel
|
|
2019
|
+
]
|
|
2278
2020
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2021
|
+
});
|
|
2022
|
+
const allCountriesQuery = Object.freeze({
|
|
2023
|
+
bool: Object.assign({ must: [
|
|
2024
|
+
matchType(NodeType.Term),
|
|
2025
|
+
matchTermType(TermTermType.region)
|
|
2026
|
+
] }, matchCountry.bool)
|
|
2027
|
+
});
|
|
2028
|
+
const matchRegion = numberGte('gadmLevel', 1);
|
|
2029
|
+
const regionsQuery = Object.freeze({
|
|
2030
|
+
bool: {
|
|
2031
|
+
must: [
|
|
2032
|
+
matchType(NodeType.Term),
|
|
2033
|
+
matchTermType(TermTermType.region),
|
|
2034
|
+
matchRegion
|
|
2035
|
+
]
|
|
2036
|
+
}
|
|
2037
|
+
});
|
|
2038
|
+
const worldRegion = Object.freeze({
|
|
2039
|
+
'@id': 'region-world',
|
|
2040
|
+
name: 'World'
|
|
2041
|
+
});
|
|
2042
|
+
const cropsQuery = Object.freeze({
|
|
2043
|
+
bool: {
|
|
2044
|
+
must: [
|
|
2045
|
+
matchType(NodeType.Term),
|
|
2046
|
+
matchTermType(TermTermType.crop)
|
|
2047
|
+
]
|
|
2048
|
+
}
|
|
2049
|
+
});
|
|
2050
|
+
const matchAggregatedQuery = matchQuery('aggregated', true);
|
|
2051
|
+
const isNestedKey = (key) => nestedSearchableKeys.includes(key.split('.')[0]);
|
|
2052
|
+
const matchNestedKey = (key, query) => isNestedKey(key) ? {
|
|
2053
|
+
nested: { path: key.split('.')[0], query }
|
|
2054
|
+
} : query;
|
|
2055
|
+
/**
|
|
2056
|
+
* List of fields to return in the search results.
|
|
2057
|
+
*/
|
|
2058
|
+
const searchResultsFields = Object.freeze({
|
|
2059
|
+
[NodeType.Cycle]: [
|
|
2060
|
+
'description', 'dataDescription', 'endDate',
|
|
2061
|
+
'emissionsCount', 'inputsCount', 'productsCount',
|
|
2062
|
+
'site.location', 'site.country.name', 'site.region.name'
|
|
2063
|
+
],
|
|
2064
|
+
[NodeType.Source]: ['bibliography.title', 'bibliography.documentDOI'],
|
|
2065
|
+
[NodeType.ImpactAssessment]: ['emissionsResourceUseCount', 'impactsCount', 'country.name']
|
|
2066
|
+
});
|
|
2067
|
+
/**
|
|
2068
|
+
* List of fields to search in.
|
|
2069
|
+
*/
|
|
2070
|
+
const searchFields = Object.freeze({
|
|
2071
|
+
[NodeType.Cycle]: ['name', 'description', 'dataDescription'],
|
|
2072
|
+
[NodeType.Source]: ['name', 'bibliography.title'],
|
|
2073
|
+
[NodeType.ImpactAssessment]: ['name', 'product.name', 'country.name']
|
|
2074
|
+
});
|
|
2075
|
+
const searchFieldsNested = Object.freeze({
|
|
2076
|
+
[NodeType.Cycle]: [
|
|
2077
|
+
'inputs.term.name',
|
|
2078
|
+
'emissions.term.name',
|
|
2079
|
+
'practices.term.name'
|
|
2080
|
+
],
|
|
2081
|
+
[NodeType.Source]: [],
|
|
2082
|
+
[NodeType.ImpactAssessment]: [
|
|
2083
|
+
'emissionsResourceUse.term.name',
|
|
2084
|
+
'impacts.term.name'
|
|
2085
|
+
]
|
|
2086
|
+
});
|
|
2087
|
+
/**
|
|
2088
|
+
* Specific strict queries per type.
|
|
2089
|
+
*/
|
|
2090
|
+
const searchQueries = {
|
|
2091
|
+
[NodeType.Cycle]: { must: [], must_not: [matchAggregatedQuery] },
|
|
2092
|
+
[NodeType.Source]: { must: [], must_not: [matchAggregatedQuery] }
|
|
2093
|
+
};
|
|
2094
|
+
const searchFiltersKeys = {
|
|
2095
|
+
[NodeType.Cycle]: key => key,
|
|
2096
|
+
[NodeType.Source]: key => key
|
|
2097
|
+
};
|
|
2098
|
+
/* eslint-disable complexity */
|
|
2099
|
+
const searchQuery = (type, query, filters, aggregated) => {
|
|
2100
|
+
const boolQuery = (Object.assign(Object.assign({ must: [
|
|
2101
|
+
matchType(type),
|
|
2102
|
+
aggregated ? matchAggregatedQuery : null
|
|
2103
|
+
].filter(Boolean) }, (query ? {
|
|
2104
|
+
should: [
|
|
2105
|
+
matchPhraseQuery(query, 100, ...searchFields[type]),
|
|
2106
|
+
matchPhrasePrefixQuery(query, 20, ...searchFields[type]),
|
|
2107
|
+
matchBoolPrefixQuery(query, 10, ...searchFields[type]),
|
|
2108
|
+
...searchFieldsNested[type].map(field => matchNestedKey(field, matchBoolPrefixQuery(query, 1, field)))
|
|
2109
|
+
],
|
|
2110
|
+
minimum_should_match: 1
|
|
2111
|
+
} : {})), { must_not: [
|
|
2112
|
+
aggregated ? null : matchAggregatedQuery
|
|
2113
|
+
].filter(Boolean) }));
|
|
2114
|
+
const keys = Object.keys(filters || {}).filter(key => filters[key].length);
|
|
2115
|
+
return {
|
|
2116
|
+
bool: keys.length ? {
|
|
2117
|
+
must: keys.map(key => {
|
|
2118
|
+
const filterKey = searchFiltersKeys[type](key);
|
|
2119
|
+
return {
|
|
2120
|
+
bool: {
|
|
2121
|
+
should: filters[key]
|
|
2122
|
+
.map(value => matchNestedKey(filterKey, matchExactQuery(filterKey, value)))
|
|
2123
|
+
.map(must => {
|
|
2124
|
+
const localQuery = JSON.parse(JSON.stringify(boolQuery));
|
|
2125
|
+
localQuery.must.push(must);
|
|
2126
|
+
return { bool: localQuery };
|
|
2127
|
+
}),
|
|
2128
|
+
minimum_should_match: 1
|
|
2129
|
+
}
|
|
2130
|
+
};
|
|
2131
|
+
})
|
|
2132
|
+
} : boolQuery
|
|
2133
|
+
};
|
|
2134
|
+
};
|
|
2135
|
+
/* eslint-enable complexity */
|
|
2136
|
+
|
|
2137
|
+
const emptySearchResult = () => ({
|
|
2138
|
+
time: 0,
|
|
2139
|
+
count: 0,
|
|
2140
|
+
results: []
|
|
2141
|
+
});
|
|
2142
|
+
const MAX_RESULTS = 10000;
|
|
2143
|
+
const suggestMatchQuery = (query) => [
|
|
2144
|
+
matchPhraseQuery(query, 10),
|
|
2145
|
+
matchQuery('nameNormalized', query, 8),
|
|
2146
|
+
matchPhrasePrefixQuery(query, 2)
|
|
2147
|
+
];
|
|
2148
|
+
const suggestQuery = (query, type, extraQueries = []) => ({
|
|
2149
|
+
bool: {
|
|
2150
|
+
must: extraQueries,
|
|
2151
|
+
should: (type ? [type] : searchableTypes).map(v => ({
|
|
2152
|
+
bool: {
|
|
2153
|
+
must: [matchType(v)],
|
|
2154
|
+
should: suggestMatchQuery(query),
|
|
2155
|
+
minimum_should_match: 1
|
|
2156
|
+
}
|
|
2157
|
+
})),
|
|
2158
|
+
minimum_should_match: 1
|
|
2159
|
+
}
|
|
2160
|
+
});
|
|
2161
|
+
const suggestSourceQuery = (query, fields) => ({
|
|
2162
|
+
bool: {
|
|
2163
|
+
must: [matchType(NodeType.Source)],
|
|
2164
|
+
should: [
|
|
2165
|
+
matchPhraseQuery(query, 100, ...fields),
|
|
2166
|
+
matchPhrasePrefixQuery(query, 20, ...fields),
|
|
2167
|
+
matchBoolPrefixQuery(query, 10, ...fields)
|
|
2168
|
+
],
|
|
2169
|
+
minimum_should_match: 1
|
|
2170
|
+
}
|
|
2171
|
+
});
|
|
2172
|
+
class HeSearchService {
|
|
2173
|
+
constructor(http, commonService) {
|
|
2174
|
+
this.http = http;
|
|
2175
|
+
this.commonService = commonService;
|
|
2176
|
+
}
|
|
2177
|
+
search(params) {
|
|
2178
|
+
return this.http.post(`${this.commonService.apiBaseUrl}/search`, params)
|
|
2179
|
+
.pipe(catchError(() => of(emptySearchResult())))
|
|
2180
|
+
.toPromise();
|
|
2181
|
+
}
|
|
2182
|
+
count(params = {}) {
|
|
2183
|
+
return this.http.post(`${this.commonService.apiBaseUrl}/count`, params).toPromise().catch(() => 0);
|
|
2184
|
+
}
|
|
2185
|
+
get$(type, id) {
|
|
2186
|
+
return this.http.post(`${this.commonService.apiBaseUrl}/search`, {
|
|
2187
|
+
limit: 1,
|
|
2188
|
+
query: {
|
|
2283
2189
|
bool: {
|
|
2284
2190
|
must: [{ match: { '@type': type } }, { match: { '@id': id } }]
|
|
2285
2191
|
}
|
|
@@ -2479,6 +2385,8 @@ const toCsv$1 = (lines) => json2csvAsync(lines.map(formatLine).filter(data => Ob
|
|
|
2479
2385
|
emptyFieldValue: ''
|
|
2480
2386
|
});
|
|
2481
2387
|
|
|
2388
|
+
const primaryProduct = ({ products }) => (products || []).find(({ primary }) => primary);
|
|
2389
|
+
|
|
2482
2390
|
const linkTypeEnabled = (type) => [
|
|
2483
2391
|
NodeType.Cycle,
|
|
2484
2392
|
NodeType.ImpactAssessment,
|
|
@@ -2797,11 +2705,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
2797
2705
|
type: Output
|
|
2798
2706
|
}] } });
|
|
2799
2707
|
|
|
2800
|
-
var
|
|
2801
|
-
(function (
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
})(
|
|
2708
|
+
var DiffsDisplayType;
|
|
2709
|
+
(function (DiffsDisplayType) {
|
|
2710
|
+
DiffsDisplayType["diffs"] = "diffs";
|
|
2711
|
+
DiffsDisplayType["sideBySide"] = "side-by-side";
|
|
2712
|
+
})(DiffsDisplayType || (DiffsDisplayType = {}));
|
|
2805
2713
|
|
|
2806
2714
|
const omit = require('lodash.omit');
|
|
2807
2715
|
const ignoreProperties = [
|
|
@@ -2817,9 +2725,9 @@ const customDiff = create({
|
|
|
2817
2725
|
class NodeDiffsComponent {
|
|
2818
2726
|
constructor(nodeService) {
|
|
2819
2727
|
this.nodeService = nodeService;
|
|
2820
|
-
this.displayType =
|
|
2728
|
+
this.displayType = DiffsDisplayType.diffs;
|
|
2821
2729
|
this.diffsLoaded = new EventEmitter();
|
|
2822
|
-
this.
|
|
2730
|
+
this.DiffsDisplayType = DiffsDisplayType;
|
|
2823
2731
|
this.loading = true;
|
|
2824
2732
|
}
|
|
2825
2733
|
ngOnInit() {
|
|
@@ -2842,7 +2750,7 @@ class NodeDiffsComponent {
|
|
|
2842
2750
|
}
|
|
2843
2751
|
}
|
|
2844
2752
|
NodeDiffsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: NodeDiffsComponent, deps: [{ token: HeNodeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2845
|
-
NodeDiffsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: NodeDiffsComponent, selector: "he-node-diffs", inputs: { data: "data", id: "id", type: "type", displayType: "displayType" }, outputs: { diffsLoaded: "diffsLoaded" }, ngImport: i0, template: "<div *ngIf=\"loading\" class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n</div>\n\n<ng-container *ngIf=\"left && right\">\n <ng-container [ngSwitch]=\"displayType\">\n <div *ngSwitchCase=\"
|
|
2753
|
+
NodeDiffsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: NodeDiffsComponent, selector: "he-node-diffs", inputs: { data: "data", id: "id", type: "type", displayType: "displayType" }, outputs: { diffsLoaded: "diffsLoaded" }, ngImport: i0, template: "<div *ngIf=\"loading\" class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n</div>\n\n<ng-container *ngIf=\"left && right\">\n <ng-container [ngSwitch]=\"displayType\">\n <div *ngSwitchCase=\"DiffsDisplayType.diffs\" [innerHTML]=\"diffHtml\"></div>\n\n <div *ngSwitchCase=\"DiffsDisplayType.sideBySide\" class=\"columns\">\n <div class=\"column is-6\">\n <pre class=\"has-background-black has-text-white\"><code>{{left | json}}</code></pre>\n </div>\n <div class=\"column is-6\">\n <pre class=\"has-background-black has-text-white\"><code>{{right | json}}</code></pre>\n </div>\n </div>\n </ng-container>\n</ng-container>\n", styles: [""], components: [{ type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }], pipes: { "json": i3.JsonPipe } });
|
|
2846
2754
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: NodeDiffsComponent, decorators: [{
|
|
2847
2755
|
type: Component,
|
|
2848
2756
|
args: [{
|
|
@@ -3858,315 +3766,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
3858
3766
|
}]
|
|
3859
3767
|
}] });
|
|
3860
3768
|
|
|
3861
|
-
|
|
3862
|
-
const
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
const siteDefaultLocation = ({ region, country }) => {
|
|
3867
|
-
const markers = [
|
|
3868
|
-
region ? createMarker(termLocation(region), termLocationName(region).name, undefined, 20) : undefined,
|
|
3869
|
-
country ? createMarker(termLocation(country), termLocationName(country).name, undefined, 40) : undefined
|
|
3870
|
-
].filter(Boolean);
|
|
3871
|
-
return (markers.length ? markers[0] : undefined);
|
|
3872
|
-
};
|
|
3873
|
-
const siteMarker = (site) => createMarker(site ? siteLocation(site) : undefined, site.name);
|
|
3874
|
-
const sitePolygon = ({ boundary }) => (boundary ? polygonsFromFeature(boundary) : undefined);
|
|
3875
|
-
const regions = (sites) => unique(sites.map(({ country, region }) => region ? region['@id'] : (country ? country['@id'] : null)).filter(Boolean));
|
|
3876
|
-
const defaultCenter = { lat: 0, lng: 0 };
|
|
3877
|
-
class SitesMapsComponent {
|
|
3878
|
-
constructor(nodeService) {
|
|
3879
|
-
this.nodeService = nodeService;
|
|
3880
|
-
this.loaded = false;
|
|
3881
|
-
this.loadPolygons = true;
|
|
3882
|
-
this.sites = [];
|
|
3883
|
-
this.nodes = [];
|
|
3884
|
-
this.center = defaultCenter;
|
|
3885
|
-
this.zoom = 2;
|
|
3886
|
-
this.showNotice = true;
|
|
3887
|
-
this.googleLoaded = false;
|
|
3888
|
-
this.showNoLocation = false;
|
|
3889
|
-
}
|
|
3890
|
-
ngOnInit() {
|
|
3891
|
-
waitFor('google', () => {
|
|
3892
|
-
this.googleLoaded = true;
|
|
3893
|
-
setTimeout(() => !this.loaded && this.loadData());
|
|
3894
|
-
});
|
|
3895
|
-
}
|
|
3896
|
-
ngAfterViewInit() {
|
|
3897
|
-
return this.googleLoaded && this.loadData();
|
|
3898
|
-
}
|
|
3899
|
-
loadData() {
|
|
3900
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3901
|
-
// loaded data as geojson
|
|
3902
|
-
this.map.googleMap.data.setStyle(() => (Object.assign(Object.assign({}, strokeStyle), { strokeOpacity: 0.1 })));
|
|
3903
|
-
const sites = yield this.getSites();
|
|
3904
|
-
const markers = this.addSiteMarkers(sites);
|
|
3905
|
-
// add the site.boundary if exist
|
|
3906
|
-
const polygons = sites.flatMap(sitePolygon).filter(Boolean);
|
|
3907
|
-
polygons.map(polygon => polygon === null || polygon === void 0 ? void 0 : polygon.setMap(this.map.googleMap));
|
|
3908
|
-
this.loaded = true;
|
|
3909
|
-
// add the default site polygons from GADM region if any
|
|
3910
|
-
const termPolygons = (yield Promise.all(regions(sites).map(v => this.addTermsPolygons(v)))).flat();
|
|
3911
|
-
this.showNoLocation = markers.length === 0 && polygons.length === 0 && termPolygons.length === 0;
|
|
3912
|
-
return markers.length ?
|
|
3913
|
-
this.centerMarker(markers[0]) :
|
|
3914
|
-
this.centerPolygons(polygons.length ? polygons : termPolygons);
|
|
3915
|
-
});
|
|
3916
|
-
}
|
|
3917
|
-
addMarkers(markers, cluster = false) {
|
|
3918
|
-
return cluster ?
|
|
3919
|
-
new MarkerClusterer(this.map.googleMap, markers, { imagePath: clustererImage }) :
|
|
3920
|
-
markers.map(marker => marker.setMap(this.map.googleMap));
|
|
3921
|
-
}
|
|
3922
|
-
addTermsPolygons(id) {
|
|
3923
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3924
|
-
return this.loadPolygons ? yield this.termPolygons(id) : [];
|
|
3925
|
-
});
|
|
3926
|
-
}
|
|
3927
|
-
centerMarker(marker) {
|
|
3928
|
-
const center = marker.getPosition();
|
|
3929
|
-
this.center = center ? { lat: center.lat(), lng: center.lng() } : defaultCenter;
|
|
3930
|
-
}
|
|
3931
|
-
centerPolygons(polygons) {
|
|
3932
|
-
try {
|
|
3933
|
-
return polygons.length ? this.map.googleMap.fitBounds(polygonBounds(polygons)) : null;
|
|
3934
|
-
}
|
|
3935
|
-
catch (err) {
|
|
3936
|
-
if (polygons.length) {
|
|
3937
|
-
this.map.googleMap.fitBounds(polygonBounds(polygons[0]));
|
|
3938
|
-
this.zoom = 3;
|
|
3939
|
-
}
|
|
3940
|
-
}
|
|
3941
|
-
}
|
|
3942
|
-
addSiteMarkers(sites) {
|
|
3943
|
-
const siteMarkers = sites.map(siteMarker).filter(Boolean);
|
|
3944
|
-
const markers = siteMarkers.length ? siteMarkers : sites.map(siteDefaultLocation).filter(Boolean);
|
|
3945
|
-
this.addMarkers(markers, !!siteMarkers.length);
|
|
3946
|
-
return markers;
|
|
3947
|
-
}
|
|
3948
|
-
loadSite(node) {
|
|
3949
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3950
|
-
// means the site was already downloaded
|
|
3951
|
-
return 'schemaVersion' in node ? node : yield this.nodeService.get(node);
|
|
3952
|
-
});
|
|
3953
|
-
}
|
|
3954
|
-
siteData(node) {
|
|
3955
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3956
|
-
return [
|
|
3957
|
-
NodeType.Site,
|
|
3958
|
-
NodeType.Organisation
|
|
3959
|
-
].includes(node.type) ? node : (isSite(node) ?
|
|
3960
|
-
this.loadSite(node) : ('site' in node && isSite(node.site) ?
|
|
3961
|
-
this.loadSite(node.site) :
|
|
3962
|
-
this.siteData(yield this.loadSite(node))));
|
|
3963
|
-
});
|
|
3964
|
-
}
|
|
3965
|
-
getSites() {
|
|
3966
|
-
const nodes = this.sites && this.sites.length ? this.sites : this.nodes;
|
|
3967
|
-
return Promise.all(nodes.map(node => this.siteData(node)));
|
|
3968
|
-
}
|
|
3969
|
-
termPolygons(id) {
|
|
3970
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3971
|
-
try {
|
|
3972
|
-
const data = yield this.nodeService.downloadRaw(`${baseUrl()}/gadm/${id}.geojson`);
|
|
3973
|
-
const polygons = polygonsFromFeature(data);
|
|
3974
|
-
polygons.map(polygon => polygon.setMap(this.map.googleMap));
|
|
3975
|
-
return polygons;
|
|
3976
|
-
}
|
|
3977
|
-
catch (_err) {
|
|
3978
|
-
// ignore error if the file does not exist
|
|
3979
|
-
return [];
|
|
3980
|
-
}
|
|
3981
|
-
});
|
|
3982
|
-
}
|
|
3983
|
-
}
|
|
3984
|
-
SitesMapsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMapsComponent, deps: [{ token: HeNodeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3985
|
-
SitesMapsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMapsComponent, selector: "he-sites-maps", inputs: { loadPolygons: "loadPolygons", sites: "sites", nodes: "nodes", center: "center", zoom: "zoom", showNotice: "showNotice" }, viewQueries: [{ propertyName: "map", first: true, predicate: GoogleMap, descendants: true }], ngImport: i0, template: "<google-map *ngIf=\"googleLoaded\"\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"zoom\"\n [center]=\"center\"\n></google-map>\n\n<p *ngIf=\"showNotice\" class=\"mt-2 is-italic is-size-7\">The information provided might not be complete</p>\n\n<div class=\"no-location has-text-center has-text-light\" *ngIf=\"showNoLocation\">\n <span>No precise location data</span>\n</div>\n", styles: [":host{display:block;height:100%;position:relative;width:100%}.no-location{background-color:#0000004d;left:0;height:100%;position:absolute;top:0;width:100%;z-index:9}.no-location>span{display:inline-block;margin-top:12%}\n"], components: [{ type: i1$2.GoogleMap, selector: "google-map", inputs: ["height", "width", "center", "zoom", "options", "mapTypeId"], outputs: ["authFailure", "boundsChanged", "centerChanged", "mapClick", "mapDblclick", "mapDrag", "mapDragend", "mapDragstart", "headingChanged", "idle", "maptypeidChanged", "mapMousemove", "mapMouseout", "mapMouseover", "projectionChanged", "mapRightclick", "tilesloaded", "tiltChanged", "zoomChanged"], exportAs: ["googleMap"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
3986
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMapsComponent, decorators: [{
|
|
3987
|
-
type: Component,
|
|
3988
|
-
args: [{
|
|
3989
|
-
selector: 'he-sites-maps',
|
|
3990
|
-
templateUrl: './sites-maps.component.html',
|
|
3991
|
-
styleUrls: ['./sites-maps.component.scss']
|
|
3992
|
-
}]
|
|
3993
|
-
}], ctorParameters: function () { return [{ type: HeNodeService }]; }, propDecorators: { map: [{
|
|
3994
|
-
type: ViewChild,
|
|
3995
|
-
args: [GoogleMap]
|
|
3996
|
-
}], loadPolygons: [{
|
|
3997
|
-
type: Input
|
|
3998
|
-
}], sites: [{
|
|
3999
|
-
type: Input
|
|
4000
|
-
}], nodes: [{
|
|
4001
|
-
type: Input
|
|
4002
|
-
}], center: [{
|
|
4003
|
-
type: Input
|
|
4004
|
-
}], zoom: [{
|
|
4005
|
-
type: Input
|
|
4006
|
-
}], showNotice: [{
|
|
4007
|
-
type: Input
|
|
4008
|
-
}] } });
|
|
4009
|
-
|
|
4010
|
-
const maxAreaSize = 5000;
|
|
4011
|
-
const siteTooBig = ({ area }) => area && area / 100 > maxAreaSize;
|
|
4012
|
-
const hasMultipleValues = (values) => (values || []).length > 1;
|
|
4013
|
-
const weighedAverage = ({ value, depthLower, depthUpper }) => value.reduce((prev, curr, index) => prev + (curr * (depthLower[index] - depthUpper[index])), 0) /
|
|
4014
|
-
value.reduce((prev, _curr, index) => prev + (depthLower[index] - depthUpper[index]), 0);
|
|
4015
|
-
const measurementValue = ({ value, depthLower, depthUpper }) => hasMultipleValues(value) && hasMultipleValues(depthLower) && hasMultipleValues(depthUpper) ?
|
|
4016
|
-
weighedAverage({ value, depthLower, depthUpper }) :
|
|
4017
|
-
propertyValue$1(value);
|
|
4018
|
-
|
|
4019
|
-
class SitesMeasurementsLogsComponent {
|
|
4020
|
-
constructor(searchService, nodeService) {
|
|
4021
|
-
this.searchService = searchService;
|
|
4022
|
-
this.nodeService = nodeService;
|
|
4023
|
-
this.originalValues = [];
|
|
4024
|
-
this.recalculatedValues = [];
|
|
4025
|
-
this.loading = true;
|
|
4026
|
-
this.NodeType = NodeType;
|
|
4027
|
-
this.models = [];
|
|
4028
|
-
this.measurements = [];
|
|
4029
|
-
}
|
|
4030
|
-
ngOnInit() {
|
|
4031
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
4032
|
-
this.logsUrl = this.nodeService.nodeLogsUrl(this.node);
|
|
4033
|
-
this.logs = yield this.nodeService.getModelsLog(this.node);
|
|
4034
|
-
const { results: measurements } = yield this.searchService.search({
|
|
4035
|
-
fields: ['@type', '@id', 'name'],
|
|
4036
|
-
limit: 1000,
|
|
4037
|
-
query: {
|
|
4038
|
-
bool: {
|
|
4039
|
-
must: [
|
|
4040
|
-
matchType(NodeType.Term),
|
|
4041
|
-
matchTermType(TermTermType.measurement)
|
|
4042
|
-
]
|
|
4043
|
-
}
|
|
4044
|
-
}
|
|
4045
|
-
});
|
|
4046
|
-
this.measurements = measurements;
|
|
4047
|
-
this.loading = false;
|
|
4048
|
-
});
|
|
4049
|
-
}
|
|
4050
|
-
get node() {
|
|
4051
|
-
return Object.assign(Object.assign({}, this.site), { dataState: DataState.recalculated });
|
|
4052
|
-
}
|
|
4053
|
-
}
|
|
4054
|
-
SitesMeasurementsLogsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsLogsComponent, deps: [{ token: HeSearchService }, { token: HeNodeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4055
|
-
SitesMeasurementsLogsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMeasurementsLogsComponent, selector: "he-sites-measurements-logs", inputs: { site: "site", originalValues: "originalValues", recalculatedValues: "recalculatedValues" }, ngImport: i0, template: "<he-node-logs-models *ngIf=\"!loading; else loader\"\n [logsUrl]=\"logsUrl\"\n [nodeType]=\"NodeType.Site\"\n [originalValues]=\"originalValues\"\n [recalculatedValues]=\"recalculatedValues\"\n [terms]=\"measurements\"\n [logs]=\"logs\"\n filteredType=\"Measurement\"\n></he-node-logs-models>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [""], components: [{ type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: ["nodeType", "nodeKey", "logsUrl", "originalValues", "recalculatedValues", "terms", "logs", "filteredType"] }, { type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
4056
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsLogsComponent, decorators: [{
|
|
4057
|
-
type: Component,
|
|
4058
|
-
args: [{
|
|
4059
|
-
selector: 'he-sites-measurements-logs',
|
|
4060
|
-
templateUrl: './sites-measurements-logs.component.html',
|
|
4061
|
-
styleUrls: ['./sites-measurements-logs.component.scss']
|
|
4062
|
-
}]
|
|
4063
|
-
}], ctorParameters: function () { return [{ type: HeSearchService }, { type: HeNodeService }]; }, propDecorators: { site: [{
|
|
4064
|
-
type: Input
|
|
4065
|
-
}], originalValues: [{
|
|
4066
|
-
type: Input
|
|
4067
|
-
}], recalculatedValues: [{
|
|
4068
|
-
type: Input
|
|
4069
|
-
}] } });
|
|
4070
|
-
|
|
4071
|
-
const orderBy$1 = require('lodash.orderby');
|
|
4072
|
-
var View$1;
|
|
4073
|
-
(function (View) {
|
|
4074
|
-
View["table"] = "table";
|
|
4075
|
-
View["logs"] = "logs";
|
|
4076
|
-
})(View$1 || (View$1 = {}));
|
|
4077
|
-
class SitesMeasurementsComponent {
|
|
4078
|
-
constructor() {
|
|
4079
|
-
this.originalValues = [];
|
|
4080
|
-
this.sites = [];
|
|
4081
|
-
this.showDownload = false;
|
|
4082
|
-
this.View = View$1;
|
|
4083
|
-
this.selectedView = View$1.table;
|
|
4084
|
-
this.maxAreaSize = maxAreaSize;
|
|
4085
|
-
this.siteTooBig = siteTooBig;
|
|
4086
|
-
this.defaultLabel = defaultLabel;
|
|
4087
|
-
this.measurementValue = measurementValue;
|
|
4088
|
-
this.measurements = [];
|
|
4089
|
-
}
|
|
4090
|
-
ngOnChanges(changes) {
|
|
4091
|
-
if ('sites' in changes) {
|
|
4092
|
-
return this.update();
|
|
4093
|
-
}
|
|
4094
|
-
if ('dataState' in changes) {
|
|
4095
|
-
this.selectedView = View$1.table;
|
|
4096
|
-
}
|
|
4097
|
-
}
|
|
4098
|
-
trackById(_index, item) {
|
|
4099
|
-
return item['@id'];
|
|
4100
|
-
}
|
|
4101
|
-
get isOriginal() {
|
|
4102
|
-
return this.dataState === DataState.original;
|
|
4103
|
-
}
|
|
4104
|
-
update() {
|
|
4105
|
-
const measurementsPerSite = groupNodesByTerm(this.sites, 'measurements', this.originalValues);
|
|
4106
|
-
this.measurements = orderBy$1(grouppedKeys(measurementsPerSite), ['key'], ['asc']);
|
|
4107
|
-
}
|
|
4108
|
-
togglePopover(popover, context) {
|
|
4109
|
-
return popover.isOpen() ? popover.close() : popover.open(context);
|
|
4110
|
-
}
|
|
4111
|
-
get showAreaTooBig() {
|
|
4112
|
-
return this.dataState === DataState.recalculated && (this.sites || []).some(siteTooBig);
|
|
4113
|
-
}
|
|
4114
|
-
}
|
|
4115
|
-
SitesMeasurementsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4116
|
-
SitesMeasurementsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMeasurementsComponent, selector: "he-sites-measurements", inputs: { originalValues: "originalValues", sites: "sites", dataState: "dataState" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"measurements.length; else emptyTable\">\n <div class=\"columns is-variable is-2 m-0\">\n <div class=\"column is-hidden-mobile\"></div>\n <div class=\"column is-narrow\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.table\" (click)=\"selectedView = View.table\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"list\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Table view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"!isOriginal && sites.length === 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.logs\" (click)=\"selectedView = View.logs\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"calculator\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Recalculations logs</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"px-3 pb-3\" [class.is-hidden]=\"selectedView !== View.table\">\n <div class=\"has-text-right mb-2\">\n <button class=\"button is-dark is-outlined is-small\" (click)=\"showDownload = true\">\n <fa-icon icon=\"download\"></fa-icon>\n <span class=\"pl-2\">Download (CSV)</span>\n </button>\n </div>\n\n <div class=\"table-container data-table-container mb-1\">\n <table class=\"table is-narrow data-table has-children-{{measurements.length}}\">\n <thead>\n <tr>\n <th class=\"width-auto\"></th>\n <th *ngFor=\"let measurement of measurements\"\n [attr.title]=\"measurement.value.term.name\"\n >\n <he-node-link [node]=\"measurement.value.term\">\n <span>{{measurement.value.term.name | ellipsis:30}}</span>\n </he-node-link>\n </th>\n </tr>\n <tr>\n <th class=\"width-auto\"></th>\n <th *ngFor=\"let measurement of measurements\"\n [attr.title]=\"measurement.value.term.units\"\n >{{measurement.value.term.units}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let site of sites; trackBy: trackById; let i = index\">\n <td class=\"width-auto\" [attr.title]=\"defaultLabel(site)\">\n <he-node-link [node]=\"site\">\n <span class=\"is-nowrap has-text-ellipsis\">{{i + 1}}. {{defaultLabel(site)}}</span>\n </he-node-link>\n </td>\n <td class=\"is-nowrap\" *ngFor=\"let measurement of measurements\">\n <span *ngIf=\"measurement.value.values[site['@id']]\"\n class=\"trigger-popover\"\n [ngbPopover]=\"details\" [autoClose]=\"'outside'\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"togglePopover(p, { data: measurement.value.values[site['@id']], site: site, key: 'measurements' })\"\n >\n <span pointer>{{measurementValue(measurement.value.values[site['@id']]) | precision:3 | default:'-'}}</span>\n <he-blank-node-state class=\"ml-1\"\n [node]=\"measurement.value.values[site['@id']].nodes[0]\"\n key=\"value\"\n ></he-blank-node-state>\n </span>\n <span *ngIf=\"!measurement.value.values[site['@id']]\">\n <span>-</span>\n <sup class=\"pl-1\" *ngIf=\"siteTooBig(site)\">(1)</sup>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <he-blank-node-state-notice [dataState]=\"dataState\"></he-blank-node-state-notice>\n\n <p class=\"is-size-7 is-italic\" *ngIf=\"showAreaTooBig\">\n (1) This region is >{{maxAreaSize}}km2 and is too large to reliably gap fill Measurements.\n </p>\n </div>\n\n <he-sites-measurements-logs *ngIf=\"selectedView === View.logs && !isOriginal\"\n [site]=\"sites[0]\"\n [originalValues]=\"originalValues[0].measurements\"\n [recalculatedValues]=\"sites[0].measurements\"\n ></he-sites-measurements-logs>\n</ng-container>\n\n<he-node-csv-export-confirm *ngIf=\"showDownload\"\n [nodes]=\"sites\" filename=\"site-measurements.csv\" [isUpload]=\"false\"\n [headerKeys]=\"['site.id', 'site.@id', 'site.measurements.']\"\n (closed)=\"showDownload = false\"\n></he-node-csv-export-confirm>\n\n<ng-template #emptyTable>\n <div class=\"panel-block\">\n <span>No data</span>\n </div>\n</ng-template>\n\n<ng-template #emptyValue>\n <span>-</span>\n</ng-template>\n\n<ng-template #details let-node=\"site\" let-data=\"data\" let-key=\"key\">\n <p><b>{{node.name}}</b></p>\n <he-node-value-details\n [data]=\"data\" [nodeType]=\"node['@type']\" [dataKey]=\"key\"\n ></he-node-value-details>\n</ng-template>\n", styles: ["fa-icon{display:inline-block;width:10px}\n"], components: [{ type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink"] }, { type: BlankNodeStateComponent, selector: "he-blank-node-state", inputs: ["nodeType", "dataKey", "key", "node", "state"] }, { type: BlankNodeStateNoticeComponent, selector: "he-blank-node-state-notice", inputs: ["dataState", "showDeleted"] }, { type: SitesMeasurementsLogsComponent, selector: "he-sites-measurements-logs", inputs: ["site", "originalValues", "recalculatedValues"] }, { type: NodeCsvExportConfirmComponent, selector: "he-node-csv-export-confirm", inputs: ["nodes", "filename", "headerKeys", "extension", "isUpload"], outputs: ["closed"] }, { type: NodeValueDetailsComponent, selector: "he-node-value-details", inputs: ["data", "nodeType", "dataKey"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay", "ngbPopover", "popoverTitle"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }], pipes: { "ellipsis": EllipsisPipe, "default": DefaultPipe, "precision": PrecisionPipe } });
|
|
4117
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsComponent, decorators: [{
|
|
4118
|
-
type: Component,
|
|
4119
|
-
args: [{
|
|
4120
|
-
selector: 'he-sites-measurements',
|
|
4121
|
-
templateUrl: './sites-measurements.component.html',
|
|
4122
|
-
styleUrls: ['./sites-measurements.component.scss']
|
|
4123
|
-
}]
|
|
4124
|
-
}], propDecorators: { originalValues: [{
|
|
4125
|
-
type: Input
|
|
4126
|
-
}], sites: [{
|
|
4127
|
-
type: Input
|
|
4128
|
-
}], dataState: [{
|
|
4129
|
-
type: Input
|
|
4130
|
-
}] } });
|
|
4131
|
-
|
|
4132
|
-
const components$2 = [
|
|
4133
|
-
SitesMapsComponent,
|
|
4134
|
-
SitesMeasurementsComponent,
|
|
4135
|
-
SitesMeasurementsLogsComponent
|
|
4136
|
-
];
|
|
4137
|
-
class HeSitesModule {
|
|
4138
|
-
}
|
|
4139
|
-
HeSitesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
4140
|
-
HeSitesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, declarations: [SitesMapsComponent,
|
|
4141
|
-
SitesMeasurementsComponent,
|
|
4142
|
-
SitesMeasurementsLogsComponent], imports: [CommonModule, ReactiveFormsModule,
|
|
4143
|
-
HeCommonModule,
|
|
4144
|
-
HeNodeModule], exports: [SitesMapsComponent,
|
|
4145
|
-
SitesMeasurementsComponent,
|
|
4146
|
-
SitesMeasurementsLogsComponent] });
|
|
4147
|
-
HeSitesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, imports: [[
|
|
4148
|
-
CommonModule, ReactiveFormsModule,
|
|
4149
|
-
HeCommonModule,
|
|
4150
|
-
HeNodeModule
|
|
4151
|
-
]] });
|
|
4152
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, decorators: [{
|
|
4153
|
-
type: NgModule,
|
|
4154
|
-
args: [{
|
|
4155
|
-
declarations: components$2,
|
|
4156
|
-
exports: components$2,
|
|
4157
|
-
imports: [
|
|
4158
|
-
CommonModule, ReactiveFormsModule,
|
|
4159
|
-
HeCommonModule,
|
|
4160
|
-
HeNodeModule
|
|
4161
|
-
]
|
|
4162
|
-
}]
|
|
4163
|
-
}] });
|
|
4164
|
-
|
|
4165
|
-
/* eslint-disable complexity */
|
|
4166
|
-
const mapErrorMessage = 'does not contain latitude and longitude';
|
|
4167
|
-
const parseDataPath = (dataPath) => {
|
|
4168
|
-
const [_, ...paths] = dataPath.split('.');
|
|
4169
|
-
return paths.map(path => ({ path, label: keyToLabel(path.replace(/\[\d+\]/g, '')) }));
|
|
3769
|
+
/* eslint-disable complexity */
|
|
3770
|
+
const mapErrorMessage = 'does not contain latitude and longitude';
|
|
3771
|
+
const parseDataPath = (dataPath) => {
|
|
3772
|
+
const [_, ...paths] = dataPath.split('.');
|
|
3773
|
+
return paths.map(path => ({ path, label: keyToLabel(path.replace(/\[\d+\]/g, '')) }));
|
|
4170
3774
|
};
|
|
4171
3775
|
const contactUsEmail = 'community@hestia.earth';
|
|
4172
3776
|
const externalLink = (href, text) => `<a href="${href}" target="_blank">${text}</a>`;
|
|
@@ -4874,6 +4478,310 @@ const calculateCycleStartDate = (properties, property) => {
|
|
|
4874
4478
|
return moment(endDate.value).locale('en-gb').subtract(cycleDuration.value, 'days').format('YYYY-MM-DD');
|
|
4875
4479
|
};
|
|
4876
4480
|
|
|
4481
|
+
const isSite = ({ '@type': type, '@id': id }) => type === NodeType.Site && !!id;
|
|
4482
|
+
const siteLocation = ({ latitude, longitude }) => latitude && longitude ? ({
|
|
4483
|
+
lat: latitude,
|
|
4484
|
+
lng: longitude
|
|
4485
|
+
}) : undefined;
|
|
4486
|
+
const siteDefaultLocation = ({ region, country }) => {
|
|
4487
|
+
const markers = [
|
|
4488
|
+
region ? createMarker(termLocation(region), termLocationName(region).name, undefined, 20) : undefined,
|
|
4489
|
+
country ? createMarker(termLocation(country), termLocationName(country).name, undefined, 40) : undefined
|
|
4490
|
+
].filter(Boolean);
|
|
4491
|
+
return (markers.length ? markers[0] : undefined);
|
|
4492
|
+
};
|
|
4493
|
+
const siteMarker = (site) => createMarker(site ? siteLocation(site) : undefined, site.name);
|
|
4494
|
+
const sitePolygon = ({ boundary }) => (boundary ? polygonsFromFeature(boundary) : undefined);
|
|
4495
|
+
const regions = (sites) => unique(sites.map(({ country, region }) => region ? region['@id'] : (country ? country['@id'] : null)).filter(Boolean));
|
|
4496
|
+
const defaultCenter = { lat: 0, lng: 0 };
|
|
4497
|
+
class SitesMapsComponent {
|
|
4498
|
+
constructor(nodeService) {
|
|
4499
|
+
this.nodeService = nodeService;
|
|
4500
|
+
this.loaded = false;
|
|
4501
|
+
this.loadPolygons = true;
|
|
4502
|
+
this.sites = [];
|
|
4503
|
+
this.nodes = [];
|
|
4504
|
+
this.center = defaultCenter;
|
|
4505
|
+
this.zoom = 2;
|
|
4506
|
+
this.showNotice = true;
|
|
4507
|
+
this.googleLoaded = false;
|
|
4508
|
+
this.showNoLocation = false;
|
|
4509
|
+
}
|
|
4510
|
+
ngOnInit() {
|
|
4511
|
+
waitFor('google', () => {
|
|
4512
|
+
this.googleLoaded = true;
|
|
4513
|
+
setTimeout(() => !this.loaded && this.loadData());
|
|
4514
|
+
});
|
|
4515
|
+
}
|
|
4516
|
+
ngAfterViewInit() {
|
|
4517
|
+
return this.googleLoaded && this.loadData();
|
|
4518
|
+
}
|
|
4519
|
+
loadData() {
|
|
4520
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4521
|
+
// loaded data as geojson
|
|
4522
|
+
this.map.googleMap.data.setStyle(() => (Object.assign(Object.assign({}, strokeStyle), { strokeOpacity: 0.1 })));
|
|
4523
|
+
const sites = yield this.getSites();
|
|
4524
|
+
const markers = this.addSiteMarkers(sites);
|
|
4525
|
+
// add the site.boundary if exist
|
|
4526
|
+
const polygons = sites.flatMap(sitePolygon).filter(Boolean);
|
|
4527
|
+
polygons.map(polygon => polygon === null || polygon === void 0 ? void 0 : polygon.setMap(this.map.googleMap));
|
|
4528
|
+
this.loaded = true;
|
|
4529
|
+
// add the default site polygons from GADM region if any
|
|
4530
|
+
const termPolygons = (yield Promise.all(regions(sites).map(v => this.addTermsPolygons(v)))).flat();
|
|
4531
|
+
this.showNoLocation = markers.length === 0 && polygons.length === 0 && termPolygons.length === 0;
|
|
4532
|
+
return markers.length ?
|
|
4533
|
+
this.centerMarker(markers[0]) :
|
|
4534
|
+
this.centerPolygons(polygons.length ? polygons : termPolygons);
|
|
4535
|
+
});
|
|
4536
|
+
}
|
|
4537
|
+
addMarkers(markers, cluster = false) {
|
|
4538
|
+
return cluster ?
|
|
4539
|
+
new MarkerClusterer(this.map.googleMap, markers, { imagePath: clustererImage }) :
|
|
4540
|
+
markers.map(marker => marker.setMap(this.map.googleMap));
|
|
4541
|
+
}
|
|
4542
|
+
addTermsPolygons(id) {
|
|
4543
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4544
|
+
return this.loadPolygons ? yield this.termPolygons(id) : [];
|
|
4545
|
+
});
|
|
4546
|
+
}
|
|
4547
|
+
centerMarker(marker) {
|
|
4548
|
+
const center = marker.getPosition();
|
|
4549
|
+
this.center = center ? { lat: center.lat(), lng: center.lng() } : defaultCenter;
|
|
4550
|
+
}
|
|
4551
|
+
centerPolygons(polygons) {
|
|
4552
|
+
try {
|
|
4553
|
+
return polygons.length ? this.map.googleMap.fitBounds(polygonBounds(polygons)) : null;
|
|
4554
|
+
}
|
|
4555
|
+
catch (err) {
|
|
4556
|
+
if (polygons.length) {
|
|
4557
|
+
this.map.googleMap.fitBounds(polygonBounds(polygons[0]));
|
|
4558
|
+
this.zoom = 3;
|
|
4559
|
+
}
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
addSiteMarkers(sites) {
|
|
4563
|
+
const siteMarkers = sites.map(siteMarker).filter(Boolean);
|
|
4564
|
+
const markers = siteMarkers.length ? siteMarkers : sites.map(siteDefaultLocation).filter(Boolean);
|
|
4565
|
+
this.addMarkers(markers, !!siteMarkers.length);
|
|
4566
|
+
return markers;
|
|
4567
|
+
}
|
|
4568
|
+
loadSite(node) {
|
|
4569
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4570
|
+
// means the site was already downloaded
|
|
4571
|
+
return 'schemaVersion' in node ? node : yield this.nodeService.get(node);
|
|
4572
|
+
});
|
|
4573
|
+
}
|
|
4574
|
+
siteData(node) {
|
|
4575
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4576
|
+
return [
|
|
4577
|
+
NodeType.Site,
|
|
4578
|
+
NodeType.Organisation
|
|
4579
|
+
].includes(node.type) ? node : (isSite(node) ?
|
|
4580
|
+
this.loadSite(node) : ('site' in node && isSite(node.site) ?
|
|
4581
|
+
this.loadSite(node.site) :
|
|
4582
|
+
this.siteData(yield this.loadSite(node))));
|
|
4583
|
+
});
|
|
4584
|
+
}
|
|
4585
|
+
getSites() {
|
|
4586
|
+
const nodes = this.sites && this.sites.length ? this.sites : this.nodes;
|
|
4587
|
+
return Promise.all(nodes.map(node => this.siteData(node)));
|
|
4588
|
+
}
|
|
4589
|
+
termPolygons(id) {
|
|
4590
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4591
|
+
try {
|
|
4592
|
+
const data = yield this.nodeService.downloadRaw(`${baseUrl()}/gadm/${id}.geojson`);
|
|
4593
|
+
const polygons = polygonsFromFeature(data);
|
|
4594
|
+
polygons.map(polygon => polygon.setMap(this.map.googleMap));
|
|
4595
|
+
return polygons;
|
|
4596
|
+
}
|
|
4597
|
+
catch (_err) {
|
|
4598
|
+
// ignore error if the file does not exist
|
|
4599
|
+
return [];
|
|
4600
|
+
}
|
|
4601
|
+
});
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
SitesMapsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMapsComponent, deps: [{ token: HeNodeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4605
|
+
SitesMapsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMapsComponent, selector: "he-sites-maps", inputs: { loadPolygons: "loadPolygons", sites: "sites", nodes: "nodes", center: "center", zoom: "zoom", showNotice: "showNotice" }, viewQueries: [{ propertyName: "map", first: true, predicate: GoogleMap, descendants: true }], ngImport: i0, template: "<google-map *ngIf=\"googleLoaded\"\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"zoom\"\n [center]=\"center\"\n></google-map>\n\n<p *ngIf=\"showNotice\" class=\"mt-2 is-italic is-size-7\">The information provided might not be complete</p>\n\n<div class=\"no-location has-text-center has-text-light\" *ngIf=\"showNoLocation\">\n <span>No precise location data</span>\n</div>\n", styles: [":host{display:block;height:100%;position:relative;width:100%}.no-location{background-color:#0000004d;left:0;height:100%;position:absolute;top:0;width:100%;z-index:9}.no-location>span{display:inline-block;margin-top:12%}\n"], components: [{ type: i1$2.GoogleMap, selector: "google-map", inputs: ["height", "width", "center", "zoom", "options", "mapTypeId"], outputs: ["authFailure", "boundsChanged", "centerChanged", "mapClick", "mapDblclick", "mapDrag", "mapDragend", "mapDragstart", "headingChanged", "idle", "maptypeidChanged", "mapMousemove", "mapMouseout", "mapMouseover", "projectionChanged", "mapRightclick", "tilesloaded", "tiltChanged", "zoomChanged"], exportAs: ["googleMap"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
4606
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMapsComponent, decorators: [{
|
|
4607
|
+
type: Component,
|
|
4608
|
+
args: [{
|
|
4609
|
+
selector: 'he-sites-maps',
|
|
4610
|
+
templateUrl: './sites-maps.component.html',
|
|
4611
|
+
styleUrls: ['./sites-maps.component.scss']
|
|
4612
|
+
}]
|
|
4613
|
+
}], ctorParameters: function () { return [{ type: HeNodeService }]; }, propDecorators: { map: [{
|
|
4614
|
+
type: ViewChild,
|
|
4615
|
+
args: [GoogleMap]
|
|
4616
|
+
}], loadPolygons: [{
|
|
4617
|
+
type: Input
|
|
4618
|
+
}], sites: [{
|
|
4619
|
+
type: Input
|
|
4620
|
+
}], nodes: [{
|
|
4621
|
+
type: Input
|
|
4622
|
+
}], center: [{
|
|
4623
|
+
type: Input
|
|
4624
|
+
}], zoom: [{
|
|
4625
|
+
type: Input
|
|
4626
|
+
}], showNotice: [{
|
|
4627
|
+
type: Input
|
|
4628
|
+
}] } });
|
|
4629
|
+
|
|
4630
|
+
const maxAreaSize = 5000;
|
|
4631
|
+
const siteTooBig = ({ area }) => area && area / 100 > maxAreaSize;
|
|
4632
|
+
const hasMultipleValues = (values) => (values || []).length > 1;
|
|
4633
|
+
const weighedAverage = ({ value, depthLower, depthUpper }) => value.reduce((prev, curr, index) => prev + (curr * (depthLower[index] - depthUpper[index])), 0) /
|
|
4634
|
+
value.reduce((prev, _curr, index) => prev + (depthLower[index] - depthUpper[index]), 0);
|
|
4635
|
+
const measurementValue = ({ value, depthLower, depthUpper }) => hasMultipleValues(value) && hasMultipleValues(depthLower) && hasMultipleValues(depthUpper) ?
|
|
4636
|
+
weighedAverage({ value, depthLower, depthUpper }) :
|
|
4637
|
+
propertyValue$1(value);
|
|
4638
|
+
|
|
4639
|
+
class SitesMeasurementsLogsComponent {
|
|
4640
|
+
constructor(searchService, nodeService) {
|
|
4641
|
+
this.searchService = searchService;
|
|
4642
|
+
this.nodeService = nodeService;
|
|
4643
|
+
this.originalValues = [];
|
|
4644
|
+
this.recalculatedValues = [];
|
|
4645
|
+
this.loading = true;
|
|
4646
|
+
this.NodeType = NodeType;
|
|
4647
|
+
this.models = [];
|
|
4648
|
+
this.measurements = [];
|
|
4649
|
+
}
|
|
4650
|
+
ngOnInit() {
|
|
4651
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4652
|
+
this.logsUrl = this.nodeService.nodeLogsUrl(this.node);
|
|
4653
|
+
this.logs = yield this.nodeService.getModelsLog(this.node);
|
|
4654
|
+
const { results: measurements } = yield this.searchService.search({
|
|
4655
|
+
fields: ['@type', '@id', 'name'],
|
|
4656
|
+
limit: 1000,
|
|
4657
|
+
query: {
|
|
4658
|
+
bool: {
|
|
4659
|
+
must: [
|
|
4660
|
+
matchType(NodeType.Term),
|
|
4661
|
+
matchTermType(TermTermType.measurement)
|
|
4662
|
+
]
|
|
4663
|
+
}
|
|
4664
|
+
}
|
|
4665
|
+
});
|
|
4666
|
+
this.measurements = measurements;
|
|
4667
|
+
this.loading = false;
|
|
4668
|
+
});
|
|
4669
|
+
}
|
|
4670
|
+
get node() {
|
|
4671
|
+
return Object.assign(Object.assign({}, this.site), { dataState: DataState.recalculated });
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
SitesMeasurementsLogsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsLogsComponent, deps: [{ token: HeSearchService }, { token: HeNodeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4675
|
+
SitesMeasurementsLogsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMeasurementsLogsComponent, selector: "he-sites-measurements-logs", inputs: { site: "site", originalValues: "originalValues", recalculatedValues: "recalculatedValues" }, ngImport: i0, template: "<he-node-logs-models *ngIf=\"!loading; else loader\"\n [logsUrl]=\"logsUrl\"\n [nodeType]=\"NodeType.Site\"\n [originalValues]=\"originalValues\"\n [recalculatedValues]=\"recalculatedValues\"\n [terms]=\"measurements\"\n [logs]=\"logs\"\n filteredType=\"Measurement\"\n></he-node-logs-models>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [""], components: [{ type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: ["nodeType", "nodeKey", "logsUrl", "originalValues", "recalculatedValues", "terms", "logs", "filteredType"] }, { type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
4676
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsLogsComponent, decorators: [{
|
|
4677
|
+
type: Component,
|
|
4678
|
+
args: [{
|
|
4679
|
+
selector: 'he-sites-measurements-logs',
|
|
4680
|
+
templateUrl: './sites-measurements-logs.component.html',
|
|
4681
|
+
styleUrls: ['./sites-measurements-logs.component.scss']
|
|
4682
|
+
}]
|
|
4683
|
+
}], ctorParameters: function () { return [{ type: HeSearchService }, { type: HeNodeService }]; }, propDecorators: { site: [{
|
|
4684
|
+
type: Input
|
|
4685
|
+
}], originalValues: [{
|
|
4686
|
+
type: Input
|
|
4687
|
+
}], recalculatedValues: [{
|
|
4688
|
+
type: Input
|
|
4689
|
+
}] } });
|
|
4690
|
+
|
|
4691
|
+
const orderBy$1 = require('lodash.orderby');
|
|
4692
|
+
var View$1;
|
|
4693
|
+
(function (View) {
|
|
4694
|
+
View["table"] = "table";
|
|
4695
|
+
View["logs"] = "logs";
|
|
4696
|
+
})(View$1 || (View$1 = {}));
|
|
4697
|
+
class SitesMeasurementsComponent {
|
|
4698
|
+
constructor() {
|
|
4699
|
+
this.originalValues = [];
|
|
4700
|
+
this.sites = [];
|
|
4701
|
+
this.showDownload = false;
|
|
4702
|
+
this.View = View$1;
|
|
4703
|
+
this.selectedView = View$1.table;
|
|
4704
|
+
this.maxAreaSize = maxAreaSize;
|
|
4705
|
+
this.siteTooBig = siteTooBig;
|
|
4706
|
+
this.defaultLabel = defaultLabel;
|
|
4707
|
+
this.measurementValue = measurementValue;
|
|
4708
|
+
this.measurements = [];
|
|
4709
|
+
}
|
|
4710
|
+
ngOnChanges(changes) {
|
|
4711
|
+
if ('sites' in changes) {
|
|
4712
|
+
return this.update();
|
|
4713
|
+
}
|
|
4714
|
+
if ('dataState' in changes) {
|
|
4715
|
+
this.selectedView = View$1.table;
|
|
4716
|
+
}
|
|
4717
|
+
}
|
|
4718
|
+
trackById(_index, item) {
|
|
4719
|
+
return item['@id'];
|
|
4720
|
+
}
|
|
4721
|
+
get isOriginal() {
|
|
4722
|
+
return this.dataState === DataState.original;
|
|
4723
|
+
}
|
|
4724
|
+
update() {
|
|
4725
|
+
const measurementsPerSite = groupNodesByTerm(this.sites, 'measurements', this.originalValues);
|
|
4726
|
+
this.measurements = orderBy$1(grouppedKeys(measurementsPerSite), ['key'], ['asc']);
|
|
4727
|
+
}
|
|
4728
|
+
togglePopover(popover, context) {
|
|
4729
|
+
return popover.isOpen() ? popover.close() : popover.open(context);
|
|
4730
|
+
}
|
|
4731
|
+
get showAreaTooBig() {
|
|
4732
|
+
return this.dataState === DataState.recalculated && (this.sites || []).some(siteTooBig);
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
SitesMeasurementsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4736
|
+
SitesMeasurementsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SitesMeasurementsComponent, selector: "he-sites-measurements", inputs: { originalValues: "originalValues", sites: "sites", dataState: "dataState" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"measurements.length; else emptyTable\">\n <div class=\"columns is-variable is-2 m-0\">\n <div class=\"column is-hidden-mobile\"></div>\n <div class=\"column is-narrow\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.table\" (click)=\"selectedView = View.table\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"list\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Table view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"!isOriginal && sites.length === 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.logs\" (click)=\"selectedView = View.logs\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"calculator\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Recalculations logs</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"px-3 pb-3\" [class.is-hidden]=\"selectedView !== View.table\">\n <div class=\"has-text-right mb-2\">\n <button class=\"button is-dark is-outlined is-small\" (click)=\"showDownload = true\">\n <fa-icon icon=\"download\"></fa-icon>\n <span class=\"pl-2\">Download (CSV)</span>\n </button>\n </div>\n\n <div class=\"table-container data-table-container mb-1\">\n <table class=\"table is-narrow data-table has-children-{{measurements.length}}\">\n <thead>\n <tr>\n <th class=\"width-auto\"></th>\n <th *ngFor=\"let measurement of measurements\"\n [attr.title]=\"measurement.value.term.name\"\n >\n <he-node-link [node]=\"measurement.value.term\">\n <span>{{measurement.value.term.name | ellipsis:30}}</span>\n </he-node-link>\n </th>\n </tr>\n <tr>\n <th class=\"width-auto\"></th>\n <th *ngFor=\"let measurement of measurements\"\n [attr.title]=\"measurement.value.term.units\"\n >{{measurement.value.term.units}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let site of sites; trackBy: trackById; let i = index\">\n <td class=\"width-auto\" [attr.title]=\"defaultLabel(site)\">\n <he-node-link [node]=\"site\">\n <span class=\"is-nowrap has-text-ellipsis\">{{i + 1}}. {{defaultLabel(site)}}</span>\n </he-node-link>\n </td>\n <td class=\"is-nowrap\" *ngFor=\"let measurement of measurements\">\n <span *ngIf=\"measurement.value.values[site['@id']]\"\n class=\"trigger-popover\"\n [ngbPopover]=\"details\" [autoClose]=\"'outside'\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"togglePopover(p, { data: measurement.value.values[site['@id']], site: site, key: 'measurements' })\"\n >\n <span pointer>{{measurementValue(measurement.value.values[site['@id']]) | precision:3 | default:'-'}}</span>\n <he-blank-node-state class=\"ml-1\"\n [node]=\"measurement.value.values[site['@id']].nodes[0]\"\n key=\"value\"\n ></he-blank-node-state>\n </span>\n <span *ngIf=\"!measurement.value.values[site['@id']]\">\n <span>-</span>\n <sup class=\"pl-1\" *ngIf=\"siteTooBig(site)\">(1)</sup>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <he-blank-node-state-notice [dataState]=\"dataState\"></he-blank-node-state-notice>\n\n <p class=\"is-size-7 is-italic\" *ngIf=\"showAreaTooBig\">\n (1) This region is >{{maxAreaSize}}km2 and is too large to reliably gap fill Measurements.\n </p>\n </div>\n\n <he-sites-measurements-logs *ngIf=\"selectedView === View.logs && !isOriginal\"\n [site]=\"sites[0]\"\n [originalValues]=\"originalValues[0].measurements\"\n [recalculatedValues]=\"sites[0].measurements\"\n ></he-sites-measurements-logs>\n</ng-container>\n\n<he-node-csv-export-confirm *ngIf=\"showDownload\"\n [nodes]=\"sites\" filename=\"site-measurements.csv\" [isUpload]=\"false\"\n [headerKeys]=\"['site.id', 'site.@id', 'site.measurements.']\"\n (closed)=\"showDownload = false\"\n></he-node-csv-export-confirm>\n\n<ng-template #emptyTable>\n <div class=\"panel-block\">\n <span>No data</span>\n </div>\n</ng-template>\n\n<ng-template #emptyValue>\n <span>-</span>\n</ng-template>\n\n<ng-template #details let-node=\"site\" let-data=\"data\" let-key=\"key\">\n <p><b>{{node.name}}</b></p>\n <he-node-value-details\n [data]=\"data\" [nodeType]=\"node['@type']\" [dataKey]=\"key\"\n ></he-node-value-details>\n</ng-template>\n", styles: ["fa-icon{display:inline-block;width:10px}\n"], components: [{ type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink"] }, { type: BlankNodeStateComponent, selector: "he-blank-node-state", inputs: ["nodeType", "dataKey", "key", "node", "state"] }, { type: BlankNodeStateNoticeComponent, selector: "he-blank-node-state-notice", inputs: ["dataState", "showDeleted"] }, { type: SitesMeasurementsLogsComponent, selector: "he-sites-measurements-logs", inputs: ["site", "originalValues", "recalculatedValues"] }, { type: NodeCsvExportConfirmComponent, selector: "he-node-csv-export-confirm", inputs: ["nodes", "filename", "headerKeys", "extension", "isUpload"], outputs: ["closed"] }, { type: NodeValueDetailsComponent, selector: "he-node-value-details", inputs: ["data", "nodeType", "dataKey"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay", "ngbPopover", "popoverTitle"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }], pipes: { "ellipsis": EllipsisPipe, "default": DefaultPipe, "precision": PrecisionPipe } });
|
|
4737
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SitesMeasurementsComponent, decorators: [{
|
|
4738
|
+
type: Component,
|
|
4739
|
+
args: [{
|
|
4740
|
+
selector: 'he-sites-measurements',
|
|
4741
|
+
templateUrl: './sites-measurements.component.html',
|
|
4742
|
+
styleUrls: ['./sites-measurements.component.scss']
|
|
4743
|
+
}]
|
|
4744
|
+
}], propDecorators: { originalValues: [{
|
|
4745
|
+
type: Input
|
|
4746
|
+
}], sites: [{
|
|
4747
|
+
type: Input
|
|
4748
|
+
}], dataState: [{
|
|
4749
|
+
type: Input
|
|
4750
|
+
}] } });
|
|
4751
|
+
|
|
4752
|
+
const components$2 = [
|
|
4753
|
+
SitesMapsComponent,
|
|
4754
|
+
SitesMeasurementsComponent,
|
|
4755
|
+
SitesMeasurementsLogsComponent
|
|
4756
|
+
];
|
|
4757
|
+
class HeSitesModule {
|
|
4758
|
+
}
|
|
4759
|
+
HeSitesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
4760
|
+
HeSitesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, declarations: [SitesMapsComponent,
|
|
4761
|
+
SitesMeasurementsComponent,
|
|
4762
|
+
SitesMeasurementsLogsComponent], imports: [CommonModule, ReactiveFormsModule,
|
|
4763
|
+
HeCommonModule,
|
|
4764
|
+
HeNodeModule], exports: [SitesMapsComponent,
|
|
4765
|
+
SitesMeasurementsComponent,
|
|
4766
|
+
SitesMeasurementsLogsComponent] });
|
|
4767
|
+
HeSitesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, imports: [[
|
|
4768
|
+
CommonModule, ReactiveFormsModule,
|
|
4769
|
+
HeCommonModule,
|
|
4770
|
+
HeNodeModule
|
|
4771
|
+
]] });
|
|
4772
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeSitesModule, decorators: [{
|
|
4773
|
+
type: NgModule,
|
|
4774
|
+
args: [{
|
|
4775
|
+
declarations: components$2,
|
|
4776
|
+
exports: components$2,
|
|
4777
|
+
imports: [
|
|
4778
|
+
CommonModule, ReactiveFormsModule,
|
|
4779
|
+
HeCommonModule,
|
|
4780
|
+
HeNodeModule
|
|
4781
|
+
]
|
|
4782
|
+
}]
|
|
4783
|
+
}] });
|
|
4784
|
+
|
|
4877
4785
|
const user = {};
|
|
4878
4786
|
class HeUsersService {
|
|
4879
4787
|
get loggedInUser() {
|
|
@@ -5863,7 +5771,7 @@ class ImpactAssessmentsProductsComponent {
|
|
|
5863
5771
|
});
|
|
5864
5772
|
}
|
|
5865
5773
|
}
|
|
5866
|
-
ImpactAssessmentsProductsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, deps: [{ token: i1$4.FormBuilder }, { token: HeNodeService }, { token: HeSearchService }, { token:
|
|
5774
|
+
ImpactAssessmentsProductsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, deps: [{ token: i1$4.FormBuilder }, { token: HeNodeService }, { token: HeSearchService }, { token: HeToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5867
5775
|
ImpactAssessmentsProductsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ImpactAssessmentsProductsComponent, selector: "he-impact-assessments-products", inputs: { cycles: "cycles", impactAssessments: "impactAssessments", key: "key", dataState: "dataState", enableCompare: "enableCompare", filterTermTypes: "filterTermTypes", enableFilterMethodModel: "enableFilterMethodModel" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"indicators.length; else emptyTable\">\n <div class=\"columns is-variable is-2 m-0\">\n <div class=\"column is-hidden-mobile\"></div>\n <div class=\"column is-narrow\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.table\" (click)=\"selectedView = View.table\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"list\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Table view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"impactAssessments.length > 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.chart\" (click)=\"selectedView = View.chart\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"chart-bar\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Chart view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"enableBreakdown\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.breakdown\" (click)=\"selectedView = View.breakdown\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"chart-bar\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Breakdown view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"!isOriginal && impactAssessments.length === 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.logs\" (click)=\"showRecalculationLogs()\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"calculator\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Recalculations logs</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"px-3 pb-3\" [class.is-hidden]=\"selectedView !== View.table\">\n <div class=\"has-text-right mb-2\">\n <button class=\"button is-dark is-outlined is-small\" (click)=\"showDownload = true\">\n <fa-icon icon=\"download\"></fa-icon>\n <span class=\"pl-2\">Download (CSV)</span>\n </button>\n </div>\n\n <div class=\"table-container data-table-container mb-1\" *bindOnce=\"indicators\">\n <table class=\"table is-narrow data-table has-children-{{indicators.length + 1}}\">\n <thead>\n <tr>\n <th class=\"width-auto\">\n <div class=\"select is-small\" *ngIf=\"enableFilterMethodModel\">\n <select name=\"selectedMethodModel\"\n (change)=\"updateImpacts()\" [(ngModel)]=\"selectedMethodModel\"\n >\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methodModels\" [ngValue]=\"term\">{{term.name}}</option>\n </select>\n </div>\n </th>\n <th></th>\n <th *ngFor=\"let indicator of indicators\"\n [attr.title]=\"indicator.value.term.name\"\n >\n <he-node-link [node]=\"indicator.value.term\">\n <span>{{indicator.value.term.name | ellipsis:30}}</span>\n </he-node-link>\n </th>\n </tr>\n <tr>\n <th class=\"width-auto\">\n <a [href]=\"baseUrl + '/schema/ImpactAssessment#functionalUnit'\" target=\"_blank\">Functional unit:</a>\n <span class=\"pl-1\">1 kg</span>\n </th>\n <th>Product</th>\n <th *ngFor=\"let indicator of indicators\"\n [attr.title]=\"indicator.value.term.units\"\n >{{indicator.value.term.units}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let impactAssessment of impactAssessments; trackBy: trackById; let i = index\">\n <td class=\"width-auto\" [attr.title]=\"impactName(impactAssessment)\" [style.border-left-color]=\"itemColor(i)\">\n <label *ngIf=\"enableCompare\" class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n (change)=\"toggleImpact(impactAssessment)\"\n [checked]=\"isSelected(impactAssessment)\"\n >\n </label>\n <he-node-link class=\"is-inline-block\" [node]=\"impactAssessment\">\n <span class=\"is-nowrap has-text-ellipsis\">{{i + 1}}. {{impactName(impactAssessment)}}</span>\n </he-node-link>\n </td>\n <td [attr.title]=\"impactAssessment.product?.name\">\n <he-node-link *ngIf=\"impactAssessment.product\" [node]=\"impactAssessment.product\">\n <span>{{impactAssessment.product.name | ellipsis:30}}</span>\n </he-node-link>\n </td>\n <td class=\"is-nowrap\" *ngFor=\"let indicator of indicators\">\n <span *ngIf=\"indicator.value.values[impactAssessment['@id']]; else emptyValue\"\n class=\"trigger-popover\"\n [ngbPopover]=\"details\" [autoClose]=\"'outside'\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"togglePopover(p, { data: indicator.value.values[impactAssessment['@id']], impactAssessment: impactAssessment, key: key })\"\n >\n <span pointer>{{propertyValue(indicator.value.values[impactAssessment['@id']].value, key === 'impacts') | precision:3 | default:'-'}}</span>\n <he-blank-node-state class=\"ml-1\"\n [node]=\"indicator.value.values[impactAssessment['@id']].nodes[0]\"\n key=\"value\"\n [state]=\"impactAssessment.aggregated ? 'aggregated' : null\"\n ></he-blank-node-state>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <he-blank-node-state-notice [dataState]=\"dataState\"></he-blank-node-state-notice>\n\n <form *ngIf=\"enableCompare\" class=\"mt-2\" [formGroup]=\"form\" (submit)=\"form.valid && addImpact()\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static\">Compare with Aggregated Impact Assessment</span>\n </div>\n <div class=\"control is-expanded\" [class.has-icons-right]=\"suggesting || loading\">\n <input class=\"input is-small\"\n placeholder=\"Search by name or id\"\n formControlName=\"search\" name=\"search\"\n\n [ngbTypeahead]=\"suggestImpactAssessment\"\n [inputFormatter]=\"formatter\"\n [resultTemplate]=\"suggestion\"\n [focusFirst]=\"true\"\n >\n <span class=\"icon is-small is-right has-text-grey-dark\" [class.is-hidden]=\"!(suggesting || loading)\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"sm\"></fa-icon>\n </span>\n </div>\n <div class=\"control\">\n <button class=\"button is-small\" type=\"submit\" [disabled]=\"suggesting || loading\">\n <fa-icon icon=\"plus\"></fa-icon>\n </button>\n </div>\n </div>\n </form>\n </div>\n\n <he-impact-assessments-indicator-breakdown-chart *ngIf=\"selectedView === View.breakdown\"\n [impactAssessment]=\"impactAssessments[0]\"\n [indicators]=\"impactAssessments[0][key]\"\n ></he-impact-assessments-indicator-breakdown-chart>\n\n <he-impact-assessments-indicators-chart *ngIf=\"impactAssessments.length > 1\" [class.is-hidden]=\"selectedView !== View.chart\"\n [key]=\"key\"\n [impactAssessments]=\"selectedImpactAssessments\"\n [filterTermTypes]=\"filterTermTypes\"\n ></he-impact-assessments-indicators-chart>\n\n <he-impact-assessments-products-logs *ngIf=\"selectedView === View.logs && !isOriginal\"\n [key]=\"key\"\n [impactAssessment]=\"impactAssessments[0]\"\n [filterTermTypes]=\"filterTermTypes\"\n [originalValues]=\"originalValues[0][key]\"\n [recalculatedValues]=\"impactAssessments[0][key]\"\n ></he-impact-assessments-products-logs>\n</ng-container>\n\n<he-node-csv-export-confirm *ngIf=\"showDownload\"\n [nodes]=\"impactAssessments\" [filename]=\"'impact-' + key + '.csv'\" [isUpload]=\"false\"\n [headerKeys]=\"['impactAssessment.id', 'impactAssessment.@id', 'impactAssessment.' + key + '.']\"\n (closed)=\"showDownload = false\"\n></he-node-csv-export-confirm>\n\n<ng-template #emptyTable>\n <div class=\"panel-block\">\n <span>No data</span>\n </div>\n</ng-template>\n\n<ng-template #emptyValue>\n <span>-</span>\n</ng-template>\n\n<ng-template #details let-node=\"impactAssessment\" let-data=\"data\" let-key=\"key\">\n <p *bindOnce=\"node\">\n <b>\n <span *ngIf=\"data.cycle\">{{cycleLabel(node.cycle)}}</span>\n <span *ngIf=\"!data.cycle\">{{data.name}}</span>\n </b>\n </p>\n <he-node-value-details\n [data]=\"data\" [nodeType]=\"node['@type']\" [dataKey]=\"key\"\n ></he-node-value-details>\n</ng-template>\n\n<ng-template #suggestion let-impact=\"result\" let-t=\"term\">\n <div class=\"is-block\">\n <ngb-highlight [result]=\"impact.name || impact.cycle.name\" [term]=\"t\"></ngb-highlight>\n </div>\n <div class=\"columns is-flex\">\n <div class=\"column\" *ngIf=\"impact.country\">\n <span class=\"pr-1 has-text-underline\">Country:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.country.name\" [term]=\"t\"></ngb-highlight></span>\n </div>\n <div class=\"column\" *ngIf=\"impact.product\">\n <span class=\"pr-1 has-text-underline\">Product:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.product.name\" [term]=\"t\"></ngb-highlight></span>\n </div>\n <div class=\"column\" *ngIf=\"impact.endDate\">\n <span class=\"pr-1 has-text-underline\">Date:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.endDate\" [term]=\"t\"></ngb-highlight></span>\n </div>\n </div>\n</ng-template>\n", styles: ["label.checkbox{width:20px}td he-node-link{width:160px}table.data-table td:first-child{border-left-width:8px}\n"], components: [{ type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink"] }, { type: BlankNodeStateComponent, selector: "he-blank-node-state", inputs: ["nodeType", "dataKey", "key", "node", "state"] }, { type: BlankNodeStateNoticeComponent, selector: "he-blank-node-state-notice", inputs: ["dataState", "showDeleted"] }, { type: ImpactAssessmentsIndicatorBreakdownChartComponent, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: ["impactAssessment", "indicators"] }, { type: ImpactAssessmentsIndicatorsChartComponent, selector: "he-impact-assessments-indicators-chart", inputs: ["impactAssessments", "key", "filterTermTypes"] }, { type: ImpactAssessmentsProductsLogsComponent, selector: "he-impact-assessments-products-logs", inputs: ["impactAssessment", "key", "filterTermTypes", "originalValues", "recalculatedValues"] }, { type: NodeCsvExportConfirmComponent, selector: "he-node-csv-export-confirm", inputs: ["nodes", "filename", "headerKeys", "extension", "isUpload"], outputs: ["closed"] }, { type: NodeValueDetailsComponent, selector: "he-node-value-details", inputs: ["data", "nodeType", "dataKey"] }, { type: i10.NgbHighlight, selector: "ngb-highlight", inputs: ["highlightClass", "result", "term"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { type: i1$4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1$4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1$4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay", "ngbPopover", "popoverTitle"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i10.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "placement", "container", "editable", "focusFirst", "showHint", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { type: i1$4.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "ellipsis": EllipsisPipe, "default": DefaultPipe, "precision": PrecisionPipe } });
|
|
5868
5776
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, decorators: [{
|
|
5869
5777
|
type: Component,
|
|
@@ -5872,7 +5780,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
5872
5780
|
templateUrl: './impact-assessments-products.component.html',
|
|
5873
5781
|
styleUrls: ['./impact-assessments-products.component.scss']
|
|
5874
5782
|
}]
|
|
5875
|
-
}], ctorParameters: function () { return [{ type: i1$4.FormBuilder }, { type: HeNodeService }, { type: HeSearchService }, { type:
|
|
5783
|
+
}], ctorParameters: function () { return [{ type: i1$4.FormBuilder }, { type: HeNodeService }, { type: HeSearchService }, { type: HeToastService }]; }, propDecorators: { cycles: [{
|
|
5876
5784
|
type: Input
|
|
5877
5785
|
}], impactAssessments: [{
|
|
5878
5786
|
type: Input
|
|
@@ -5957,5 +5865,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
|
5957
5865
|
* Generated bundle index. Do not edit.
|
|
5958
5866
|
*/
|
|
5959
5867
|
|
|
5960
|
-
export { BibliographiesSearchConfirmComponent, BindOnceDirective, BlankNodeDiffsComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, ClickOutsideDirective, ClipboardComponent, CyclesActivityComponent, CyclesActivityLogsComponent, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesEmissionsComponent, CyclesEmissionsLogsComponent, CyclesFunctionalUnitMeasureComponent, CyclesResultComponent, CyclesSuggestFormComponent, DefaultPipe, DeltaColour, DeltaDisplayType, EllipsisPipe, FilesFormComponent, GetPipe, HE_API_BASE_URL, HE_ORCHESTRATOR_BASE_URL, HeAggregationEngineService, HeAuthService, HeBibliographiesModule, HeCommonModule, HeCommonService, HeCyclesModule, HeEngineService, HeFilesModule, HeFontawesomeModule, HeImpactAssessmentsModule, HeMendeleyService, HeNodeCsvService, HeNodeModule, HeNodeService, HeSchemaService, HeSearchModule, HeSearchService, HeSitesModule, HeUsersService, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, ImpactAssessmentsProductsLogsComponent, KeyToLabelPipe, KeysPipe, Level, LinkKeyValueComponent, MAX_RESULTS, MapsDrawingConfirmComponent, MendeleySearchResult, NodeCsvExportConfirmComponent, NodeCsvSelectHeadersComponent, NodeDiffsComponent, NodeIconComponent, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeMissingLookupFactorsComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, SchemaVersionLinkComponent, SitesMapsComponent, SitesMeasurementsComponent, SitesMeasurementsLogsComponent, SkeletonTextComponent, SocialTagsComponent, TagsInputDirective, TimesPipe, ToastComponent,
|
|
5868
|
+
export { ARRAY_DELIMITER, BibliographiesSearchConfirmComponent, BindOnceDirective, BlankNodeDiffsComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, ClickOutsideDirective, ClipboardComponent, CyclesActivityComponent, CyclesActivityLogsComponent, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesEmissionsComponent, CyclesEmissionsLogsComponent, CyclesFunctionalUnitMeasureComponent, CyclesResultComponent, CyclesSuggestFormComponent, DefaultPipe, DeltaColour, DeltaDisplayType, DiffsDisplayType, EllipsisPipe, FilesFormComponent, GetPipe, HE_API_BASE_URL, HE_ORCHESTRATOR_BASE_URL, HeAggregationEngineService, HeAuthService, HeBibliographiesModule, HeCommonModule, HeCommonService, HeCyclesModule, HeEngineService, HeFilesModule, HeFontawesomeModule, HeImpactAssessmentsModule, HeMendeleyService, HeNodeCsvService, HeNodeModule, HeNodeService, HeSchemaService, HeSearchModule, HeSearchService, HeSitesModule, HeToastService, HeUsersService, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, ImpactAssessmentsProductsLogsComponent, KeyToLabelPipe, KeysPipe, Level, LinkKeyValueComponent, MAX_RESULTS, MapsDrawingConfirmComponent, MendeleySearchResult, NodeCsvExportConfirmComponent, NodeCsvSelectHeadersComponent, NodeDiffsComponent, NodeIconComponent, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeMissingLookupFactorsComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, SchemaVersionLinkComponent, SitesMapsComponent, SitesMeasurementsComponent, SitesMeasurementsLogsComponent, SkeletonTextComponent, SocialTagsComponent, TagsInputDirective, TimesPipe, ToastComponent, UnitConverterComponent, addPolygonToFeature, allCountriesQuery, arrayValue, availableProperties, baseUrl, bottom, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, calculatePercentDelta, clustererImage, code, coordinatesToPoint, countriesQuery, createMarker, cropsQuery, customDeltaFuncs, dataPathToKey, dataValue, defaultFeature, defaultLabel, defaultSuggestionType, definitionToSchemaType, delta, deserializeSearchFilters, ellipsis, emptyValue, errorHasError, errorHasWarning, errorText, evaluateSuccess, filenameWithoutExt, fillColor, fillStyle, filterError, filterParams, findConfigModels, findProperty, findPropertyById, formatCustomErrorMessage, formatDiffValues, formatError, formatLinkNodesSuggestions, formatPropertyError, formatSuggestion, gitBranch, gitHome, gitRawBaseUrl, groupChanged, groupNodesByTerm, grouppedKeys, grouppedValueKeys, handleAPIError, hasError, hasWarning, isAddPropertyEnabled, isChrome, isExternal, isMissingOneOfError, isMissingPropertyError, isSchemaIri, isScrolledBelow, itemColor, keyToDataPath, keyToLabel, levels, linkTypeEnabled, listColor, locationQuery, lookupUrl, lookups, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, missingNodeErrorMessage, missingNodeErrors, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, nodeAvailableProperties, nodeLink, nodeLogsUrl, nodeUrl, numberGte, parentKey, parentProperty, parseData, parseDataPath, parseLines, parseMessage, parseNewValue, pathToApiDocsPath, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonsFromFeature, primaryProduct, propertyError, propertyId, propertyValue$1 as propertyValue, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, repeat, roundValue, safeJSONParse, safeJSONStringify, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchQuery, searchResultsFields, searchableTypes, serializeSearchFilters, siblingProperty, singleProperty, siteTooBig, sortOrder, sortProperties, strokeColor, strokeStyle, suggestMatchQuery, suggestQuery, termChildToParent, termLocation, termLocationName, termProperties, termTypeGroups, termTypeLabel, termTypeLookupUrl, toCsv$1 as toCsv, toDashCase, typeToNewProperty, updateProperties, valueTypeToDefault, waitFor, wildcardQuery, worldRegion };
|
|
5961
5869
|
//# sourceMappingURL=hestia-earth-ui-components.js.map
|