diff --git a/microdraw/src/atlas_ui.js b/microdraw/src/atlas_ui.js index 100c362bce023d7aa8f4f7418237fbed52c5743b..7d1324f2d222405ed8efa37e5fa3c15c81aec269 100644 --- a/microdraw/src/atlas_ui.js +++ b/microdraw/src/atlas_ui.js @@ -123,10 +123,10 @@ var app = new Vue({ task_wizard: { loading: false, section_data: [], - selected_item: null, selected_task: new Task(), section_naming: false, tasks: [], + import_text: null, }, }, computed: { @@ -854,11 +854,16 @@ var app = new Vue({ taskWizardRemoveAll: function(task) { task.annotations.splice(0, task.annotations.length); }, + taskWizardResetTask: function(task) { + this.task_wizard.selected_task = new Task(); + if (task) { + // Remember settings from last task + this.task_wizard.selected_task.no_aux_labels = task.no_aux_labels; + } + }, taskWizardAddTask: function(task) { this.task_wizard.tasks.push(task); - this.task_wizard.selected_task = new Task(); - // Remember settings from last task - this.task_wizard.selected_task.no_aux_labels = task.no_aux_labels; + this.taskWizardResetTask(task); }, taskWizardRemoveTask: function(index) { this.task_wizard.tasks.splice(index, 1); @@ -875,6 +880,95 @@ var app = new Vue({ } this.task_wizard.tasks.splice(0, this.task_wizard.tasks.length); }, + taskWizardImport: function() { + // Only allow this with a filter! + if (!this.annotation_filter) { + alert("A filter is required to perform import. If you really want everything, use '.*' as filter."); + return; + } + + // Enable automatic renaming + this.task_wizard.section_naming = true; + + // Get import text and search for section numbers per line + let import_text = this.task_wizard.import_text; + let pattern = /(?<section>\d+)/g; + + // Create a new task + this.taskWizardResetTask(this.task_wizard.selected_task); + + // Save added tasks + let added_tasks = []; + + // Split by lines + let lines = import_text.split("\n"); + for (let linei in lines) { + + // Deselect all sections + for (let section_item in this.task_wizard.section_data) { + section_item = this.task_wizard.section_data[section_item]; + section_item.selected = false; + } + + let line = lines[linei]; + let match = line.match(pattern); + let abort = false; + // Search for selected sections + for (let mi=0; mi<match.length; mi++) { + let section = parseInt(match[mi]); + let found = false; + + for (let section_item in this.task_wizard.section_data) { + section_item = this.task_wizard.section_data[section_item]; + if (section == section_item.section) { + // Found section, select it + section_item.selected = true; + found = true; + break; + } + } + + if (!found) { + alert(`Could not find section ${section}!`); + abort = true; + break; + } + } + + if (!abort) { + // add all annotations + this.taskWizardAddAll(this.task_wizard.selected_task); + if (this.task_wizard.selected_task.annotations) { + // Add tha task if it has annotations + added_tasks.push(this.task_wizard.selected_task); + this.taskWizardSetTaskName(); + this.taskWizardAddTask(this.task_wizard.selected_task); + } else { + // ...abort if it does not + alert(`No annotations matching the filter for line ${line}!`); + abort = true; + } + } + + // Abort and revoke all changes + if (abort) { + // Remove all added tasks and break + for (let taski in added_tasks) { + this.taskWizardRemoveTask(added_tasks[taski]); + } + break; + } + } + + + // Deselect all sections + for (let section_item in this.task_wizard.section_data) { + section_item = this.task_wizard.section_data[section_item]; + section_item.selected = false; + } + + alert(`Added ${added_tasks.length} tasks! You may now close this dialogue.`); + }, queryAnnotationsForSections: function(sections) { // Query annotations or specific section from microdraw database // based on microdraw.json:microdrawDBLoad diff --git a/microdraw/src/microdraw.html b/microdraw/src/microdraw.html index e47e4466958a387d5bbf0557784f91f11d1b1d8f..e9092421892ab31d4c29aa7be2ae27ef740feb61 100755 --- a/microdraw/src/microdraw.html +++ b/microdraw/src/microdraw.html @@ -446,6 +446,9 @@ <button type="button" class="btn btn-primary" v-on:click="taskWizardSectionSelect(true)" :disabled="task_wizard.section_data.length == 0">Enable all</button> <button type="button" class="btn btn-danger" v-on:click="taskWizardSectionSelect(false)" :disabled="task_wizard.section_data.length == 0">Disable all</button> </div> + <div class="btn-group" role="group" id="atlas_ui_task_wizard_section_controls2"> + <button type="button" class="btn btn-success" data-toggle="modal" data-target="#atlas_ui_task_wizard_import_modal">Import</button> + </div> </div> <!-- Annotations --> @@ -569,6 +572,33 @@ </div> </div> + <div class="modal fade" id="atlas_ui_task_wizard_import_modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" role="dialog"> + <div class="modal-dialog modal-xl" role="document"> + <div class="modal-content"> + <!-- Header of dialogue --> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalLabel">Import</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + + <!-- Body of dialogue --> + <div class="modal-body"> + <div class="container col-12"> + <div class="row"> + <textarea class="form-control" id="atlas_ui_task_wizard_import_text" v-model="task_wizard.import_text" placeholder="Enter sections to import. One task per line."></textarea> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" v-on:click="taskWizardImport()">Import</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + </div> + </div> + </div> + </div> + <div class="modal fade" id="atlas_ui_jobs_modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" v-if="selected_task !== null"> <div class="modal-dialog modal-lg" role="document">