mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-16 14:17:00 +08:00
164 lines
6 KiB
Vue
164 lines
6 KiB
Vue
<template>
|
|
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content" data-e2e="e2e-MD-manageColumns">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" data-e2e="e2e-BT-manageColumnsModal-close">
|
|
<i class="sn-icon sn-icon-close"></i>
|
|
</button>
|
|
<h4 class="modal-title truncate !block" data-e2e="e2e-TX-manageColumnsModal-title">
|
|
{{ i18n.t('experiments.table.column_display_modal.title') }}
|
|
</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="max-h-90 overflow-y-auto">
|
|
<Draggable
|
|
v-model="columnsList"
|
|
:forceFallback="true"
|
|
:handle="'.element-grip'"
|
|
item-key="field"
|
|
@end="endReorder"
|
|
>
|
|
<template #item="{element}">
|
|
<div
|
|
class="flex items-center gap-4 py-2.5 px-3 group/column"
|
|
:class="{
|
|
'hover:bg-sn-super-light-grey': element.field !== 'pinnedSeparator',
|
|
'!py-2.5': element.field === 'pinnedSeparator',
|
|
'text-sn-grey': (element.field !== 'pinnedSeparator' && !columnVisbile(element))
|
|
}"
|
|
>
|
|
<div v-if="element.field == 'pinnedSeparator'" class="h-[1px] w-full bg-sn-sleepy-grey"></div>
|
|
<template v-else>
|
|
<div class="opacity-0 group-hover/column:!opacity-100 element-grip cursor-pointer" :data-e2e="'e2e-BT-manageColumnsModal-'+element.field+'-drag'">
|
|
<i class="sn-icon sn-icon-drag"></i>
|
|
</div>
|
|
<div v-if="element.field === 'name'" class="w-6 h-6"></div>
|
|
<template v-else>
|
|
<i v-if="columnVisbile(element)" @click="toggleColumn(element, true)"
|
|
class="sn-icon sn-icon-visibility-show cursor-pointer" :data-e2e="'e2e-BT-manageColumnsModal-'+element.field+'-hide'"></i>
|
|
<i v-else @click="toggleColumn(element, false)"
|
|
class="sn-icon sn-icon-visibility-hide cursor-pointer" :data-e2e="'e2e-BT-manageColumnsModal-'+element.field+'-show'"></i>
|
|
</template>
|
|
<div class="truncate" :data-e2e="'e2e-TX-manageColumnsModal-'+element.field+'-columnName'">{{ element.headerName }}</div>
|
|
<div class="ml-auto cursor-pointer" :data-e2e="'e2e-BT-manageColumnsModal-'+element.field+'-pin'">
|
|
<i v-if="columnPinned(element)" @click="unPinColumn(element)" class="sn-icon sn-icon-pinned"></i>
|
|
<i v-else @click="pinColumn(element)" class="sn-icon sn-icon-pin"></i>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</Draggable>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary mr-auto" @click="resetToDefault" data-e2e="e2e-BT-manageColumnsModal-resetToDefault">
|
|
{{ i18n.t('experiments.table.column_display_modal.reset_to_default') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import modalMixin from '../../modal_mixin';
|
|
import Draggable from 'vuedraggable';
|
|
|
|
export default {
|
|
name: 'NewModal',
|
|
props: {
|
|
columnDefs: { type: Array, required: true },
|
|
tableState: { type: Object }
|
|
},
|
|
components: {
|
|
Draggable
|
|
},
|
|
data() {
|
|
return {
|
|
currentTableState: {},
|
|
columnsList: []
|
|
};
|
|
},
|
|
created() {
|
|
this.syncColumns();
|
|
},
|
|
watch: {
|
|
tableState: {
|
|
handler() {
|
|
this.syncColumns();
|
|
},
|
|
deep: true
|
|
}
|
|
},
|
|
mixins: [modalMixin],
|
|
methods: {
|
|
resetToDefault() {
|
|
this.$emit('resetToDefault');
|
|
this.close();
|
|
},
|
|
columnVisbile(column) {
|
|
return !this.currentTableState.columnsState?.find((col) => col.colId === column.field).hide;
|
|
},
|
|
columnPinned(column) {
|
|
return this.currentTableState.columnsState?.find((col) => col.colId === column.field).pinned;
|
|
},
|
|
toggleColumn(column, visible) {
|
|
if (column.field === 'name') return;
|
|
|
|
if (visible) {
|
|
this.$emit('hideColumn', column);
|
|
} else {
|
|
this.$emit('showColumn', column);
|
|
}
|
|
},
|
|
pinColumn(column) {
|
|
this.$emit('pinColumn', column);
|
|
},
|
|
unPinColumn(column) {
|
|
this.$emit('unPinColumn', column);
|
|
},
|
|
syncColumns() {
|
|
this.currentTableState = this.tableState;
|
|
this.currentTableState.columnsState.forEach((col, index) => {
|
|
col.position = index;
|
|
});
|
|
|
|
let columns = this.currentTableState.columnsState
|
|
.sort((a, b) => {
|
|
if (a.pinned === b.pinned) {
|
|
return a.position - b.position;
|
|
}
|
|
return a.pinned ? -1 : 1;
|
|
});
|
|
|
|
const pinnedAmount = columns.filter((col) => col.pinned).length;
|
|
columns = columns
|
|
.map((col) => this.columnDefs.find((c) => c.field === col.colId))
|
|
.filter((col) => col);
|
|
this.columnsList = [
|
|
...columns.slice(0, pinnedAmount - 1),
|
|
{ field: 'pinnedSeparator' },
|
|
...columns.slice(pinnedAmount - 1)
|
|
];
|
|
},
|
|
endReorder(event) {
|
|
this.$nextTick(() => {
|
|
const { newIndex } = event;
|
|
const columnName = this.columnsList[newIndex].field;
|
|
const separatorIndex = this.columnsList.findIndex((col) => col.field === 'pinnedSeparator');
|
|
const reordedColumns = this.columnsList.filter((col) => col.field !== 'pinnedSeparator');
|
|
|
|
const columnsOrdered = reordedColumns.map((col) => col.field);
|
|
this.$emit('reorderColumns', columnsOrdered);
|
|
|
|
if (newIndex <= separatorIndex) {
|
|
this.pinColumn(this.columnDefs.find((col) => col.field === columnName));
|
|
} else {
|
|
this.unPinColumn(this.columnDefs.find((col) => col.field === columnName));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
</script>
|