Skip to content

Commit

Permalink
Improve Add Study logic ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
Freymaurer committed Nov 16, 2023
1 parent 2c39e0e commit b671ecc
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 36 deletions.
1 change: 0 additions & 1 deletion packages/main/src/mainWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ contextMenu({
});

async function createWindow() {
console.log("HIT; ", join(__dirname, './../../../ressources/icon.png'))
const mainWindow = new BrowserWindow({
show: false, // Use 'ready-to-show' event to show window
webPreferences: {
Expand Down
6 changes: 5 additions & 1 deletion packages/renderer/src/AppProperties.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { reactive } from 'vue'

const AppProperties = reactive({
const AppProperties: {
STATES: any,
active_study: string | null
active_assay: string | null
} = reactive({
STATES: {
HOME: 0,

Expand Down
4 changes: 2 additions & 2 deletions packages/renderer/src/components/FormInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const isValidTerm = ()=>{
</div>

<q-checkbox
v-else-if='props.property.type==="checkbox"'
v-else-if='props.property.type === "checkbox"'
v-model="props.property.model[props.property.property]"
:label="props.property.label"
color='secondary'
Expand All @@ -135,7 +135,7 @@ const isValidTerm = ()=>{
</q-checkbox>

<q-input
v-else-if='props.property.type!=="select"'
v-else-if='props.property.type !== "select"'

:style="`margin:0 0.5em ${props.property.hint?2:-0.5}em 0.5em;`"
:bg-color="props.property.dirty() ? 'teal-1':'grey-3'"
Expand Down
133 changes: 113 additions & 20 deletions packages/renderer/src/dialogs/NewAssayDialog.vue
Original file line number Diff line number Diff line change
@@ -1,56 +1,131 @@
<script lang="ts" setup>
import { useDialogPluginComponent } from 'quasar';
import { reactive, onMounted, watch } from 'vue';
import { reactive, onMounted, watch, ref } from 'vue';
import FormInput from '../components/FormInput.vue';
import Property from '../Property.ts';
import ArcControlService from '../ArcControlService.ts';
const iProps = reactive({
import {ArcStudy} from "@nfdi4plants/arctrl"
import {checkValidCharacters} from '@nfdi4plants/arctrl/ISA/ISA/Identifier.js'
export type NewAssayInformation = {
assayIdentifier: string
studyIdentifier: string [] | null
}
const iProps : {
valid: boolean,
errorMsgs: string [],
assay_identifier: string
study_identifier: string [],
studies: string []
existingStudies: string [],
form: any []
} = reactive({
valid: true,
errorMsgs: [],
assay_identifier: '',
// This value contains the selected study identifiers, for which the new assay will be registered
study_identifier: [],
// This value contains the currently available select options
// (this can differ from existingStudies if new options are added)
studies: [],
// This value always contains only the existing study identifiers from ARC model
existingStudies: [],
form: []
});
let filterOptions = ref(iProps.studies)
defineEmits([
...useDialogPluginComponent.emits
]);
const createStudyString = 'Create New Study';
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
const onSubmit = async () => {
iProps.valid = iProps.assay_identifier && iProps.study_identifier.length;
if(!iProps.valid)
return;
onDialogOK([iProps.assay_identifier,iProps.study_identifier.includes(createStudyString) ? [] : iProps.study_identifier]);
if (iProps.assay_identifier === ``) {
iProps.valid = false;
iProps.errorMsgs.push('Assay Identifier cannot be empty!')
}
if (!iProps.valid) return;
const newAssayInformation : NewAssayInformation = {assayIdentifier: iProps.assay_identifier, studyIdentifier: iProps.study_identifier}
onDialogOK(newAssayInformation);
};
const init = async ()=>{
iProps.studies = ArcControlService.props.arc.ISA.Studies.map(s => s.Identifier).sort();
let arcStudies = ArcControlService.props.arc.ISA.Studies.map((s: ArcStudy) => s.Identifier).sort();
iProps.studies = arcStudies
iProps.existingStudies = arcStudies
iProps.assay_identifier = '';
iProps.study_identifier = [createStudyString];
iProps.study_identifier = [];
iProps.form = [
[Property( iProps, 'assay_identifier', {label:'Assay Identifier'})],
[Property( iProps, 'study_identifier', {label:'Study Identifier',type:'select',multi:true, options:iProps.studies})]
];
};
onMounted(init);
watch( ()=>iProps.study_identifier, ()=>{
if(iProps.study_identifier.length>1 && iProps.study_identifier.includes(createStudyString)){
iProps.study_identifier.splice(iProps.study_identifier.indexOf(createStudyString),1);
} else if(iProps.study_identifier.length<1){
iProps.study_identifier = [createStudyString];
function resetErrors() {
iProps.valid = true;
iProps.errorMsgs = [];
}
watch( () => [iProps.study_identifier, iProps.assay_identifier], () =>{
resetErrors();
for (let study of iProps.study_identifier)
try {
if (study !== '') checkValidCharacters(study)
} catch (error) {
iProps.valid = false;
iProps.errorMsgs.push(`Invalid Identifier for: "${study}": ${error}`)
}
try {
if (iProps.assay_identifier !== '') checkValidCharacters(iProps.assay_identifier)
} catch (error) {
iProps.valid = false;
iProps.errorMsgs.push(`Invalid Identifier for: "${iProps.assay_identifier}": ${error}`)
}
});
function filterStudyIdentifiers (val, update) {
update(() => {
if (val === '') {
filterOptions.value = iProps.studies
}
else {
const needle = val.toLowerCase()
filterOptions.value = iProps.studies.filter(
v => v.toLowerCase().indexOf(needle) > -1
)
}
})
}
function createNewStudyIdentifier (val, done) {
if (val.length > 0) {
if (!iProps.studies.includes(val)) {
iProps.studies.push(val)
}
done(val, 'toggle')
}
}
// this does not work currently:
// https://github.com/quasarframework/quasar/discussions/16602
function clearStudyIdentifier (val: any) {
console.log("HIT")
let index = iProps.study_identifier.indexOf(val)
iProps.study_identifier.splice(index)
if (!iProps.existingStudies.includes(val)) {
console.log("cleared non existing study")
let index = iProps.studies.indexOf(val)
iProps.studies.splice(index)
}
return;
}
</script>

<template>
Expand All @@ -69,13 +144,31 @@ watch( ()=>iProps.study_identifier, ()=>{
<FormInput :property='property'></FormInput>
</div>
</div>

<q-select
filled
label="Study Identifiers"
v-model="iProps.study_identifier"
:style="`margin:0 0.5em -0.5em 0.5em;`"
bg-color="grey-3"
use-input
use-chips
multiple
input-debounce="0"
new-value-mode="add-unique"
:options="filterOptions"
hint="You can add new studies from here."
@new-value="createNewStudyIdentifier"
@filter="filterStudyIdentifiers"
@clear="clearStudyIdentifier"
/>
<div style="min-height:3.5em;margin:1em 1em -1em 1em;">
<q-banner rounded inline-actions class="bg-red-10 text-white" v-if='!iProps.valid' dense>
<template v-slot:avatar>
<q-icon name="warning"/>
</template>
<b>Identifier and Study Association are Required.</b>
<ul>
<li v-for="error in iProps.errorMsgs">{{error}}</li>
</ul>
</q-banner>
</div>
</q-card-section>
Expand Down
34 changes: 22 additions & 12 deletions packages/renderer/src/views/ArcTreeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import ArcControlService from '../ArcControlService';
import StringDialog from '../dialogs/StringDialog.vue';
import AddProtocolDialog from '../dialogs/AddProtocolDialog.vue';
import NewAssayDialog from '../dialogs/NewAssayDialog.vue';
import { NewAssayInformation } from '../dialogs/NewAssayDialog.vue';
import { useQuasar } from 'quasar'
import {ArcStudy, ArcAssay} from '@nfdi4plants/arctrl/ISA/ISA/ArcTypes/ArcTypes.js';
const $q = useQuasar();
interface ArcTreeViewNode {
Expand Down Expand Up @@ -104,21 +106,29 @@ const addStudy = async ()=>{
const addAssay = async ()=>{
$q.dialog({
component: NewAssayDialog
}).onOk( async data => {
if(data[1].length<1){
await addStudy_(data[0],true);
data[1].push(data[0]);
}
const assay = new ArcAssay(data[0]);
}).onOk( async (data: NewAssayInformation) => {
// if(data[1].length<1){
// await addStudy_(data[0],true);
// data[1].push(data[0]);
// }
const assay = new ArcAssay(data.assayIdentifier);
ArcControlService.props.arc.ISA.AddAssay(assay);
for(let study of data[1])
ArcControlService.props.arc.ISA.RegisterAssay(study,data[0]);
await ArcControlService.writeARC(ArcControlService.props.arc_root);
if (data.studyIdentifier !== null) {
for(let studyIdentifier of data.studyIdentifier)
try {
ArcControlService.props.arc.ISA.RegisterAssay(studyIdentifier,data.assayIdentifier);
} catch {
console.log("Unfound study identifier: '", studyIdentifier, "'. Created new Study for identifier.")
const study = new ArcStudy(studyIdentifier);
ArcControlService.props.arc.ISA.AddRegisteredStudy(study);
ArcControlService.props.arc.ISA.RegisterAssay(studyIdentifier,data.assayIdentifier);
}
};
await ArcControlService.writeARC(ArcControlService.props.arc_root, undefined, undefined);
await ArcControlService.readARC();
AppProperties.active_assay = data[0];
AppProperties.active_assay = data.assayIdentifier;
});
};
Expand Down

0 comments on commit b671ecc

Please sign in to comment.