mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-21 20:44:45 +08:00
Create a modal for item assignment from inventory page [SCI-8250]
- Fix the behavior of the search_select. - Fix select options positioning. - Get the items to assign from selected rows. - Style the modal. Style the modal [SCI-8250] Fix select options positioning [SCI-8250]
This commit is contained in:
parent
443cd21090
commit
5f8eafedf9
7 changed files with 225 additions and 88 deletions
|
@ -278,6 +278,10 @@ var RepositoryDatatable = (function(global) {
|
|||
});
|
||||
}
|
||||
|
||||
function updateSelectedRowsForAssignments() {
|
||||
window.AssignItemsToTaskModalComponent.setShowCallback(() => rowsSelected);
|
||||
}
|
||||
|
||||
function checkAvailableColumns() {
|
||||
$.ajax({
|
||||
url: $(TABLE_ID).data('available-columns'),
|
||||
|
@ -732,6 +736,7 @@ var RepositoryDatatable = (function(global) {
|
|||
})
|
||||
|
||||
initRowSelection();
|
||||
updateSelectedRowsForAssignments();
|
||||
// $(window).resize(() => {
|
||||
// setTimeout(() => {
|
||||
// adjustTableHeader();
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
.assign-items-to-task-modal-container {
|
||||
.modal-header {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
color: $color-volcano;
|
||||
font-size: $font-size-h2;
|
||||
font-weight: bold;
|
||||
|
||||
.close {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
color: $color-volcano;
|
||||
font-size: $font-size-base;
|
||||
|
||||
.level-selector {
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
gap: .25rem;
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
font-weight: bold;
|
||||
font-size: $font-size-h6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ Vue.prototype.i18n = window.I18n;
|
|||
function initAssignItemsToTaskModalComponent() {
|
||||
const container = $('.assign-items-to-task-modal-container');
|
||||
if (container.length) {
|
||||
window.AssignItemsToTaskModalComponent = new Vue({
|
||||
window.AssignItemsToTaskModalComponentContainer = new Vue({
|
||||
el: '.assign-items-to-task-modal-container',
|
||||
name: 'AssignItemsToTaskModalComponent',
|
||||
components: {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
role="dialog"
|
||||
aria-labelledby="assignItemsToTaskModalLabel"
|
||||
>
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-dialog modal-sm" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">
|
||||
|
@ -29,23 +29,39 @@
|
|||
}}
|
||||
</div>
|
||||
|
||||
<div class="project-selector">
|
||||
<div class="project-selector level-selector">
|
||||
<label>
|
||||
{{ i18n.t("repositories.modal_assign_items_to_task.body.project_select.label") }}
|
||||
{{
|
||||
i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.project_select.label"
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
|
||||
<SelectSearch
|
||||
ref="projectsSelector"
|
||||
@change="changeProject"
|
||||
:options="projects"
|
||||
:placeholder="i18n.t('repositories.modal_assign_items_to_task.body.project_select.placeholder')"
|
||||
:searchPlaceholder="i18n.t('repositories.modal_assign_items_to_task.body.project_select.placeholder')"
|
||||
:placeholder="
|
||||
i18n.t(
|
||||
'repositories.modal_assign_items_to_task.body.project_select.placeholder'
|
||||
)
|
||||
"
|
||||
:searchPlaceholder="
|
||||
i18n.t(
|
||||
'repositories.modal_assign_items_to_task.body.project_select.placeholder'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="experiment-selector">
|
||||
<div class="experiment-selector level-selector">
|
||||
<label>
|
||||
{{ i18n.t("repositories.modal_assign_items_to_task.body.experiment_select.label") }}
|
||||
{{
|
||||
i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.experiment_select.label"
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
|
||||
<SelectSearch
|
||||
|
@ -54,13 +70,21 @@
|
|||
@change="changeExperiment"
|
||||
:options="experiments"
|
||||
:placeholder="experimentsSelectorPlaceholder"
|
||||
:searchPlaceholder="i18n.t('repositories.modal_assign_items_to_task.body.experiment_select.placeholder')"
|
||||
:searchPlaceholder="
|
||||
i18n.t(
|
||||
'repositories.modal_assign_items_to_task.body.experiment_select.placeholder'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="task-selector">
|
||||
<div class="task-selector level-selector">
|
||||
<label>
|
||||
{{ i18n.t("repositories.modal_assign_items_to_task.body.task_select.label") }}
|
||||
{{
|
||||
i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.task_select.label"
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
|
||||
<SelectSearch
|
||||
|
@ -68,16 +92,28 @@
|
|||
ref="tasksSelector"
|
||||
@change="changeTask"
|
||||
:options="tasks"
|
||||
:placeholder="i18n.t('repositories.modal_assign_items_to_task.body.task_select.disabled_placeholder')"
|
||||
:searchPlaceholder="i18n.t('repositories.modal_assign_items_to_task.body.task_select.placeholder')"
|
||||
:placeholder="
|
||||
i18n.t(
|
||||
'repositories.modal_assign_items_to_task.body.task_select.disabled_placeholder'
|
||||
)
|
||||
"
|
||||
:searchPlaceholder="
|
||||
i18n.t(
|
||||
'repositories.modal_assign_items_to_task.body.task_select.placeholder'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal">
|
||||
{{
|
||||
i18n.t("repositories.modal_assign_items_to_task.assign")
|
||||
}}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="modal"
|
||||
:disabled="!selectedTask"
|
||||
@click="assign"
|
||||
>
|
||||
{{ i18n.t("repositories.modal_assign_items_to_task.assign") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,77 +122,90 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import SelectSearch from '../shared/select_search.vue'
|
||||
import SelectSearch from "../shared/select_search.vue";
|
||||
|
||||
export default {
|
||||
name: "AssignItemsToTaskModalContainer",
|
||||
props: {
|
||||
visibility: Boolean,
|
||||
urls: Object,
|
||||
urls: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projects: [
|
||||
[1, "project1"],
|
||||
[2, "project2"],
|
||||
[3, "project3"],
|
||||
[4, "project4"],
|
||||
[5, "project5"],
|
||||
[6, "project6"],
|
||||
[7, "project7"],
|
||||
[8, "project8"],
|
||||
],
|
||||
experiments: [
|
||||
[1, "experiment1"],
|
||||
[2, "experiment2"],
|
||||
[3, "experiment3"],
|
||||
[4, "experiment4"],
|
||||
[5, "experiment5"],
|
||||
[6, "experiment6"],
|
||||
[7, "experiment7"],
|
||||
[8, "experiment8"],
|
||||
],
|
||||
tasks: [
|
||||
[1, "task1"],
|
||||
[2, "task2"],
|
||||
[3, "task3"],
|
||||
[4, "task4"],
|
||||
[5, "task5"],
|
||||
[6, "task6"],
|
||||
[7, "task7"],
|
||||
[8, "task8"],
|
||||
],
|
||||
rowsToAssign: [],
|
||||
projects: [],
|
||||
experiments: [],
|
||||
tasks: [],
|
||||
selectedProject: null,
|
||||
selectedExperiment: null,
|
||||
selectedTask: null
|
||||
selectedTask: null,
|
||||
showCallback: null
|
||||
};
|
||||
},
|
||||
components: {
|
||||
SelectSearch
|
||||
},
|
||||
created() {
|
||||
window.AssignItemsToTaskModalComponent = this;
|
||||
},
|
||||
mounted() {
|
||||
$.get(this.urls.projects)
|
||||
$(this.$refs.modal).on('hidden.bs.modal', () => {
|
||||
this.$emit('close');
|
||||
$(this.$refs.modal).on("shown.bs.modal", () => {
|
||||
$.get(this.projectURL, data => {
|
||||
if (Array.isArray(data)) {
|
||||
this.projects = data;
|
||||
return false;
|
||||
}
|
||||
this.projects = [];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$(this.$refs.modal).on("hidden.bs.modal", () => {
|
||||
this.$emit("close");
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
delete window.AssignItemsToTaskModalComponent;
|
||||
},
|
||||
computed: {
|
||||
experimentsSelectorPlaceholder() {
|
||||
if (this.selectedProject) {
|
||||
return this.i18n.t('repositories.modal_assign_items_to_task.body.experiment_select.placeholder');
|
||||
return this.i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.experiment_select.placeholder"
|
||||
);
|
||||
}
|
||||
return this.i18n.t('repositories.modal_assign_items_to_task.body.experiment_select.disabled_placeholder')
|
||||
return this.i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.experiment_select.disabled_placeholder"
|
||||
);
|
||||
},
|
||||
tasksSelectorPlaceholder() {
|
||||
if (this.selectedExperiment) {
|
||||
return this.i18n.t('repositories.modal_assign_items_to_task.body.task_select.placeholder');
|
||||
return this.i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.task_select.placeholder"
|
||||
);
|
||||
}
|
||||
return this.i18n.t('repositories.modal_assign_items_to_task.body.task_select.disabled_placeholder')
|
||||
return this.i18n.t(
|
||||
"repositories.modal_assign_items_to_task.body.task_select.disabled_placeholder"
|
||||
);
|
||||
},
|
||||
projectURL() {
|
||||
return `${this.urls.projects}`;
|
||||
},
|
||||
experimentURL() {
|
||||
return `${this.urls.experiments}?project_id=${this.selectedProject ||
|
||||
""}`;
|
||||
},
|
||||
taskURL() {
|
||||
return `${this.urls.tasks}?experiment_id=${this.selectedExperiment ||
|
||||
""}`;
|
||||
},
|
||||
assignURL() {
|
||||
return this.urls.assign.replace(":module_id", this.selectedTask);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visibility(newVal) {
|
||||
if (newVal) {
|
||||
visibility() {
|
||||
if (this.visibility) {
|
||||
this.showModal();
|
||||
} else {
|
||||
this.hideModal();
|
||||
|
@ -165,33 +214,76 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
showModal() {
|
||||
$(this.$refs.modal).modal('show');
|
||||
$(this.$refs.modal).modal("show");
|
||||
|
||||
this.rowsToAssign = this.showCallback();
|
||||
},
|
||||
hideModal(){
|
||||
$(this.$refs.modal).modal('hide');
|
||||
hideModal() {
|
||||
$(this.$refs.modal).modal("hide");
|
||||
},
|
||||
changeProject(value) {
|
||||
const newProjectVal = value;
|
||||
this.selectedProject = null;
|
||||
this.selectedExperiment = null;
|
||||
this.selectedTask = null;
|
||||
|
||||
setTimeout(() => {
|
||||
this.experiments = [
|
||||
[1, 'ex1'],
|
||||
[2, 'ex2'],
|
||||
[3, 'ex3'],
|
||||
[4, 'ex4']
|
||||
];
|
||||
this.selectedProject = newProjectVal;
|
||||
}, 2000);
|
||||
this.selectedProject = value;
|
||||
this.resetExperimentSelector();
|
||||
this.resetTaskSelector();
|
||||
|
||||
$.get(this.experimentURL, data => {
|
||||
if (Array.isArray(data)) {
|
||||
this.experiments = data;
|
||||
return false;
|
||||
}
|
||||
this.experiments = [];
|
||||
});
|
||||
},
|
||||
changeExperiment(value) {
|
||||
this.selectedExperiment = value;
|
||||
this.resetTaskSelector();
|
||||
|
||||
$.get(this.taskURL, data => {
|
||||
if (Array.isArray(data)) {
|
||||
this.tasks = data;
|
||||
return false;
|
||||
}
|
||||
this.tasks = [];
|
||||
});
|
||||
},
|
||||
changeTask(value) {
|
||||
this.selectedTask = value;
|
||||
},
|
||||
resetProjectSelector() {
|
||||
this.projects = [];
|
||||
this.selectedProject = null;
|
||||
},
|
||||
resetExperimentSelector() {
|
||||
this.experiments = [];
|
||||
this.selectedExperiment = null;
|
||||
},
|
||||
resetTaskSelector() {
|
||||
this.tasks = [];
|
||||
this.selectedTask = null;
|
||||
},
|
||||
resetSelectors() {
|
||||
this.resetTaskSelector();
|
||||
this.resetExperimentSelector();
|
||||
this.resetProjectSelector();
|
||||
},
|
||||
assign() {
|
||||
if (!this.selectedTask) return;
|
||||
|
||||
$.ajax({
|
||||
url: this.assignURL,
|
||||
type: "PATCH",
|
||||
dataType: "json",
|
||||
data: { rows_to_assign: this.rowsToAssign }
|
||||
}).always(() => {
|
||||
this.resetSelectors();
|
||||
this.deselectRows();
|
||||
});
|
||||
},
|
||||
setShowCallback(callback) {
|
||||
this.showCallback = callback;
|
||||
},
|
||||
deselectRows() {
|
||||
$('.repository-row-selector:checked').trigger('click');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
setTimeout(() => {
|
||||
this.isOpen = false;
|
||||
this.$emit('blur');
|
||||
}, 100)
|
||||
}, 200)
|
||||
},
|
||||
toggle() {
|
||||
this.isOpen = !this.isOpen;
|
||||
|
@ -71,12 +71,11 @@
|
|||
this.$emit('change', this.value);
|
||||
},
|
||||
updateOptionPosition() {
|
||||
let rect = this.$refs.container.getBoundingClientRect();
|
||||
let top =rect.top + rect.height;
|
||||
let left = rect.left;
|
||||
let width = rect.width;
|
||||
const rect = this.$refs.container.getBoundingClientRect();
|
||||
const top = rect.height;
|
||||
const width = rect.width;
|
||||
|
||||
this.optionPositionStyle = `position: fixed; top: ${top}px; left: ${left}px; width: ${width}px`
|
||||
this.optionPositionStyle = `position: absolute; top: ${top}px; width: ${width}px`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,16 +42,20 @@
|
|||
} else {
|
||||
this.currentOptions = this.options.filter((o) => o[1].toLowerCase().includes(this.query.toLowerCase()));
|
||||
}
|
||||
},
|
||||
options() {
|
||||
this.currentOptions = this.options;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
valueLabel() {
|
||||
let option = this.options.find((o) => o[0] === this.value);
|
||||
let option = this.currentOptions.find((o) => o[0] === this.value);
|
||||
return option && option[1];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
blur() {
|
||||
this.isOpen = false;
|
||||
this.$emit('blur');
|
||||
},
|
||||
change(value) {
|
||||
|
@ -68,7 +72,7 @@
|
|||
this.$emit('close');
|
||||
},
|
||||
fetchOptions() {
|
||||
$.get(`/${this.optionsUrl}?query=${this.query}`,
|
||||
$.get(`${this.optionsUrl}?query=${this.query || ''}`,
|
||||
(data) => {
|
||||
this.currentOptions = data;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div
|
||||
class="assign-items-to-task-modal-container"
|
||||
data-assign-url=<%= my_module_repository_path(MyModule.first) %>
|
||||
data-projects-url=<%= project_filter_projects_path %>
|
||||
data-experiments-url=<%= experiment_filter_experiments_path %>
|
||||
data-tasks-url=<%= module_filter_my_modules_path %>
|
||||
data-assign-url="<%= my_module_repository_path(":module_id") %>"
|
||||
data-projects-url="<%= project_filter_projects_path %>"
|
||||
data-experiments-url="<%= experiment_filter_experiments_path %>"
|
||||
data-tasks-url="<%= module_filter_my_modules_path %>"
|
||||
>
|
||||
<assign-items-to-task-modal-container
|
||||
:visibility="visibility"
|
||||
|
|
Loading…
Add table
Reference in a new issue