From 4f6976feef9150992e37171d44fb739268bacc5f Mon Sep 17 00:00:00 2001 From: W Beecher Baker Date: Fri, 4 Apr 2025 16:17:30 -0400 Subject: [PATCH] add Determined To Rank to Stats panel --- .../Panel/PanelStats/PanelStats.vue | 35 +++++++++++++++++++ src/modules/otus/services/TaxonWorks.js | 8 +++++ src/modules/otus/store/store.js | 15 ++++++++ 3 files changed, 58 insertions(+) diff --git a/src/modules/otus/components/Panel/PanelStats/PanelStats.vue b/src/modules/otus/components/Panel/PanelStats/PanelStats.vue index d645fd7..00b092b 100644 --- a/src/modules/otus/components/Panel/PanelStats/PanelStats.vue +++ b/src/modules/otus/components/Panel/PanelStats/PanelStats.vue @@ -23,6 +23,7 @@ > Taxa + Total + + To rank + {{ rank }} {{ taxa }} + {{ toRank(rank) }} {{ names.invalid + names.valid }} @@ -108,6 +117,12 @@ const props = defineProps({ default: false }, + // Show "Determined to Rank" column? + showToRank: { + type: Boolean, + default: false + }, + hideNames: { type: Boolean, default: false @@ -117,6 +132,22 @@ const props = defineProps({ const store = useOtuStore() const isAdvancedView = ref(props.showTaxa) const hideNames = ref(props.hideNames) +const showToRank = ref(props.showToRank) + +if (props.showToRank) { + store.loadToRank(props.otuId) +} + +const toRank = (rank) => { + const rankLc = rank.toLowerCase() + const data = store.determinedToRank.data + if (store.determinedToRank.isLoading) return "..." + else if (!data) return "—" // not yet loaded, or failed + else { + if (rankLc in data) return data[rankLc] ?? 0 // null means 0 in the API response + else return "missing" + } +} const menuOptions = computed(() => [ { @@ -126,6 +157,10 @@ const menuOptions = computed(() => [ { label: hideNames.value ? 'Show names' : 'Hide names', action: () => (hideNames.value = !hideNames.value) + }, + { + label: showToRank.value ? 'Hide to rank' : 'Show to rank', + action: () => (showToRank.value = !showToRank.value) } ]) diff --git a/src/modules/otus/services/TaxonWorks.js b/src/modules/otus/services/TaxonWorks.js index 135baaf..43d72dd 100644 --- a/src/modules/otus/services/TaxonWorks.js +++ b/src/modules/otus/services/TaxonWorks.js @@ -104,6 +104,14 @@ export default class TaxonWorks { return makeAPIRequest.get(`/tags/`, processedOpt) } + // Counts of specimens within a given taxon that are identified only to a certain rank, and no finer. + // For example, {class: null, order: null, family: 3, genus: 5, species; 25, subspecies: 2} + // would mean that 3 specimens (probably lots of multiple individuals) have only been identified + // down to the family level, so they are good candidates to borrow for further identification. + static getDeterminedToRank(otuId, opt) { + return makeAPIRequest.get(`/otus/${otuId}/inventory/determined_to_rank.json`, opt) + } + /** Load image info (thumbnail, etc) from a URL such as one in a Darwin Core 'associatedMedia' field. */ static getImageFromUrl(url, opt) { // sanity check that this is the kind of URL we're looking for diff --git a/src/modules/otus/store/store.js b/src/modules/otus/store/store.js index 957f66e..aef3b06 100644 --- a/src/modules/otus/store/store.js +++ b/src/modules/otus/store/store.js @@ -19,6 +19,10 @@ export const useOtuStore = defineStore('otuStore', { taxonomy: { commonNames: [], synonyms: [] + }, + determinedToRank: { + isLoading: false, + data: {} } } }, @@ -72,6 +76,17 @@ export const useOtuStore = defineStore('otuStore', { } }, + async loadToRank(otuId, opts) { + this.determinedToRank.isLoading = true + const response = await useOtuPageRequest('determinedToRank', () => + TaxonWorks.getDeterminedToRank(otuId, opts) + ) + this.determinedToRank = { + isLoading: false, + data: response.data + } + }, + async loadInit({ otuId, controller }) { const requestStore = useOtuPageRequestStore()