Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions web/src/views/SubmissionPortal/Components/StudyForm.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
<script lang="ts">
import { defineComponent, onMounted, ref } from '@vue/composition-api';
import {
defineComponent,
onMounted,
ref,
nextTick,
} from '@vue/composition-api';
import NmdcSchema from 'nmdc-schema/jsonschema/nmdc.schema.json';
import { cloneDeep } from 'lodash';
import Definitions from '@/definitions';
import { studyForm, studyFormValid } from '../store';
import SubmissionTable from './SubmissionTable.vue';
import { MetadataSubmissionRecord } from '../store/api';

export default defineComponent({
components: {
SubmissionTable,
},
setup() {
const formRef = ref();
const copyDataDialog = ref(false);

function addContributor() {
studyForm.contributors.push({
Expand All @@ -23,18 +35,32 @@ export default defineComponent({
];
}

function copyInfoClicked() {
copyDataDialog.value = true;
}

function copyData(item: MetadataSubmissionRecord) {
const newStudyData = cloneDeep(item.metadata_submission.studyForm);
Object.assign(studyForm, newStudyData);
nextTick(() => formRef.value.validate());
copyDataDialog.value = false;
}

onMounted(() => {
formRef.value.validate();
});

return {
formRef,
copyDataDialog,
studyForm,
studyFormValid,
NmdcSchema,
Definitions,
addContributor,
requiredRules,
copyData,
copyInfoClicked,
};
},
});
Expand All @@ -45,9 +71,41 @@ export default defineComponent({
<div class="text-h2">
Study Information
</div>
<div class="text-h5">
<div class="text-h5 mb-1">
{{ NmdcSchema.$defs.Study.description }}
</div>
<v-btn
color="primary"
depressed
@click="copyInfoClicked"
>
<v-icon class="pr-1">
mdi-content-copy
</v-icon>
Copy from another submission
<v-dialog
v-model="copyDataDialog"
activator="parent"
>
<v-card>
<v-card-title>
Copy Study Data
</v-card-title>
<v-card-text>Copy study data from an existing submission.</v-card-text>
<submission-table
:action-title="`Copy`"
@submissionSelected="copyData"
/>
<v-card-actions>
<v-btn
@click="copyDataDialog = false"
>
Cancel
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-btn>
<v-form
ref="formRef"
v-model="studyFormValid"
Expand Down
117 changes: 10 additions & 107 deletions web/src/views/SubmissionPortal/Components/SubmissionList.vue
Original file line number Diff line number Diff line change
@@ -1,66 +1,19 @@
<script lang="ts">
import {
defineComponent, ref, watch,
} from '@vue/composition-api';
import { DataTableHeader } from 'vuetify';
import { defineComponent } from '@vue/composition-api';
import { useRouter } from '@/use/useRouter';
import usePaginatedResults from '@/use/usePaginatedResults';
import {
loadRecord, generateRecord, submissionStatus,
loadRecord, generateRecord,
} from '../store';
import * as api from '../store/api';
import { HARMONIZER_TEMPLATES } from '../harmonizerApi';
import SubmissionTable from './SubmissionTable.vue';

const headers: DataTableHeader[] = [
{
text: 'Study Name',
value: 'metadata_submission.studyForm.studyName',
sortable: false,
},
{
text: 'Author',
value: 'author.name',
sortable: false,
},
{
text: 'Template',
value: 'metadata_submission.templates',
sortable: false,
},
{
text: 'Status',
value: 'status',
sortable: false,
},
{
text: 'Created',
value: 'created',
sortable: false,
},
{
text: '',
value: 'action',
align: 'end',
sortable: false,
export default defineComponent({
components: {
SubmissionTable,
},
];

export default defineComponent({
setup() {
const router = useRouter();
const itemsPerPage = 10;
const options = ref({
page: 1,
itemsPerPage,
});

function getStatus(item: api.MetadataSubmissionRecord) {
const color = item.status === submissionStatus.Complete ? 'success' : 'default';
return {
text: item.status,
color,
};
}

async function resume(item: api.MetadataSubmissionRecord) {
await loadRecord(item.id);
Expand All @@ -72,17 +25,9 @@ export default defineComponent({
router?.push({ name: 'Submission Context', params: { id: item.id } });
}

const submission = usePaginatedResults(ref([]), api.listRecords, ref([]), itemsPerPage);
watch(options, () => submission.setPage(options.value.page), { deep: true });

return {
HARMONIZER_TEMPLATES,
createNewSubmission,
getStatus,
resume,
headers,
options,
submission,
};
},
});
Expand Down Expand Up @@ -111,51 +56,9 @@ export default defineComponent({
<v-card-text>
Pick up where you left off or review a previous submission.
</v-card-text>
<v-card outlined>
<v-data-table
:headers="headers"
:items="submission.data.results.results"
:server-items-length="submission.data.results.count"
:options.sync="options"
:loading="submission.loading.value"
:items-per-page.sync="submission.data.limit"
:footer-props="{ itemsPerPageOptions: [10, 20, 50] }"
>
<template #[`item.author.name`]="{ item }">
<a
:href="`https://orcid.org/${item.author.orcid}`"
rel="noopener noreferrer"
target="_blank"
>
{{ item.author.name || item.author.orcid }}
</a>
</template>
<template #[`item.metadata_submission.templates`]="{ item }">
{{ item.metadata_submission.templates.map((template) => HARMONIZER_TEMPLATES[template].displayName).join(' + ') }}
</template>
<template #[`item.created`]="{ item }">
{{ new Date(item.created).toLocaleString() }}
</template>
<template #[`item.status`]="{ item }">
<v-chip
:color="getStatus(item).color"
>
{{ getStatus(item).text }}
</v-chip>
</template>
<template #[`item.action`]="{ item }">
<v-btn
small
color="primary"
@click="() => resume(item)"
>
Resume
<v-icon class="pl-1">
mdi-arrow-right-circle
</v-icon>
</v-btn>
</template>
</v-data-table>
</v-card>
<SubmissionTable
:action-title="`Resume`"
@submissionSelected="resume"
/>
</v-card>
</template>
126 changes: 126 additions & 0 deletions web/src/views/SubmissionPortal/Components/SubmissionTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<script lang="ts">
import { defineComponent, ref, watch } from '@vue/composition-api';
import { DataTableHeader } from 'vuetify';
import usePaginatedResults from '@/use/usePaginatedResults';
import { HARMONIZER_TEMPLATES } from '../harmonizerApi';
import { submissionStatus } from '../store';
import * as api from '../store/api';

const headers: DataTableHeader[] = [
{
text: 'Study Name',
value: 'metadata_submission.studyForm.studyName',
sortable: false,
},
{
text: 'Author',
value: 'author.name',
sortable: false,
},
{
text: 'Template',
value: 'metadata_submission.templates',
sortable: false,
},
{
text: 'Status',
value: 'status',
sortable: false,
},
{
text: 'Created',
value: 'created',
sortable: false,
},
{
text: '',
value: 'action',
align: 'end',
sortable: false,
},
];

export default defineComponent({
props: {
actionTitle: {
type: String,
required: true,
},
},
setup() {
const itemsPerPage = 10;
const options = ref({
page: 1,
itemsPerPage,
});

function getStatus(item: api.MetadataSubmissionRecord) {
const color = item.status === submissionStatus.Complete ? 'success' : 'default';
return {
text: item.status,
color,
};
}

const submission = usePaginatedResults(ref([]), api.listRecords, ref([]), itemsPerPage);
watch(options, () => submission.setPage(options.value.page), { deep: true });

return {
HARMONIZER_TEMPLATES,
getStatus,
headers,
options,
submission,
};
},
});
</script>

<template>
<v-card outlined>
<v-data-table
:headers="headers"
:items="submission.data.results.results"
:server-items-length="submission.data.results.count"
:options.sync="options"
:loading="submission.loading.value"
:items-per-page.sync="submission.data.limit"
:footer-props="{ itemsPerPageOptions: [10, 20, 50] }"
>
<template #[`item.author.name`]="{ item }">
<a
:href="`https://orcid.org/${item.author.orcid}`"
rel="noopener noreferrer"
target="_blank"
>
{{ item.author.name || item.author.orcid }}
</a>
</template>
<template #[`item.metadata_submission.templates`]="{ item }">
{{ item.metadata_submission.templates.map((template) => HARMONIZER_TEMPLATES[template].displayName).join(' + ') }}
</template>
<template #[`item.created`]="{ item }">
{{ new Date(item.created).toLocaleString() }}
</template>
<template #[`item.status`]="{ item }">
<v-chip
:color="getStatus(item).color"
>
{{ getStatus(item).text }}
</v-chip>
</template>
<template #[`item.action`]="{ item }">
<v-btn
small
color="primary"
@click="$emit('submissionSelected', item)"
>
{{ actionTitle }}
<v-icon class="pl-1">
mdi-arrow-right-circle
</v-icon>
</v-btn>
</template>
</v-data-table>
</v-card>
</template>