Skip to content

Commit

Permalink
WIP #78
Browse files Browse the repository at this point in the history
  • Loading branch information
eboileau committed Apr 16, 2024
1 parent 2c2b837 commit 987455e
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 75 deletions.
271 changes: 196 additions & 75 deletions client/src/components/project/ProjectMetaData.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ import {
updSelectionFromAll
} from '@/utils/selection.js'
const modification = ref()
const method = ref()
const modification = ref([])
const method = ref([])
const taxid = ref([])
const assembly = ref([])
const selectedModification = ref()
const selectedMethod = ref()
const selectedType = ref()
const selectedTaxid = ref()
const selectedAssembly = ref()
// TODO define in BE
const rna = ref([{ key: 'mRNA' }, { key: 'rRNA' }])
const rna = ref(['mRNA', 'rRNA'])
import FormDropdown from '@/components/ui/FormDropdown.vue'
Expand All @@ -34,47 +38,70 @@ 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!'),
rna: string().required('RNA type is required!'), //.nullable().transform((value) => !!value ? value : null),
modification: string().required('Modification is required!'), //.nullable().transform((value) => !!value ? value : null),
method: string().required('Method is required!'), //.nullable().transform((value) => !!value ? value : null),
technology: string().required('Technology is required!'),
taxid: number().integer(),
organism: string(),
assembly: string(), //?
taxid: number().integer().required('Organism is a required field!'),
organism: string().required('Cell, tissue, or organ is required!'),
assembly: number()
.integer()
.typeError('Assembly ID must be a number!')
.transform((_, val) => (val !== '' ? Number(val) : null)),
freeAssembly: 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 initialValues = {
rna: '',
modification: '',
method: '',
technology: '',
taxid: null,
organism: '',
assembly: null,
freeAssembly: '',
note: ''
}
const getInitialValues = () => {
if (model.value === undefined) {
return initialValues
} else {
return { ...model.value }
}
}
console.log('INITIAL', getInitialValues())
const { 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')
console.log('FIELDS', fields)
const onSubmit = handleSubmit((values) => {
// Submit to API
console.log('ON SUBMIT')
console.log(values)
// model.value = values
// props.nextCallback()
})
const getAssemblies = () => {
HTTP.get(`/assembly/${selectedTaxid.value.key}`)
.then(function (response) {
assembly.value = response.data
})
.catch((error) => {
console.log(error)
})
}
onMounted(() => {
HTTP.get('/modification')
.then(function (response) {
Expand All @@ -93,6 +120,19 @@ onMounted(() => {
.catch((error) => {
console.log(error)
})
HTTP.get('/taxid')
.then(function (response) {
let opts = response.data
opts = opts.map((item) => {
const kingdom = Object.is(item.kingdom, null) ? item.domain : item.kingdom
return { ...item, kingdom }
})
taxid.value = toCascade(toTree(opts, ['kingdom', 'taxa_sname'], 'id'))
nestedSort(taxid.value, ['child1'])
})
.catch((error) => {
console.log(error)
})
})
</script>

Expand All @@ -103,43 +143,59 @@ onMounted(() => {
<!-- <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"
/>
<Button @click="push(initialValues)" 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>
<label for="rnaDropdown" class="text-primary-500 font-semibold"> RNA type </label>
<Dropdown
id="rnaDropdown"
v-model="field.value.rna"
:options="rna"
placeholder="Select RNA type"
:class="errors[`metadata[${idx}].rna`] ? '!ring-red-700' : ''"
/>
<span class="inline-flex items-baseline">
<i
:class="
errors[`metadata[${idx}].rna`]
? 'pi pi-times-circle place-self-center text-red-700'
: ''
"
/>
<span :class="['pl-1 place-self-center', 'text-red-700']"
>{{ errors[`metadata[${idx}].rna`] }}&nbsp;</span
>
</span>
</div>
<div class="inline-flex flex-col gap-2">
<label for="modDropdown" class="text-primary-500 font-semibold"> Modification </label>
<Dropdown
id="modDropdown"
v-model="selectedModification"
@change="field.value.modification = selectedModification.id"
editable
:options="modification"
optionLabel="modomics_sname"
placeholder="Select RNA modification"
:class="errors[`metadata[${idx}].modification`] ? '!ring-red-700' : ''"
/>
<span class="inline-flex items-baseline">
<i
:class="
errors[`metadata[${idx}].modification`]
? 'pi pi-times-circle place-self-center text-red-700'
: ''
"
/>
<span :class="['pl-1 place-self-center', 'text-red-700']"
>{{ errors[`metadata[${idx}].modification`] }}&nbsp;</span
>
</span>
</div>
<div class="inline-flex flex-col gap-2">
<label for="methDropdown" class="text-primary-500 font-semibold"> Method </label>
<CascadeSelect
id="meth"
id="methDropdown"
v-model="selectedMethod"
@change="field.value.method = selectedMethod.key"
:options="method"
Expand All @@ -157,31 +213,96 @@ onMounted(() => {
: ''
"
/>
<span :class="['pl-1 place-self-center', props.errMsgCls]"
<span :class="['pl-1 place-self-center', 'text-red-700']"
>{{ errors[`metadata[${idx}].method`] }}&nbsp;</span
>
</span>
</div>

<FormTextInput
v-model="field.value.technology"
:error="errors[`metadata[${idx}].technology`]"
placeholder="Tech-seq"
>Technology</FormTextInput
>
<div class="inline-flex flex-col gap-2">
<label for="orgDropdown" class="text-primary-500 font-semibold"> Organism </label>
<CascadeSelect
id="orgDropdown"
v-model="selectedTaxid"
@change="
field.value.taxid = selectedTaxid.key
getAssemblies()
"
:options="taxid"
optionLabel="label"
optionGroupLabel="label"
:optionGroupChildren="['child1']"
placeholder="Select organism"
:class="errors[`metadata[${idx}].taxid`] ? '!ring-red-700' : ''"
/>
<span class="inline-flex items-baseline">
<i
:class="
errors[`metadata[${idx}].taxid`]
? 'pi pi-times-circle place-self-center text-red-700'
: ''
"
/>
<span :class="['pl-1 place-self-center', props.errMsgCls]"
>{{ errors[`metadata[${idx}].taxid`] }}&nbsp;</span
>
</span>
</div>
<FormTextInput
v-model="field.value.organism"
:error="errors[`metadata[${idx}].organism`]"
placeholder="e.g. HeLa, mESC, or Heart"
>Cell, tissue, organ</FormTextInput
>
<div class="inline-flex flex-col gap-2">
<label for="asmbDropdown" class="text-primary-500 font-semibold">
Assembly (select from existing assemblies)
</label>
<Dropdown
id="asmbDropdown"
v-model="selectedAssembly"
@change="field.value.assembly = selectedAssembly.id"
:options="assembly"
optionLabel="name"
placeholder="Select assembly"
:class="errors[`metadata[${idx}].assembly`] ? '!ring-red-700' : ''"
/>
<span class="inline-flex items-baseline">
<i
:class="
errors[`metadata[${idx}].assembly`]
? 'pi pi-times-circle place-self-center text-red-700'
: ''
"
/>
<span :class="['pl-1 place-self-center', 'text-red-700']"
>{{ errors[`metadata[${idx}].assembly`] }}&nbsp;</span
>
</span>
</div>
<FormTextInput
v-model="field.value.freeAssembly"
:error="errors[`metadata[${idx}].freeAssembly`]"
placeholder="e.g. NCBI36 (Ensembl release 54)"
>Assembly (if not available)</FormTextInput
>
<FormTextArea
v-model="field.value.note"
:error="errors[`metadata[${idx}].note`]"
placeholder="Tech-seq sources: 10.XXXX/... This metadata template is for published data (PubMed-ID, GEO, ...), etc."
>
Additional notes for this metadata template.
</FormTextArea>
FIELDS:
{{ 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
> -->
<br />
ERRORS:
{{ errors }}
<div class="place-self-start self-center">
<Button @click="remove(idx)" label="Remove" />
</div>
Expand Down
14 changes: 14 additions & 0 deletions server/src/scimodom/api/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ def get_method():
return public_service.get_detection_method()


@api.route("/taxid", methods=["GET"])
@cross_origin(supports_credentials=True)
def get_taxid():
public_service = get_public_service()
return public_service.get_taxa()


@api.route("/assembly/<taxid>", methods=["GET"])
@cross_origin(supports_credentials=True)
def get_assembly(taxid):
public_service = get_public_service()
return public_service.get_assembly_for_taxid(taxid)


@api.route("/selection", methods=["GET"])
@cross_origin(supports_credentials=True)
def get_selection():
Expand Down
29 changes: 29 additions & 0 deletions server/src/scimodom/services/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ def get_detection_method(self):
query = select(DetectionMethod.id, DetectionMethod.cls, DetectionMethod.meth)
return self._dump(query)

def get_taxa(self):
"""Get all organisms with their taxonomy.
:returns: Query result
:rtype: list of dict
"""

query = select(
Taxa.id,
Taxa.short_name.label("taxa_sname"),
Taxonomy.domain,
Taxonomy.kingdom,
Taxonomy.phylum,
).join_from(Taxa, Taxonomy, Taxa.inst_taxonomy)

return self._dump(query)

def get_assembly_for_taxid(self, taxid: int):
"""Get available assemblies for given Taxa ID.
:param taxid: Taxa ID
:type taxid: int
:returns: Query result
:rtype: list of dict
"""

query = select(Assembly.id, Assembly.name).where(Assembly.taxa_id == taxid)
return self._dump(query)

def get_selection(self):
"""Get available selections.
Expand Down

0 comments on commit 987455e

Please sign in to comment.