Skip to content

Commit 4da7fad

Browse files
committed
fix: make ElasticField and MetaField reactive to prop changes
Convert imperative let assignments to computed properties so derived values update when props change. ElasticField now wraps all field derivation logic in a single computed(). MetaField uses computed properties for sorted data and display name. ObjectView reads route query id reactively inside fetchdata.
1 parent a2b347e commit 4da7fad

File tree

3 files changed

+91
-74
lines changed

3 files changed

+91
-74
lines changed

src/components/ElasticField.vue

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
<script setup lang="ts">
2+
import { computed } from 'vue';
3+
24
import MetaField from '@/components/MetaField.vue';
35
import LeafletMap from '@/components/widgets/LeafletMap.vue';
46
5-
const { field, title } = defineProps<{
7+
import { ui } from '@/configuration';
8+
import { formatDuration, formatFileSize, shortenText } from '@/tools';
9+
10+
const props = defineProps<{
611
// biome-ignore lint/suspicious/noExplicitAny: FIXME
712
field: any;
813
title: string;
914
}>();
1015
11-
import { ui } from '@/configuration';
12-
import { formatDuration, formatFileSize, shortenText } from '@/tools';
13-
1416
const { expand = [], byteFields = [], durationFields = [] } = ui.main;
1517
16-
let id: string;
17-
let url: string | undefined;
18-
let name: string;
19-
let description: string;
20-
// biome-ignore lint/suspicious/noExplicitAny: FIXME
21-
let geometry: any;
22-
// biome-ignore lint/suspicious/noExplicitAny: FIXME
23-
let expandField: any;
24-
let identifier: string | undefined;
25-
2618
const testURL = (url: string) => {
2719
if (url?.startsWith?.('http')) {
2820
//TODO: make this a real url test
@@ -35,75 +27,92 @@ const isIdentifier = (item: object) =>
3527
3628
const isLanguage = (item: object) => '@type' in item && item['@type'] === 'Language' && 'name' in item;
3729
38-
if (typeof field === 'undefined') {
39-
name = '';
40-
} else if (byteFields.includes(title)) {
41-
name = formatFileSize(field);
42-
} else if (durationFields.includes(title) && typeof field === 'number') {
43-
name = formatDuration(field);
44-
} else if (['string', 'number'].includes(typeof field)) {
45-
name = String(field);
46-
} else if (isIdentifier(field)) {
47-
identifier = field.name;
48-
name = field.value;
49-
} else if (isLanguage(field)) {
50-
name = field.name;
51-
if ('code' in field) {
52-
name += ` (${field.code})`;
53-
}
54-
url = testURL(field['@id']);
55-
} else if (Array.isArray(field) && typeof field[0] === 'string') {
56-
name = String(field[0]);
57-
} else {
58-
url = testURL(field['@id']);
59-
name = Array.isArray(field.name) ? field.name[0] : field.name;
60-
description = Array.isArray(field.description) ? field.description[0] : field.description;
61-
62-
if (title === 'contentLocation') {
63-
geometry = field.geo;
64-
} else if (expand.includes(title)) {
65-
expandField = { name: title, data: field };
30+
const derived = computed(() => {
31+
const field = props.field;
32+
const title = props.title;
33+
34+
let name = '';
35+
let url: string | undefined;
36+
let id: string | undefined;
37+
let description: string | undefined;
38+
// biome-ignore lint/suspicious/noExplicitAny: FIXME
39+
let geometry: any;
40+
// biome-ignore lint/suspicious/noExplicitAny: FIXME
41+
let expandField: any;
42+
let identifier: string | undefined;
43+
44+
if (typeof field === 'undefined') {
45+
name = '';
46+
} else if (byteFields.includes(title)) {
47+
name = formatFileSize(field);
48+
} else if (durationFields.includes(title) && typeof field === 'number') {
49+
name = formatDuration(field);
50+
} else if (['string', 'number'].includes(typeof field)) {
51+
name = String(field);
52+
} else if (isIdentifier(field)) {
53+
identifier = field.name;
54+
name = field.value;
55+
} else if (isLanguage(field)) {
56+
name = field.name;
57+
if ('code' in field) {
58+
name += ` (${field.code})`;
59+
}
60+
url = testURL(field['@id']);
61+
} else if (Array.isArray(field) && typeof field[0] === 'string') {
62+
name = String(field[0]);
63+
} else {
64+
url = testURL(field['@id']);
65+
name = Array.isArray(field.name) ? field.name[0] : field.name;
66+
description = Array.isArray(field.description) ? field.description[0] : field.description;
67+
68+
if (title === 'contentLocation') {
69+
geometry = field.geo;
70+
} else if (expand.includes(title)) {
71+
expandField = { name: title, data: field };
72+
}
6673
}
67-
}
6874
69-
const collapseName = shortenText(name);
75+
const collapseName = shortenText(name);
76+
77+
return { name, url, id, description, geometry, expandField, identifier, collapseName };
78+
});
7079
</script>
7180

7281
<template>
73-
<template v-if="identifier">
82+
<template v-if="derived.identifier">
7483
<div class="space-y-2">
75-
<span class="font-medium">{{ identifier }}:</span>
76-
<span class="ml-2">{{ name }}</span>
84+
<span class="font-medium">{{ derived.identifier }}:</span>
85+
<span class="ml-2">{{ derived.name }}</span>
7786
</div>
7887
</template>
7988

80-
<template v-else-if="expandField">
89+
<template v-else-if="derived.expandField">
8190
<el-collapse>
82-
<el-collapse-item :title="collapseName" :name="collapseName">
83-
<MetaField :meta="expandField" :isExpand="true" />
91+
<el-collapse-item :title="derived.collapseName" :name="derived.collapseName">
92+
<MetaField :meta="derived.expandField" :isExpand="true" />
8493
</el-collapse-item>
8594
</el-collapse>
8695
</template>
8796

88-
<template v-else-if="geometry">
89-
<LeafletMap class="h-72 flex grow min-w-50 mr-4" :modelValue="geometry" :enableDrawing="false" />
97+
<template v-else-if="derived.geometry">
98+
<LeafletMap class="h-72 flex grow min-w-50 mr-4" :modelValue="derived.geometry" :enableDrawing="false" />
9099
<p class="text-sm">This map is not designed or suitable for Native Title research.</p>
91100
</template>
92101

93-
<template v-else-if="url">
94-
<a class="wrap-break-word underline text-blue-600 hover:text-blue-800 visited:text-purple-600" :href="url"
102+
<template v-else-if="derived.url">
103+
<a class="wrap-break-word underline text-blue-600 hover:text-blue-800 visited:text-purple-600" :href="derived.url"
95104
target="_blank" rel="nofollow noreferrer">
96105
<span class="break-all">
97-
{{ name || id }}
106+
{{ derived.name || derived.id }}
98107
</span>
99108
</a><br />
100109
</template>
101110

102111
<template v-else>
103112
<p>
104-
{{ name || id }}
105-
<el-tooltip v-if="description" class="box-item" effect="light" trigger="click" :content="description"
106-
placement="top">
113+
{{ derived.name || derived.id }}
114+
<el-tooltip v-if="derived.description" class="box-item" effect="light" trigger="click"
115+
:content="derived.description" placement="top">
107116
<el-button size="small" link>
108117
<font-awesome-icon icon="fa-solid fa-circle-info" />
109118
</el-button>

src/components/MetaField.vue

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,34 @@ const { meta, isExpand } = defineProps<{
1616
const currentPage = ref(1);
1717
const pageSize = ref(10);
1818
19-
if (meta.data && Array.isArray(meta.data) && paginatedMeta.includes(meta.name)) {
20-
(meta.data as { name: string }[]).sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
21-
}
19+
const name = computed(() => meta.name);
20+
const data = computed(() => meta.data);
21+
22+
const sortedData = computed(() => {
23+
if (Array.isArray(meta.data) && paginatedMeta.includes(meta.name)) {
24+
return [...(meta.data as { name: string }[])].sort((a, b) =>
25+
a.name.toLowerCase().localeCompare(b.name.toLowerCase()),
26+
);
27+
}
28+
29+
return meta.data;
30+
});
2231
2332
const paginatedMetaData = computed(() => {
24-
if (Array.isArray(meta.data) && meta.data?.length > pageSize.value) {
33+
if (Array.isArray(sortedData.value) && sortedData.value.length > pageSize.value) {
2534
const start = (currentPage.value - 1) * pageSize.value;
26-
return meta.data.slice(start, start + pageSize.value);
35+
return sortedData.value.slice(start, start + pageSize.value);
2736
}
2837
29-
return meta.data;
38+
return sortedData.value;
3039
});
3140
</script>
3241

3342
<template>
3443
<el-row :gutter="10" class="py-2">
3544
<template v-if="isExpand">
3645
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
37-
<el-row v-for="(value, key) in meta.data">
46+
<el-row v-for="(value, key) in data">
3847
<el-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">{{ startCase(key as string) }}</el-col>
3948
<el-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17">
4049
<ElasticField :field="value" :title="key as string" />
@@ -44,18 +53,18 @@ const paginatedMetaData = computed(() => {
4453
</template>
4554
<template v-else>
4655
<el-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7" class="mt-1">
47-
<span class="font-bold break-words">{{ startCase(meta.name) }}</span>
56+
<span class="font-bold wrap-break-word">{{ startCase(name) }}</span>
4857
<FieldHelperCard :meta="meta" />
4958
</el-col>
5059
<el-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17">
51-
<template v-if="Array.isArray(meta.data)">
52-
<ElasticField :field="d" :title="meta.name" :key="d as string" v-for="d of paginatedMetaData" />
53-
<el-pagination v-if="meta.data.length > pageSize" class="mt-4" layout="prev, pager, next"
54-
:total="meta.data.length" :page-size="pageSize" :current-page="currentPage"
60+
<template v-if="Array.isArray(sortedData)">
61+
<ElasticField :field="d" :title="name" :key="d as string" v-for="d of paginatedMetaData" />
62+
<el-pagination v-if="(sortedData as unknown[]).length > pageSize" class="mt-4" layout="prev, pager, next"
63+
:total="(sortedData as unknown[]).length" :page-size="pageSize" :current-page="currentPage"
5564
@current-change="currentPage = $event" />
5665
</template>
5766
<template v-else>
58-
<ElasticField :field="meta.data" :title="meta.name" />
67+
<ElasticField :field="data" :title="name" />
5968
</template>
6069
</el-col>
6170
</template>

src/views/ObjectView.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ const route = useRoute();
3333
const head = injectHead();
3434
const gtm = useGtm();
3535
36-
const id = route.query.id as string;
37-
3836
const { name, meta, populateName, populateMeta, handleMissingEntity } = useEntityView(config);
3937
4038
const parts = ref<({ '@id': string; name: string; encodingFormat: string[] } & Record<string, string>)[]>([]);
@@ -141,6 +139,7 @@ const fetchMembers = async () => {
141139
};
142140
143141
const fetchdata = async () => {
142+
const id = route.query.id?.toString();
144143
if (!id) {
145144
handleMissingEntity();
146145
@@ -285,7 +284,7 @@ fetchdata();
285284
<el-card :body-style="{ padding: '0px' }" class="mx-10 p-5">
286285
<h5 class="text-2xl font-medium">{{ t('object.retrieveMetadata') }}</h5>
287286
<hr class="divider divider-gray pt-2" />
288-
<RetrieveDataMetadata :id="id" :identifier="metadata.identifier" />
287+
<RetrieveDataMetadata :id="String(route.query.id ?? '')" :identifier="metadata.identifier" />
289288
<template v-if="metadata.metadataLicense">
290289
<hr class="divider divider-gray mt-4 pb-2" />
291290
<h4 class="text-1xl font-medium">

0 commit comments

Comments
 (0)