Skip to content

Commit

Permalink
WIP #78 prj request metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
eboileau committed Apr 15, 2024
1 parent 0a2825b commit 2c2b837
Show file tree
Hide file tree
Showing 9 changed files with 576 additions and 141 deletions.
243 changes: 119 additions & 124 deletions client/package-lock.json

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,31 @@
"format": "prettier --write src/"
},
"dependencies": {
"axios": "^1.6.7",
"axios": "^1.6.8",
"jwt-decode": "^4.0.0",
"pinia": "^2.1.7",
"primeicons": "^6.0.1",
"primevue": "^3.49.1",
"vee-validate": "^4.12.5",
"primeicons": "^7.0.0",
"primevue": "^3.51.0",
"vee-validate": "^4.12.6",
"vite-svg-loader": "^4.0.0",
"vue": "^3.2.47",
"vue-cookies": "^1.8.3",
"vue-cookies": "^1.8.4",
"vue-router": "^4.3.0",
"yup": "^1.4.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.7.2",
"@rushstack/eslint-patch": "^1.10.2",
"@vitejs/plugin-vue": "^4.6.2",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/test-utils": "^2.4.4",
"autoprefixer": "^10.4.18",
"@vue/test-utils": "^2.4.5",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.22.0",
"eslint-plugin-vue": "^9.25.0",
"jsdom": "^21.1.2",
"postcss": "^8.4.35",
"postcss": "^8.4.38",
"prettier": "^2.8.8",
"tailwindcss": "^3.4.1",
"vite": "^4.5.2",
"tailwindcss": "^3.4.3",
"vite": "^4.5.3",
"vitest": "^0.29.8"
}
}
30 changes: 26 additions & 4 deletions client/src/components/project/ProjectForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import FormTextInput from '@/components/ui/FormTextInput.vue'
import FormTextArea from '@/components/ui/FormTextArea.vue'
import FormButton from '@/components/ui/FormButton.vue'
const props = defineProps(['nextCallback'])
const model = defineModel()
const validationSchema = object({
forename: string().required('Forename is required!'),
surname: string().required('Surname is required!'),
Expand All @@ -33,11 +36,17 @@ const validationSchema = object({
)
})
const getInitialValues = () => {
if (model.value === undefined) {
return { doi: '', pmid: null }
} else {
return { ...model.value }
}
}
const { defineField, handleSubmit, errors } = useForm({
validationSchema: validationSchema,
initialValues: {
sources: [{ doi: '', pmid: null }]
}
initialValues: getInitialValues()
})
const [forename, forenameProps] = defineField('forename')
const [surname, surnameProps] = defineField('surname')
Expand All @@ -52,6 +61,8 @@ const { remove, push, fields } = useFieldArray('sources')
const onSubmit = handleSubmit((values) => {
// Submit to API
console.log(values)
model.value = values
props.nextCallback()
})
onMounted(() => {
Expand Down Expand Up @@ -127,7 +138,18 @@ onMounted(() => {
</div>

<br />
<FormButton type="submit">Submit</FormButton>
<div class="flex pt-4 justify-end">
<Button
type="submit"
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
class="p-4 text-primary-50 border border-white-alpha-30"
>
</Button>
<!-- <div class="flex pt-4 justify-end">
<FormButton type="submit">Nexat</FormButton> -->
</div>
</form>
</div>
</SectionLayout>
Expand Down
204 changes: 204 additions & 0 deletions client/src/components/project/ProjectMetaData.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<script setup>
import { ref, onMounted } from 'vue'
import { useForm, useFieldArray } from 'vee-validate'
import { object, array, string, number, date } from 'yup'
import { HTTPSecure } from '@/services/API'
import { toTree, toCascade, nestedSort, toIds } from '@/utils/index.js'
import { HTTP } from '@/services/API.js'
import {
updModification,
updOrganismFromMod,
updTechnologyFromModAndOrg,
updSelectionFromAll
} from '@/utils/selection.js'
const modification = ref()
const method = ref()
const selectedModification = ref()
const selectedMethod = ref()
const selectedType = ref()
// TODO define in BE
const rna = ref([{ key: 'mRNA' }, { key: 'rRNA' }])
import FormDropdown from '@/components/ui/FormDropdown.vue'
import FormTextInput from '@/components/ui/FormTextInput.vue'
import FormTextArea from '@/components/ui/FormTextArea.vue'
import FormButton from '@/components/ui/FormButton.vue'
const props = defineProps(['nextCallback'])
const model = defineModel()
const validationSchema = object({
metadata: array().of(
object().shape({
rna: string().required('RNA type is required@'),
modification: string().required('Modification is required!'),
method: string().required('Method is required!'),
technology: string().required('Technology is required!'),
taxid: number().integer(),
organism: string(),
assembly: string(), //?
note: string()
})
)
})
// const getInitialValues = () => {
// if (model.value === undefined) {
// return { doi: '', pmid: null }
// } else {
// return { ...model.value}
// }
// }
const { defineField, handleSubmit, errors } = useForm({
validationSchema: validationSchema
// initialValues: getInitialValues()
})
// const [forename, forenameProps] = defineField('forename')
// const [surname, surnameProps] = defineField('surname')
// const [institution, institutionProps] = defineField('institution')
// const [email, emailProps] = defineField('email')
// const [title, titleProps] = defineField('title')
// const [summary, summaryProps] = defineField('summary')
// const [published, publishedProps] = defineField('published')
const { remove, push, fields } = useFieldArray('metadata')
const onSubmit = handleSubmit((values) => {
// Submit to API
console.log(values)
// model.value = values
// props.nextCallback()
})
onMounted(() => {
HTTP.get('/modification')
.then(function (response) {
modification.value = response.data
})
.catch((error) => {
console.log(error)
})
HTTP.get('/method')
.then(function (response) {
method.value = toCascade(toTree(response.data, ['cls', 'meth'], 'id'))
// console.log(method.value)
nestedSort(method.value, ['child1'])
// console.log('2', method.value)
})
.catch((error) => {
console.log(error)
})
})
</script>

<template>
<SectionLayout>
<div>
<form @submit.prevent="onSubmit">
<!-- <h3 class="dark:text-white/80">Your contact details</h3> -->

<h3 class="mt-4 mb-2 dark:text-white/80">Project metadata...</h3>
<Button
@click="
push({
rna: '',
modification: '',
method: '',
technology: '',
taxid: '',
organism: '',
assembly: '',
note: ''
})
"
label="Add metadata"
/>
<div class="grid grid-cols-2 gap-4 mt-2" v-for="(field, idx) in fields" :key="field.key">
<FormDropdown
v-model.getKey="field.value.rna"
:options="rna"
optionLabel="key"
:error="errors[`metadata[${idx}].rna`]"
placeholder="Select RNA type"
>RNA type</FormDropdown
>
<Dropdown
v-model="selectedModification"
@change="field.value.modification = selectedModification.id"
editable
:options="modification"
optionLabel="modomics_sname"
placeholder="Select RNA modification"
/>

<div class="inline-flex flex-col gap-2">
<label for="meth" class="text-primary-500 font-semibold"> Method </label>
<CascadeSelect
id="meth"
v-model="selectedMethod"
@change="field.value.method = selectedMethod.key"
:options="method"
optionLabel="label"
optionGroupLabel="label"
:optionGroupChildren="['child1', 'child2']"
placeholder="Select method"
:class="errors[`metadata[${idx}].method`] ? '!ring-red-700' : ''"
/>
<span class="inline-flex items-baseline">
<i
:class="
errors[`metadata[${idx}].method`]
? 'pi pi-times-circle place-self-center text-red-700'
: ''
"
/>
<span :class="['pl-1 place-self-center', props.errMsgCls]"
>{{ errors[`metadata[${idx}].method`] }}&nbsp;</span
>
</span>
</div>

<FormTextInput
v-model="field.value.technology"
:error="errors[`metadata[${idx}].technology`]"
placeholder="Tech-seq"
>Technology</FormTextInput
>
{{ fields }}
<!-- <FormTextInput
v-model="field.value.doi"
:error="errors[`sources[${idx}].doi`]"
placeholder="10.XXXX/..."
>DOI</FormTextInput
>
<FormTextInput
v-model="field.value.pmid"
:error="errors[`sources[${idx}].pmid`]"
placeholder="PubMed-ID"
>PMID</FormTextInput
> -->
<div class="place-self-start self-center">
<Button @click="remove(idx)" label="Remove" />
</div>
</div>

<br />
<div class="flex pt-4 justify-end">
<Button
type="submit"
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
class="p-4 text-primary-50 border border-white-alpha-30"
>
</Button>
</div>
</form>
</div>
</SectionLayout>
</template>
72 changes: 72 additions & 0 deletions client/src/components/ui/FormDropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script setup>
// const model = defineModel()
const [model, modifiers] = defineModel({
set(value) {
if (modifiers.getKey) {
return value.key
}
return value
}
})
const props = defineProps({
error: {
required: true
},
options: {
type: Array,
required: true
},
optionLabel: {
type: String,
required: false,
default: 'label'
},
placeholder: {
type: String,
required: false,
default: ''
},
labelCls: {
type: String,
required: false,
default: 'text-primary-500 font-semibold'
},
errMsgCls: {
type: String,
required: false,
default: 'text-red-700'
},
errIconCls: {
type: String,
required: false,
default: 'pi pi-times-circle place-self-center text-red-700'
},
// overwrites component style in case of error
errCls: {
type: String,
required: false,
default: '!ring-red-700'
}
})
</script>

<template>
<div class="inline-flex flex-col gap-2">
<label for="field" :class="props.labelCls">
<slot></slot>
</label>
<Dropdown
id="field"
v-model="model"
:options="options"
:optionLabel="optionLabel"
:placeholder="props.placeholder"
:class="error ? props.errCls : ''"
/>
<span class="inline-flex items-baseline">
<i :class="error ? props.errIconCls : ''" />
<span :class="['pl-1 place-self-center', props.errMsgCls]">{{ error }}&nbsp;</span>
</span>
</div>
</template>
4 changes: 4 additions & 0 deletions client/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import Panel from 'primevue/panel'
import ProgressSpinner from 'primevue/progressspinner'
import RadioButton from 'primevue/radiobutton'
import Row from 'primevue/row'
import Stepper from 'primevue/stepper'
import StepperPanel from 'primevue/stepperpanel'
import TabPanel from 'primevue/tabpanel'
import TabView from 'primevue/tabview'
import Textarea from 'primevue/textarea'
Expand Down Expand Up @@ -67,6 +69,8 @@ app.component('Panel', Panel)
app.component('ProgressSpinner', ProgressSpinner)
app.component('RadioButton', RadioButton)
app.component('Row', Row)
app.component('Stepper', Stepper)
app.component('StepperPanel', StepperPanel)
app.component('TabPanel', TabPanel)
app.component('TabView', TabView)
app.component('Textarea', Textarea)
Expand Down
Loading

0 comments on commit 2c2b837

Please sign in to comment.