Skip to content

Commit

Permalink
Merge branch 'collection-objects' into dev-main
Browse files Browse the repository at this point in the history
  • Loading branch information
wbbaker committed Aug 22, 2024
2 parents bb41271 + 05fda1a commit b8068da
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<VCard>
<ClientOnly>
<VSpinner
v-if="isLoading"
logo-class="w-8 h-8"
legend=""
/>
</ClientOnly>
<VCardHeader class="flex justify-between">
<h2 class="text-md">
In the Collection
<span v-if="Array.isArray(inventoryDWC)"> [{{ inventoryDWC.length }}]</span>
</h2>
<PanelDropdown panel-key="panel:specimens" />
</VCardHeader>
<VCardContent class="text-sm">
<p v-if="typeof inventoryDWC === 'string'" v-html="inventoryDWC"/>
<ul v-else class="tree ml-2">
<li v-for="specimen in inventoryDWC" :key="specimen.id" class="mt-1">
<SpecimenSummary :specimen="specimen"/>
</li>
</ul>
</VCardContent>
</VCard>
</template>

<script setup>
import { ref, watch } from 'vue'
import PanelDropdown from '../PanelDropdown.vue'
import { useOtuPageRequest } from "@/modules/otus/helpers/useOtuPageRequest.js"
import TaxonWorks from "@/modules/otus/services/TaxonWorks.js"
import SpecimenSummary from "@/modules/otus/components/Panel/PanelSpecimens/SpecimenSummary.vue"
const props = defineProps({
otuId: {
type: [String, Number],
required: true
}
})
const inventoryDWC = ref("Loading...")
const isLoading = ref(false)
watch(
() => props.otuId,
async () => {
if (!props.otuId) {
inventoryDWC.value = 'No OTU specified.'
return
}
isLoading.value = true
useOtuPageRequest('panel:specimens', () =>
TaxonWorks.getOtuInventoryDarwinCore(props.otuId)
).then(({data}) => {
inventoryDWC.value = data
}).catch(
e => inventoryDWC.value = `Error: ${e}`
).finally(() => isLoading.value = false)
},
{immediate: true}
)
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!--
A text summary of a Darwin Core representation of a specimen,
from the TaxonWorks api /otus/<ID>/inventory/dwc.json.
For further reference see https://dwc.tdwg.org/terms/.
-->
<template>
<details>
<summary class="cursor-pointer">
{{ describeSpecimen(specimen) }}
</summary>
<ul class="m-2 ml-6 list-disc">
<li v-for="detail in describeDetails(specimen)" v-html="detail" :key="detail?.id"/>
<li>
<details>
<summary class="cursor-pointer">Full Record ({{Object.keys(specimen).length}} items)</summary>
<dl class="m-2 ml-6">
<template v-for="entry in Object.entries(specimen)" :key="entry[0]">
<dt>{{ entry[0] }}</dt>
<dd class="ml-4 mb-2">{{ entry[1] }}</dd>
</template>
</dl>
</details>
</li>
</ul>
</details>
</template>

<script setup>
const props = defineProps({
specimen: {
type: Object, // Darwin Core schema -- see above for references
required: true,
}
})

/** Based on taxonpages-orthoptera PanelSpecimenRecords. */
function describeSpecimen(specimen) {
return [
specimen.catalogNumber,
describeLocation(specimen),
specimen.year,
// `length ${JSON.stringify(item).length}`,
].filter(Boolean).join("; ")
}

function describeDetails(specimen) {
return [
describeCollectionDate(specimen),
specimen.recordedBy && `Recorded by ${specimen.recordedBy}`,
describeIdentifiedBy(specimen),
specimen.georeferencedBy && `Georeferenced by ${specimen.georeferencedBy}${describeGeoreferenceUncertainty(specimen)}`,
// CollectionObject #1234
specimen.dwc_occurrence_object_id && `${specimen.dwc_occurrence_object_type} #${specimen.dwc_occurrence_object_id}`,
].filter(Boolean)
}

function describeLocation(specimen) {
return [
specimen.country && specimen.country,
specimen.stateProvince && specimen.stateProvince,
specimen.county && `${specimen.county} County`,
].filter(Boolean).join(", ")
}

function describeIdentifiedBy(specimen) {
return [
specimen.identifiedBy && `Identified by ${specimen.identifiedBy}`,
specimen.dateIdentified,
].filter(Boolean).join(", ")
}

function describeCollectionDate(specimen) {
if (!specimen.year) return null
const date = new Date(specimen.year, specimen.month, specimen.day)
return `Collected ${date.toLocaleDateString()}`
}

function describeGeoreferenceUncertainty(specimen) {
return specimen.coordinateUncertaintyInMeters && ` to within ${specimen.coordinateUncertaintyInMeters} meters`
}
</script>
6 changes: 6 additions & 0 deletions src/modules/otus/components/Panel/PanelSpecimens/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import PanelSpecimens from "./PanelSpecimens.vue";

export default {
id: 'panel:specimens',
component: PanelSpecimens
}
3 changes: 2 additions & 1 deletion src/modules/otus/constants/layouts/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export const DEFAULT_OVERVIEW_LAYOUT = {
'panel:type',
'panel:type-specimen',
'panel:nomenclature',
'panel:nomenclature-references'
'panel:nomenclature-references',
'panel:specimens'
],
[
'panel:map',
Expand Down
20 changes: 20 additions & 0 deletions src/modules/otus/services/TaxonWorks.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ export default class TaxonWorks {
return makeAPIRequest.get(`/otus/${otuId}/inventory/content`, opt)
}

// Note that this could support multiple OTUs.
// The API takes a comma-separated list of OTU IDs.
static getCollectionObjects(otuId, opt) {
return makeAPIRequest.get(`/collection_objects?otu_id[]=${otuId}`, opt)
// See taxonworks/lib/collection_object/filter.rb Queries:CollectionObject:Filter for full list of options.
// However, none seems to change the result.
/*
@with_buffered_collecting_event = boolean_param(params, :with_buffered_collecting_event)
@with_buffered_determinations = boolean_param(params, :with_buffered_determinations)
@with_buffered_other_labels = boolean_param(params, :with_buffered_other_labels)
*/
// return makeAPIRequest.get(`/collection_objects?otu_id[]=${otuId}&with_buffered_determination=true`, opt)
// return makeAPIRequest.get(`/collection_objects?otu_id[]=${otuId}&descendants=true`, opt)
// return makeAPIRequest.get(`/collection_objects?otu_id[]=${otuId}/dwc.json`, opt)
}

static getOtuInventoryDarwinCore(otuId, opt) {
return makeAPIRequest.get(`/otus/${otuId}/inventory/dwc.json`, opt)
}

static getCachedMap(id) {
return makeAPIRequest.get(`/cached_maps/${id}`)
}
Expand Down

0 comments on commit b8068da

Please sign in to comment.