Skip to content
Open
12 changes: 12 additions & 0 deletions src/types/Dataset.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@ export interface DatasetRelatedIdentifiers {
related_identifiers: DatasetRelatedIdentifier[];
}

export interface FieldValidation {
name: string;
metadata_header: string;
route: string;
}

export interface DatasetMetadataValidation {
message: string;
metadata: FieldValidation[];
route_identifier: string;
}

export interface DatasetHealthsheetRecord {
id: number;
question: string;
Expand Down
12 changes: 12 additions & 0 deletions src/views/study/dataset/metadata/about/DatasetMetadataOther.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const moduleData = ref<DatasetOther>({
acknowledgement: "",
format: [],
Expand Down Expand Up @@ -189,6 +192,15 @@ const scrollToSection = (key: string) => {
class="w-full"
:disabled="studyStore.currentStudyRole === 'viewer'"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h3 class="resource-type">Resource Type</h3>

<p class="pb-8 pt-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const displayLicenseEditor = ref(false);
const draftLicense = ref("");
const licenseName = ref("");
Expand Down Expand Up @@ -250,6 +253,15 @@ const scrollToSection = (key: string) => {
label-placement="top"
class="w-full overflow-auto"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h2 class="access pb-4">Access</h2>

<n-card class="bg-gray-50">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const moduleData = reactive<DatasetDataManagement>({
consent: {
details: "",
Expand Down Expand Up @@ -250,6 +253,15 @@ const scrollToSection = (key: string) => {
label-placement="top"
class="w-full"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h2 class="consent pb-4">Consent</h2>

<n-card class="bg-gray-50">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const formRef = ref<FormInst | null>(null);
const moduleData = reactive<DatasetGeneralInformation>({
dates: [],
Expand Down Expand Up @@ -308,6 +311,15 @@ const scrollToSection = (key: string) => {
label-placement="top"
:disabled="studyStore.currentStudyRole === 'viewer'"
>
<div v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h2 class="titles py-4">Titles</h2>

<n-card class="bg-gray-50">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const formRef = ref<FormInst | null>(null);
const moduleData = reactive<DatasetIdentifiers>({
identifiers: [],
Expand Down Expand Up @@ -197,6 +200,15 @@ const scrollToSection = (key: string) => {
</div>

<div class="w-full">
<div v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h3 class="primary-Identifier">Primary Identifier</h3>

<p class="pb-8 pt-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const formRef = ref<FormInst | null>(null);

const moduleData = reactive<DatasetRelatedIdentifiers>({
Expand Down Expand Up @@ -178,6 +181,15 @@ const saveMetadata = (e: MouseEvent) => {
class="pr-4"
v-else
>
<div v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<CollapsibleCard
v-for="(item, index) in moduleData.related_identifiers"
:key="item.id"
Expand Down
12 changes: 12 additions & 0 deletions src/views/study/dataset/metadata/team/DatasetMetadataTeam.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const routeParams = {
const studyId = routeParams.studyId;
const datasetId = routeParams.datasetId;

const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const formRef = ref<FormInst | null>(null);

const moduleData = reactive<DatasetTeam>({
Expand Down Expand Up @@ -375,6 +378,15 @@ const scrollToSection = (key: string) => {
class="w-full pr-4"
:disabled="studyStore.currentStudyRole === 'viewer'"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h2 class="creators pb-4">Creators</h2>

<n-card class="bg-gray-50">
Expand Down
81 changes: 80 additions & 1 deletion src/views/study/dataset/publish/new/NewVersion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { faker } from "@faker-js/faker";

import { useSidebarStore } from "@/stores/sidebar";
import type { DatasetMetadataValidation } from "@/types/Dataset";
import { baseURL } from "@/utils/constants";

const route = useRoute();
Expand All @@ -17,6 +18,7 @@ const routeParams = {

const studyId = routeParams.studyId as string;
const datasetId = routeParams.datasetId as string;
const responseLoading = ref(false);

const loading = ref(false);

Expand All @@ -26,6 +28,8 @@ const version = ref({
title: faker.commerce.productName(),
});

const moduleData = reactive<DatasetMetadataValidation[]>([]);

const rules: FormRules = {
title: [
{
Expand All @@ -38,6 +42,31 @@ const rules: FormRules = {

onBeforeMount(async () => {
sidebarStore.setAppSidebarCollapsed(true);
responseLoading.value = true;

const response = await fetch(
`${baseURL}/study/${studyId}/dataset/${datasetId}/metadata-validation`,
{
method: "GET",
}
);
responseLoading.value = false;

if (!response.ok) {
push.error("Something went wrong.");

throw new Error("Network response was not ok");
}

const data = await response.json();

console.log(data);

moduleData.splice(0, moduleData.length, ...(data ?? []).map((item: any) => ({ ...item })));

//
// aboutList = moduleData.map((item: any) => item.about);
// datasetSubjects = moduleData.map((item: any) => item.dataset_subjects);
});

const createVersion = (e: MouseEvent) => {
Expand Down Expand Up @@ -83,6 +112,25 @@ const createVersion = (e: MouseEvent) => {
}
});
};

function uniqueMetadataIdentifiers(fullMetadata: any) {
const uniqueIdentifier = new Set();

const uniqueFields = fullMetadata.filter((field: any) => {
const key = field.metadata_header; // or field.field if that's your unique identifier
if (!uniqueIdentifier.has(key)) {
uniqueIdentifier.add(key);
return true;
}
return false;
});

return uniqueFields;
}

function getNamesForHeader(metadata, header) {
return metadata.filter((m) => m.metadata_header === header).map((m) => m.name);
}
</script>

<template>
Expand All @@ -96,7 +144,38 @@ const createVersion = (e: MouseEvent) => {

<n-divider />

<div class="mr-4 flex gap-2 pb-4" :key="index" v-for="(item, index) in moduleData">
<n-alert :title="item.message" class="w-full" type="error">
<div
class="mb-2 flex text-sm"
v-for="(field, index) in uniqueMetadataIdentifiers(item.metadata)"
:key="index"
>
<RouterLink
:to="{
name: `${item.route_identifier}:${field.route}`,
params: {
studyId: routeParams.studyId,
datasetId: routeParams.datasetId,
},
state: {
metadata_header: field.metadata_header,
missingFields: getNamesForHeader(item.metadata, field.metadata_header),
},
}"
>
<n-button size="tiny" type="info" ghost>
Add Missing {{ field.metadata_header }} Details
</n-button>
</RouterLink>
</div>
</n-alert>
</div>

<LottieLoader v-if="responseLoading" />

<n-form
v-else
ref="formRef"
:model="version"
:rules="rules"
Expand All @@ -111,7 +190,7 @@ const createVersion = (e: MouseEvent) => {
<n-divider />

<div class="flex justify-start">
<n-button size="large" type="primary" @click="createVersion" :loading="loading">
<n-button disabled size="large" type="primary" @click="createVersion" :loading="loading">
<template #icon>
<f-icon icon="gridicons:create" />
</template>
Expand Down
10 changes: 10 additions & 0 deletions src/views/study/metadata/description/StudyDescription.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const router = useRouter();
const push = usePush();

const studyStore = useStudyStore();
const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");
const metadata_header = routeState?.metadata_header || "";

const formRef = ref<FormInst | null>(null);

Expand Down Expand Up @@ -355,6 +358,13 @@ const scrollToSection = (key: string) => {
:disabled="studyStore.currentStudyRole === 'viewer'"
class="w-full"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic"> {{ metadata_header }}:{{ missingFieldsList }} </span>
</n-alert>
</div>

<h2 class="description pb-4">Description</h2>

<n-card class="rounded-xl bg-gray-50">
Expand Down
11 changes: 11 additions & 0 deletions src/views/study/metadata/design/StudyDesign.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const router = useRouter();
const push = usePush();

const studyStore = useStudyStore();
const routeState = window.history.state;
const missingFieldsList = (routeState?.missingFields || []).map((f) => f).join(", ");

const formRef = ref<FormInst | null>(null);

Expand Down Expand Up @@ -359,6 +361,15 @@ const scrollToSection = (key: string) => {
label-placement="top"
class="w-full pr-4"
>
<div class="pb-4" v-if="routeState?.missingFields && routeState.missingFields.length">
<n-alert type="error">
Please fill the following required field(s):
<span class="italic">
{{ missingFieldsList }}
</span>
</n-alert>
</div>

<h3 class="study-type pb-4">Study Type</h3>

<p class="pb-8 pt-2">
Expand Down
Loading
Loading