@hestia-earth/ui-components 0.43.11 → 0.43.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/hestia-earth-ui-components-file-errors.mjs +46 -12
- package/fesm2022/hestia-earth-ui-components-file-errors.mjs.map +1 -1
- package/fesm2022/hestia-earth-ui-components.mjs +442 -45
- package/fesm2022/hestia-earth-ui-components.mjs.map +1 -1
- package/package.json +1 -1
- package/types/hestia-earth-ui-components-file-errors.d.ts +1 -1
- package/types/hestia-earth-ui-components.d.ts +153 -47
|
@@ -498,9 +498,22 @@ const guidePageId = (nodeType, errorMessage) => {
|
|
|
498
498
|
};
|
|
499
499
|
const mapErrorMessage = 'does not contain latitude and longitude';
|
|
500
500
|
const allowedDataPathsLabels = Object.values(SchemaType);
|
|
501
|
+
const isInfrastructureInputTermType = (dataPath = '') => /infrastructure\[\d+\]\.inputs\[\d+\]\.term\.termType$/.test(dataPath);
|
|
501
502
|
const idPatternError = (chars) => `You can only use the following characters for this field: ${chars.join(', ')}`;
|
|
502
503
|
const noTillage = { id: 'noTillage', name: 'No tillage' };
|
|
503
504
|
const pastureGrass = { id: 'pastureGrass', name: 'Pasture grass' };
|
|
505
|
+
/**
|
|
506
|
+
* Which distribution flagged a value as outside its confidence interval.
|
|
507
|
+
*
|
|
508
|
+
* The two mean very different things, so the message has to say which one fired: a `posterior` is
|
|
509
|
+
* fitted to HESTIA Cycle data for this country and product, while a `prior` is only the FAOSTAT
|
|
510
|
+
* national average — it stands in for any country/product too thin to have a posterior, so it is
|
|
511
|
+
* weak evidence rather than an alarm.
|
|
512
|
+
*/
|
|
513
|
+
const distributionSourceMessage = {
|
|
514
|
+
prior: 'This was flagged against the FAOSTAT prior (national average), not HESTIA Cycle data for this product, so it is weak evidence.',
|
|
515
|
+
posterior: 'This was flagged against HESTIA Cycle data for this product in this country.'
|
|
516
|
+
};
|
|
504
517
|
const isMigrationError = ({ params }) => params?.current && 'expected' in params;
|
|
505
518
|
/**
|
|
506
519
|
* Builds the error formatting functions for a given presentation (`renderer`) and link
|
|
@@ -519,6 +532,8 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
519
532
|
const glossaryTypeLink = (type, text = termTypeLabel(type)) => r.link(`${urls.glossaryBaseUrl()}?termType=${type}`, text);
|
|
520
533
|
const termLink = ({ id, name }) => r.link(`${urls.baseUrl()}/term/${id}`, name || id);
|
|
521
534
|
const listAsCode = (values) => (values ?? []).map(value => r.code(value)).join(', ');
|
|
535
|
+
const joinWithAnd = (values) => values.length > 1 ? `${values.slice(0, -1).join(', ')} and ${values[values.length - 1]}` : values.join('');
|
|
536
|
+
const listAsCodeWithAnd = (values) => joinWithAnd((values ?? []).map(value => r.code(value)));
|
|
522
537
|
const joinValues = (values) => (values || [])
|
|
523
538
|
.filter(Boolean)
|
|
524
539
|
.map(value => r.code(value))
|
|
@@ -583,6 +598,18 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
583
598
|
? `${r.underline(negation ? 'none' : 'one')} of the following must be valid: ${formatList(rule.anyOf.map(nested => formatRule(nested)))}`
|
|
584
599
|
: '';
|
|
585
600
|
const patternErrorKey = (pattern) => `should match pattern "${pattern}"`;
|
|
601
|
+
/**
|
|
602
|
+
* Names the distribution(s) behind the grouped warnings, as a trailing sentence.
|
|
603
|
+
*
|
|
604
|
+
* Returns an empty string when no error carries a `source`, so warnings raised before the
|
|
605
|
+
* validation service started sending it read exactly as they did before.
|
|
606
|
+
*/
|
|
607
|
+
const distributionSources = (errors) => {
|
|
608
|
+
const sentences = unique(errors.map(({ params }) => params?.source))
|
|
609
|
+
.map(source => distributionSourceMessage[source])
|
|
610
|
+
.filter(Boolean);
|
|
611
|
+
return sentences.length ? `${sentences.join(r.lineBreak)}${r.lineBreak}` : '';
|
|
612
|
+
};
|
|
586
613
|
// set message as empty to not display it
|
|
587
614
|
const customErrorMessage = {
|
|
588
615
|
'this field is required': ({ dataPath }, _errorCount, allErrors) => {
|
|
@@ -612,6 +639,9 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
612
639
|
},
|
|
613
640
|
"should have required property '@id'": idNotFoundError,
|
|
614
641
|
"should have required property 'id'": idNotFoundError,
|
|
642
|
+
"should have required property 'inputsCompleteness'": () => `You must add the ${schemaLink('Infrastructure#inputsCompleteness', 'inputsCompleteness')} field when you have specified inputs for the Site infrastructure.
|
|
643
|
+
This allows us to know whether the ${code('material')} completeness can be updated after copying the
|
|
644
|
+
infrastructure inputs to the Cycle.`,
|
|
615
645
|
'should match exactly one schema in oneOf': () => '',
|
|
616
646
|
'should match some schema in anyOf': () => '',
|
|
617
647
|
'should match "then" schema': () => '',
|
|
@@ -709,16 +739,20 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
709
739
|
].every(Boolean))
|
|
710
740
|
: null;
|
|
711
741
|
return [
|
|
712
|
-
dataPath
|
|
713
|
-
?
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
742
|
+
isInfrastructureInputTermType(dataPath)
|
|
743
|
+
? `Only terms in the ${listAsCodeWithAnd(params?.allowedValues)} glossaries can be added as inputs to Site
|
|
744
|
+
infrastructure. Other inputs, e.g., ${code('fuel')}, should be specified on the Cycle.
|
|
745
|
+
You can use the ${schemaLink('Input#operation', 'operation')} field on inputs to specify what the input is for.`
|
|
746
|
+
: dataPath.endsWith('term.termType')
|
|
747
|
+
? [
|
|
748
|
+
`For ${pluralize(paths[paths.length - 3].label, 0)}, we only allow terms from the following glossaries: ${listAsCode(params?.allowedValues)}.`,
|
|
749
|
+
ifError
|
|
750
|
+
? ''
|
|
751
|
+
: 'Please either change the Term you are using and ensure it is from one of the glossaries listed above, or follow the schema to identify where this Term can be added.'
|
|
752
|
+
]
|
|
753
|
+
.filter(Boolean)
|
|
754
|
+
.join(' ')
|
|
755
|
+
: `Only the following ${values} are permitted: ${listAsCode(params?.allowedValues)}.`,
|
|
722
756
|
ifError?.schema.properties
|
|
723
757
|
? `This validation applies when the following conditions are met:${formatList(Object.entries(ifError.schema.properties).map(([key, value]) => formatRule(value, key)))}`
|
|
724
758
|
: ''
|
|
@@ -893,7 +927,7 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
893
927
|
Please, use a term with termType ${glossaryTypeLink(TermTermType.landCover)} instead.
|
|
894
928
|
This will help us gap-fill the amount of grass consumed by the herd.`,
|
|
895
929
|
'the sum of all pastureGrass values must be 100': ({ params }) => `The sum of all ${termLink(pastureGrass)} values must be equal to ${params.expected}%.`,
|
|
896
|
-
'is outside confidence interval': (error, errorCount, allErrors) => `${unique((allErrors.length ? allErrors : [error]).flatMap(({ dataPath, params }) => params?.outliers?.map(value => `The ${dataPath.includes('product') ? 'product' : 'input'} value ${errorCount === 1 ? `${code(value)} ` : ''}is ${value > params?.min ? 'above' : 'below'} ${params?.threshold ? `${code(`${(params.threshold + (1 - params.threshold) / 2) * 100}%`)} of` : ''} all ${params?.group ? code(params.group) : code(params?.term?.name)} data in ${code(params?.country.name)} on the HESTIA platform.`))).join(r.lineBreak)}${r.lineBreak}
|
|
930
|
+
'is outside confidence interval': (error, errorCount, allErrors) => `${unique((allErrors.length ? allErrors : [error]).flatMap(({ dataPath, params }) => params?.outliers?.map(value => `The ${dataPath.includes('product') ? 'product' : 'input'} value ${errorCount === 1 ? `${code(value)} ` : ''}is ${value > params?.min ? 'above' : 'below'} ${params?.threshold ? `${code(`${(params.threshold + (1 - params.threshold) / 2) * 100}%`)} of` : ''} all ${params?.group ? code(params.group) : code(params?.term?.name)} data in ${code(params?.country.name)} on the HESTIA platform.`))).join(r.lineBreak)}${r.lineBreak}${distributionSources(allErrors.length ? allErrors : [error])}
|
|
897
931
|
Please double-check these values before submitting.`,
|
|
898
932
|
'should be equal to boundary': ({ params }) => `The calculated ${schemaLink('Site#area', 'area')} from ${code('boundary')} is ${code(params?.expected)} ha.
|
|
899
933
|
This may be an error if the boundary represents the area under cultivation.`,
|
|
@@ -1198,7 +1232,7 @@ const createErrorFormatter = ({ renderer: r, urls }) => {
|
|
|
1198
1232
|
const field = message.split("'")[1].replace("'", '');
|
|
1199
1233
|
const nodeType = dataPathLabel(error?.dataPath);
|
|
1200
1234
|
return `You are missing the following required field: ${code(field)}. ${nodeType && nodeType.toLowerCase() !== 'completeness'
|
|
1201
|
-
? `Either: add ${code(field)}, or if you
|
|
1235
|
+
? `Either: add ${code(field)}, or if you did not intend to add this ${nodeType}, please remove all fields on this ${nodeType}.`
|
|
1202
1236
|
: ''}`.trim();
|
|
1203
1237
|
};
|
|
1204
1238
|
const parseDefaultMessage = (message, error) => r.capitalizeFirst(message?.startsWith('should have required property') ? requiredPropertyError(message, error) : message);
|