diff --git a/arches_for_science/media/js/views/components/annotation-summary.js b/arches_for_science/media/js/views/components/annotation-summary.js index 014306518..cf9101e69 100644 --- a/arches_for_science/media/js/views/components/annotation-summary.js +++ b/arches_for_science/media/js/views/components/annotation-summary.js @@ -69,6 +69,12 @@ define([ return feature.properties; }, onEachFeature: function(feature, layer) { + const classificationConcepts = Object.freeze({ + // Concept IDs, not values + "a2588fa8-5ae6-4770-a473-dec0c05fb175": 'Analysis Area', + "2703e524-b5ea-4548-bea7-7ce354e4e05a": 'Sample Area', + "9db724b9-b3c7-4761-9a50-673d64a15bd8": 'Sample', + }); if (feature.properties.active === false){ var popup = L.popup({ closeButton: false, @@ -76,15 +82,11 @@ define([ }) .setContent(popupHtml) .on('add', function() { + // hope that translator has not adjusted the location of the bracket. const titleArray = feature.properties.name.split('['); const title = titleArray[0].trim(); - // TODO(i18n) samples - const type = titleArray[1].startsWith('Analysis Area') ? 'Analysis Area': - titleArray[1].startsWith('Sample Area') ? 'Sample Area': - 'Part'; - const parent = titleArray[1].startsWith('Analysis Area') ? titleArray[1].replace('Analysis Area of ', '').replace(']',''): - titleArray[1].startsWith('Sample Area') ? titleArray[1].replace('Sample Area of ','').replace(']',''): - titleArray[1].replace(']',''); + const type = classificationConcepts[feature.properties.classificationConceptId]; + const parent = feature.properties.parentPhysicalThingName; const description = ( arches.translations.existingAnnotation .replace('{title}', title) diff --git a/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-annotation-step.js b/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-annotation-step.js index 9b8b06799..9fa3457a8 100644 --- a/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-annotation-step.js +++ b/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-annotation-step.js @@ -155,7 +155,7 @@ define([ this.areaNameFromTileData = (tileData) => { const nameValue = tileData[self.partIdentifierAssignmentLabelNodeId]; const baseName = self.getStrValue(nameValue) || ""; - return `${baseName} [${arches.translations.analysisArea} ${arches.translations.of} ${self.physicalThingName()}]`; + return arches.translations.analysisAreaOf.replace('{analysisName}', baseName).replace('{physicalThingName}', self.physicalThingName()); }; this.areaName = ko.computed(function(){ if (self.selectedAnalysisAreaInstance()){ @@ -410,7 +410,6 @@ define([ parentPhysicalThingTileData: koMapping.toJSON(parentPhysicalThing.data), parentPhysicalThingTileId: parentPhysicalThing.tileid, transactionId: params.form.workflowId, - analysisAreaName: self.areaName() }; self.savingTile(true); @@ -504,12 +503,12 @@ define([ const data = { parentPhysicalThingResourceid: self.physicalThingResourceId, + parentPhysicalThingName: self.physicalThingName(), collectionResourceid: params.projectSet, partIdentifierAssignmentTileData: koMapping.toJSON(self.selectedAnalysisAreaInstance().data), partIdentifierAssignmentTileId: self.selectedAnalysisAreaInstance().tileid, partIdentifierAssignmentResourceId: self.selectedAnalysisAreaInstance().resourceinstance_id, transactionId: params.form.workflowId, - analysisAreaName: self.areaName(), }; $.ajax({ @@ -812,6 +811,7 @@ define([ }) .then(function(json) { json.features.forEach(function(feature) { + // TODO(i18n) slug or name? feature.properties.graphName = "Physical Thing"; if (self.sampleLocationTileIds.includes(feature.properties.tileId)) { feature.properties.type = 'sample_location'; diff --git a/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-final-step.js b/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-final-step.js index e11fc2c11..10bf24260 100644 --- a/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-final-step.js +++ b/arches_for_science/media/js/views/components/workflows/analysis-areas-workflow/analysis-areas-final-step.js @@ -5,8 +5,9 @@ define([ 'arches', 'views/components/workflows/summary-step', 'templates/views/components/workflows/analysis-areas-workflow/analysis-areas-final-step.htm', + 'utils/label-based-graph-utils', 'views/components/annotation-summary', -], function(ko, _, uuid, arches, SummaryStep, analysisAreasFinalStepTemplate) { +], function(ko, _, uuid, arches, SummaryStep, analysisAreasFinalStepTemplate, labelBasedGraphUtils) { function viewModel(params) { var self = this; @@ -97,12 +98,21 @@ define([ annotator: annotation.annotator, }); } else { - annotation.annotationJson.features.map(feature => { - feature.properties.color = '#999999'; - feature.properties.fillColor = '#999999'; - feature.properties.tileId = annotation.tileId; - feature.properties.name = annotation.annotationName; - feature.properties.active = false; + // TODO: fetch in parallel + fetch(self.urls.api_resources(annotation.resourceId) + '?format=json&compact=false&v=beta') + .then(response => response.json()) + .then(data => { + annotation.annotationJson.features.map(feature => { + feature.properties.color = '#999999'; + feature.properties.fillColor = '#999999'; + feature.properties.tileId = annotation.tileId; + feature.properties.name = annotation.annotationName; + feature.properties.active = false; + feature.properties.classificationConceptId = data.resource.type.concept_details[0].concept_id; + feature.properties.parentPhysicalThingName = labelBasedGraphUtils.getPropByNodeId( + data.resource, 'f8d5fe4c-b31d-11e9-9625-a4d18cec433a', '@display_value' + ); + }); }); } }); diff --git a/arches_for_science/media/js/views/components/workflows/create-project-workflow/add-things-step.js b/arches_for_science/media/js/views/components/workflows/create-project-workflow/add-things-step.js index 4b48458f8..e1080a6a4 100644 --- a/arches_for_science/media/js/views/components/workflows/create-project-workflow/add-things-step.js +++ b/arches_for_science/media/js/views/components/workflows/create-project-workflow/add-things-step.js @@ -94,9 +94,6 @@ define([ analysis: '31d97bdd-f10f-4a26-958c-69cb5ab69af1', }; this.physicalThingTypeNodeId = '8ddfe3ab-b31d-11e9-aff0-a4d18cec433a'; - // TODO(i18n) samples - const sampleSubstring = '[Sample'; // for "[Sample of ..." and "[Sample Area of ..." - const regionSubstring = '[Region'; this.value.subscribe(function(a) { a.forEach(function(action) { @@ -332,8 +329,8 @@ define([ return ( result.context_label.includes("Physical Thing") || result.context_label.includes("Search Term") - ) && (self.includeSamples() || !result.text.includes(sampleSubstring)) - && (self.includeAnalysisAreas() || !result.text.includes(regionSubstring)) + ) && (self.includeSamples() || !result.text.includes(arches.translations.sample)) + && (self.includeAnalysisAreas() || !result.text.includes(arches.translations.analysisArea)) }); return { "results": filteredResults diff --git a/arches_for_science/media/js/views/components/workflows/project-report-workflow/add-annotations.js b/arches_for_science/media/js/views/components/workflows/project-report-workflow/add-annotations.js index 4b469b8da..c2b2fa972 100644 --- a/arches_for_science/media/js/views/components/workflows/project-report-workflow/add-annotations.js +++ b/arches_for_science/media/js/views/components/workflows/project-report-workflow/add-annotations.js @@ -225,15 +225,17 @@ define([ }) .setContent(popupHtml) .on('add', function() { + const classificationConcepts = Object.freeze({ + // Concept IDs, not values + "a2588fa8-5ae6-4770-a473-dec0c05fb175": 'Analysis Area', + "2703e524-b5ea-4548-bea7-7ce354e4e05a": 'Sample Area', + "9db724b9-b3c7-4761-9a50-673d64a15bd8": 'Sample', + }); + // hope that translator has not adjusted the location of the bracket. const titleArray = feature.properties.name.split('['); const title = titleArray[0].trim(); - // TODO(i18n) samples - const type = titleArray[1].startsWith('Analysis Area') ? 'Analysis Area': - titleArray[1].startsWith('Sample Area') ? 'Sample Area': - 'Part'; - const parent = titleArray[1].startsWith('Analysis Area') ? titleArray[1].replace('Analysis Area of ', '').replace(']',''): - titleArray[1].startsWith('Sample Area') ? titleArray[1].replace('Sample Area of ','').replace(']',''): - titleArray[1].replace(']',''); + const type = classificationConcepts[feature.properties.classificationConceptId]; + const parent = feature.properties.parentPhysicalThingName; const description = ( arches.translations.existingAnnotation .replace('{title}', title) diff --git a/arches_for_science/media/js/views/components/workflows/project-report-workflow/download-report.js b/arches_for_science/media/js/views/components/workflows/project-report-workflow/download-report.js index b52d25be7..1bbfe9722 100644 --- a/arches_for_science/media/js/views/components/workflows/project-report-workflow/download-report.js +++ b/arches_for_science/media/js/views/components/workflows/project-report-workflow/download-report.js @@ -86,7 +86,6 @@ define([ const reportDate = today.toLocaleDateString('en-US', options); const physicalThingsDetailsArray = [...Object.values(physicalThingsDetails)]; const objectOfStudyDetailsArray = physicalThingsDetailsArray.filter(thing => physicalThingFromPreviousStep.includes(thing.resourceinstanceid)); - // TODO(i18n) samples const analysisAreas = physicalThingsDetailsArray.filter(physicalThing => physicalThing.resource?.type?.["@display_value"] == 'analysis areas'); const annotationScreenshots = screenshots?.map((screenshot) => { const url = `${window.location.origin}/temp_file/${screenshot.fileId}`; diff --git a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-final-step.js b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-final-step.js index b574773ff..010687f04 100644 --- a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-final-step.js +++ b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-final-step.js @@ -56,6 +56,12 @@ define([ return feature.properties; }, onEachFeature: function(feature, layer) { + const classificationConcepts = Object.freeze({ + // Concept IDs, not values + "a2588fa8-5ae6-4770-a473-dec0c05fb175": 'Analysis Area', + "2703e524-b5ea-4548-bea7-7ce354e4e05a": 'Sample Area', + "9db724b9-b3c7-4761-9a50-673d64a15bd8": 'Sample', + }); if (!feature.properties.active){ var popup = L.popup({ closeButton: false, @@ -63,15 +69,11 @@ define([ }) .setContent(iiifPopup) .on('add', function() { + // hope that translator has not adjusted the location of the bracket. const titleArray = feature.properties.locationName.split('['); const title = titleArray[0].trim(); - // TODO(i18n) samples - const type = titleArray[1].startsWith('Analysis Area') ? 'Analysis Area': - titleArray[1].startsWith('Sample Area') ? 'Sample Area': - 'Part'; - const parent = titleArray[1].startsWith('Analysis Area') ? titleArray[1].replace('Analysis Area of ', '').replace(']',''): - titleArray[1].startsWith('Sample Area') ? titleArray[1].replace('Sample Area of ','').replace(']',''): - titleArray[1].replace(']',''); + const type = classificationConcepts[feature.properties.classificationConceptId]; + const parent = feature.properties.parentPhysicalThingName; const description = ( arches.translations.existingAnnotation .replace('{title}', title) @@ -209,35 +211,43 @@ define([ const parentPhyiscalThingResourceId = self.getResourceValue(val.resource["Sampling Unit"][0], ['Sampling Area','Overall Object Sampled','resourceId']); const parentPhyiscalThing = ko.observable(); self.getResourceData(parentPhyiscalThingResourceId, parentPhyiscalThing); - parentPhyiscalThing.subscribe(function(val){ // 2nd request + parentPhyiscalThing.subscribe(async function(val) { // 2nd request const parts = self.getResourceValue(val.resource, ['Part Identifier Assignment']); - parts.forEach(function(part){ + for (const part of parts) { const locationName = self.getResourceValue(part,['Part Identifier Assignment_Physical Part of Object','@display_value']); const tileId = self.getResourceValue(part,['@tile_id']); - const sampleAreaResourceId = self.getResourceValue(part,['Part Identifier Assignment_Physical Part of Object','resourceId']); + const partResourceId = self.getResourceValue(part,['Part Identifier Assignment_Physical Part of Object','resourceId']); const partsAnnotationString = self.getResourceValue(part,['Part Identifier Assignment_Polygon Identifier','@display_value']); if (partsAnnotationString) { const locationAnnotation = JSON.parse(partsAnnotationString.replaceAll("'",'"')); const canvas = locationAnnotation.features[0].properties.canvas; - locationAnnotation.features.forEach(function(feature){ - feature.properties.active = false; - feature.properties.tileId = tileId; - feature.properties.locationName = locationName; - feature.properties.sampleAreaResourceId = sampleAreaResourceId; - }); - if (canvas in partsAnnotationCollection) { - partsAnnotationCollection[canvas].push({ - locationAnnotation: locationAnnotation, - sampleAreaResourceId: sampleAreaResourceId, + // TODO: fetch in parallel + await fetch(self.urls.api_resources(partResourceId) + '?format=json&compact=false&v=beta') + .then(response => response.json()) + .then(data => { + locationAnnotation.features.forEach(function(feature) { + feature.properties.active = false; + feature.properties.tileId = tileId; + feature.properties.locationName = locationName; + // misnomer, could be analysis area + feature.properties.sampleAreaResourceId = partResourceId; + feature.properties.classificationConceptId = data.resource.type.concept_details[0].concept_id; + feature.properties.parentPhysicalThingName = parentPhyiscalThing().resource._label?.['@display_value'] ?? ''; }); - } else { - partsAnnotationCollection[canvas] = [{ - locationAnnotation: locationAnnotation, - sampleAreaResourceId: sampleAreaResourceId, - }]; - } + if (canvas in partsAnnotationCollection) { + partsAnnotationCollection[canvas].push({ + locationAnnotation: locationAnnotation, + sampleAreaResourceId: partResourceId, + }); + } else { + partsAnnotationCollection[canvas] = [{ + locationAnnotation: locationAnnotation, + sampleAreaResourceId: partResourceId, + }]; + } + }); } - }); + } // add the annotation of parts to the final object self.annotationStatus = ko.observable(); diff --git a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.js b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.js index c5d285eb9..c4320efdf 100644 --- a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.js +++ b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.js @@ -164,11 +164,15 @@ define([ } }); + this.sampleNameFromTileData = (data) => { + const partIdentifierAssignmentLabelNodeId = '3e541cc6-859b-11ea-97eb-acde48001122'; + const baseName = ko.unwrap(ko.unwrap(data[partIdentifierAssignmentLabelNodeId])?.[arches.activeLanguage]?.["value"]) || ""; + return arches.translations.sampleOf.replace('{sampleName}', baseName).replace('{physicalThingName}', params.physicalThingName); + }; + this.sampleName = ko.computed(function() { - var partIdentifierAssignmentLabelNodeId = '3e541cc6-859b-11ea-97eb-acde48001122'; if (self.selectedSampleLocationInstance()){ - const baseName = ko.unwrap(ko.unwrap(self.selectedSampleLocationInstance().data[partIdentifierAssignmentLabelNodeId])?.[arches.activeLanguage]?.["value"]) || ""; - return `${baseName} [Sample of ${params.physicalThingName}]`; + return self.sampleNameFromTileData(self.selectedSampleLocationInstance().data); } }); diff --git a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sampling-info-step.js b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sampling-info-step.js index 33f1a7251..3e463d937 100644 --- a/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sampling-info-step.js +++ b/arches_for_science/media/js/views/components/workflows/sample-taking-workflow/sampling-info-step.js @@ -85,8 +85,7 @@ define([ }); this.samplingDate.subscribe(function(val){ - // TODO(i18n) samples - self.samplingName(["Sampling Activity of", self.physicalThingNameValue, val].join(' ')); + self.samplingName(arches.translations.samplingActivityOf.replace('{physicalThingName}', self.physicalThingNameValue) + ' ' + val); }); const selectPhysThingData = params.selectPhysThingData; diff --git a/arches_for_science/media/js/views/components/workflows/upload-dataset/instrument-info-step.js b/arches_for_science/media/js/views/components/workflows/upload-dataset/instrument-info-step.js index 7b2d3f779..978d09757 100644 --- a/arches_for_science/media/js/views/components/workflows/upload-dataset/instrument-info-step.js +++ b/arches_for_science/media/js/views/components/workflows/upload-dataset/instrument-info-step.js @@ -107,8 +107,10 @@ define([ self.instrumentInstance(self.createRelatedInstance(val, instrumentUsedInObservation, observationInstrumentUsedIn)); instrumentData.then(function(data){ self.instrumentName(data._source.displayname); - // TODO(i18n) samples - self.nameValue(`Observation of ${physThingName} with ${data._source.displayname} ${self.dateValue()}`); + const formattedName = arches.translations.observationWith + .replace('{physicalThingName}', physThingName) + .replace('{instrumentName}', data._source.displayname); + self.nameValue(`${formattedName} ${self.dateValue()}`); }); } if (!val) { @@ -119,8 +121,10 @@ define([ this.dateValue.subscribe(function(val){ if (self.instrumentName()) { - // TODO(i18n) samples - self.nameValue(`Observation of ${physThingName} with ${self.instrumentName()} ${val}`); + const formattedName = arches.translations.observationWith + .replace('{physicalThingName}', physThingName) + .replace('{instrumentName}', self.instrumentName()); + self.nameValue(`${formattedName} ${val}`); } }); diff --git a/arches_for_science/templates/javascript.htm b/arches_for_science/templates/javascript.htm index 9756b7f3b..cbe3feefe 100644 --- a/arches_for_science/templates/javascript.htm +++ b/arches_for_science/templates/javascript.htm @@ -149,13 +149,18 @@ takes-too-long='{% trans "This is taking longer than usual. Thank you for your patience." as takesTooLong %} "{{ takesTooLong|escapejs }}"' analysis-area='{% trans "Analysis Area" as analysisArea %} "{{ analysisArea|escapejs }}"' analysis-areas='{% trans "Analysis Areas" as analysisAreas %} "{{ analysisAreas|escapejs }}"' + analysis-area-of='{% trans "{analysisName} [Analysis Area of {physicalThingName}]" as analysisAreaOf %} "{{ analysisAreaOf|escapejs }}"' + sample='{% trans "Sample" as sample %} "{{ sample|escapejs }}"' + sample-of='{% trans "{sampleName} [Sample of {physicalThingName}]" as sampleOf %} "{{ sampleOf|escapejs }}"' + sampling-activity-of='{% trans "Sampling Activity of {physicalThingName}" as samplingActivityOf %} "{{ samplingActivityOf|escapejs }}"' no-modifying-areas='{% trans "Analysis Areas may not be modified in the sample taking workflow" as noModifyingAreas %} "{{ noModifyingAreas|escapejs }}"' sample-location='{% trans "Sample Location" as sampleLocation %} "{{ sampleLocation|escapejs }}"' no-modifying-samples='{% trans "Sample locations may not be modified in the analysis area workflow" as noModifyingSamples %} "{{ noModifyingSamples|escapejs }}"' physical-thing-placeholder='{% trans "find a physical thing: enter an artist, object name, artwork title or object number" as physicalThingPlaceholder %} "{{ physicalThingPlaceholder|escapejs }}"' annotation-summary-for='{% trans "Annotation Summary for" as annotationSummaryFor %} "{{ annotationSummaryFor|escapejs }}"' - existing-annotation='{% trans "{title} is a {type} of {parent},\n which is created before" as existingAnnotation %} "{{ existingAnnotation|escapejs }}"' + existing-annotation='{% trans "{title} is a(n) {type} of {parent}, which is created before" as existingAnnotation %} "{{ existingAnnotation|escapejs }}"' timespan='{% trans "TimeSpan" as timespan %} "{{ timespan|escapejs }}"' + observation-with='{% trans "Observation of {physicalThingName} with {instrumentName}" as observationWith %} "{{ observationWith|escapejs }}"' > {% endblock arches_translations %} diff --git a/arches_for_science/templates/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.htm b/arches_for_science/templates/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.htm index d60925fdd..50abb8c01 100644 --- a/arches_for_science/templates/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.htm +++ b/arches_for_science/templates/views/components/workflows/sample-taking-workflow/sample-taking-sample-location-step.htm @@ -143,11 +143,7 @@