feat: Implement editable student grid and refactor maintenance dialogs
This commit is contained in:
+87
-3
@@ -59,7 +59,7 @@
|
||||
:disabled="!hasSelectedRows"
|
||||
:prepend-icon="mdiDelete"
|
||||
variant="outlined"
|
||||
@click="deleteSelectedRows"
|
||||
@click="requestDeleteSelectedRows"
|
||||
>
|
||||
批次刪除
|
||||
</v-btn>
|
||||
@@ -69,7 +69,7 @@
|
||||
:disabled="!hasAnyChange"
|
||||
:prepend-icon="mdiContentSave"
|
||||
variant="outlined"
|
||||
@click="saveAllRows"
|
||||
@click="requestSaveAllRows"
|
||||
>
|
||||
儲存變更
|
||||
</v-btn>
|
||||
@@ -289,7 +289,7 @@
|
||||
:disabled="!isBulkEditEnabled"
|
||||
size="small"
|
||||
variant="text"
|
||||
@click="deleteSingleRow(item.id)"
|
||||
@click="requestDeleteSingleRow(item.id)"
|
||||
>
|
||||
刪除
|
||||
</v-btn>
|
||||
@@ -300,10 +300,38 @@
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
v-model="confirmDeleteSingleVisible"
|
||||
confirm-color="error"
|
||||
confirm-text="確定刪除"
|
||||
:message="singleDeleteMessage"
|
||||
title="確認刪除"
|
||||
@confirm="confirmDeleteSingleRow"
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
v-model="confirmDeleteSelectedVisible"
|
||||
confirm-color="error"
|
||||
confirm-text="確定批次刪除"
|
||||
:message="selectedDeleteMessage"
|
||||
title="確認批次刪除"
|
||||
@confirm="confirmDeleteSelectedRows"
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
v-model="confirmSaveVisible"
|
||||
confirm-text="確認儲存"
|
||||
message="確定要儲存目前所有變更嗎?"
|
||||
title="確認儲存變更"
|
||||
@confirm="confirmSaveAllRows"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mdiContentSave, mdiDelete, mdiMagnify, mdiRestore } from '@mdi/js'
|
||||
import { computed, ref } from 'vue'
|
||||
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
|
||||
import { useEditableStudentGrid } from '@/composables/maint/useEditableStudentGrid'
|
||||
|
||||
const {
|
||||
@@ -331,6 +359,62 @@ const {
|
||||
deleteSingleRow,
|
||||
resetAllRows,
|
||||
} = useEditableStudentGrid()
|
||||
|
||||
const confirmDeleteSingleVisible = ref(false)
|
||||
const confirmDeleteSelectedVisible = ref(false)
|
||||
const confirmSaveVisible = ref(false)
|
||||
const pendingDeleteRowId = ref<number | null>(null)
|
||||
|
||||
const pendingDeleteRow = computed(() =>
|
||||
pendingDeleteRowId.value === null ? null : getDraftRow(pendingDeleteRowId.value)
|
||||
)
|
||||
|
||||
const singleDeleteMessage = computed(() => {
|
||||
const row = pendingDeleteRow.value
|
||||
if (!row) {
|
||||
return '確定要刪除此筆資料嗎?此操作會在儲存後正式生效。'
|
||||
}
|
||||
|
||||
return `確定要刪除 ${row.name}(${row.studentId})嗎?此操作會在儲存後正式生效。`
|
||||
})
|
||||
|
||||
const selectedDeleteMessage = computed(
|
||||
() =>
|
||||
`確定要刪除目前選取的 ${selectedRowIds.value.length} 筆資料嗎?此操作會在儲存後正式生效。`
|
||||
)
|
||||
|
||||
function requestDeleteSingleRow(id: number) {
|
||||
pendingDeleteRowId.value = id
|
||||
confirmDeleteSingleVisible.value = true
|
||||
}
|
||||
|
||||
function confirmDeleteSingleRow() {
|
||||
if (pendingDeleteRowId.value === null) return
|
||||
|
||||
deleteSingleRow(pendingDeleteRowId.value)
|
||||
pendingDeleteRowId.value = null
|
||||
confirmDeleteSingleVisible.value = false
|
||||
}
|
||||
|
||||
function requestDeleteSelectedRows() {
|
||||
if (!hasSelectedRows.value) return
|
||||
confirmDeleteSelectedVisible.value = true
|
||||
}
|
||||
|
||||
function confirmDeleteSelectedRows() {
|
||||
deleteSelectedRows()
|
||||
confirmDeleteSelectedVisible.value = false
|
||||
}
|
||||
|
||||
function requestSaveAllRows() {
|
||||
if (!hasAnyChange.value) return
|
||||
confirmSaveVisible.value = true
|
||||
}
|
||||
|
||||
function confirmSaveAllRows() {
|
||||
saveAllRows()
|
||||
confirmSaveVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<common-confirm-dialog
|
||||
v-model="closeVisibleModel"
|
||||
confirm-color="error"
|
||||
confirm-text="關閉不儲存"
|
||||
message="目前有尚未儲存的內容,確定要關閉嗎?"
|
||||
title="未儲存變更"
|
||||
@confirm="emit('confirm-close')"
|
||||
/>
|
||||
|
||||
<common-confirm-dialog
|
||||
v-model="saveVisibleModel"
|
||||
:confirm-loading="props.isSaving"
|
||||
confirm-text="確認儲存"
|
||||
max-width="520"
|
||||
title="確認儲存變更"
|
||||
@confirm="emit('confirm-save')"
|
||||
>
|
||||
<div v-if="props.saveSummary.length > 0" class="d-flex flex-column ga-2">
|
||||
<div v-for="item in props.saveSummary" :key="item.label" class="d-flex flex-column">
|
||||
<div class="text-caption text-medium-emphasis">{{ item.label }}</div>
|
||||
<div v-if="item.before !== null" class="text-body-2">
|
||||
<span class="text-medium-emphasis">原:</span>
|
||||
<span :class="{ 'text-medium-emphasis': item.before === '—' }">
|
||||
{{ item.before }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
<span class="text-medium-emphasis">新:</span>
|
||||
<span :class="{ 'text-medium-emphasis': item.after === '—' }">
|
||||
{{ item.after }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-body-2">目前沒有可儲存的變更。</div>
|
||||
</common-confirm-dialog>
|
||||
|
||||
<common-confirm-dialog
|
||||
v-model="deleteVisibleModel"
|
||||
confirm-color="error"
|
||||
confirm-text="確定刪除"
|
||||
:message="`確定要刪除 ${props.pendingDeleteLabel} 嗎?此操作無法復原。`"
|
||||
title="確認刪除"
|
||||
@confirm="emit('confirm-delete')"
|
||||
/>
|
||||
|
||||
<common-confirm-dialog
|
||||
v-model="switchVisibleModel"
|
||||
confirm-text="確定切換"
|
||||
max-width="480"
|
||||
message="目前有尚未儲存的內容,切換為檢視模式將會捨棄變更,確定要切換嗎?"
|
||||
title="未儲存變更"
|
||||
@confirm="emit('confirm-switch')"
|
||||
/>
|
||||
|
||||
<common-confirm-dialog
|
||||
v-model="navigateVisibleModel"
|
||||
confirm-text="確定切換"
|
||||
max-width="480"
|
||||
message="目前有尚未儲存的內容,切換到其他資料將會捨棄變更,確定要切換嗎?"
|
||||
title="未儲存變更"
|
||||
@confirm="emit('confirm-navigate')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { SaveSummaryItem } from '@/composables/maint/useStudentMaintenanceForm'
|
||||
import { computed } from 'vue'
|
||||
import CommonConfirmDialog from './CommonConfirmDialog.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
closeVisible: boolean
|
||||
deleteVisible: boolean
|
||||
isSaving: boolean
|
||||
navigateVisible: boolean
|
||||
pendingDeleteLabel: string
|
||||
saveSummary: SaveSummaryItem[]
|
||||
saveVisible: boolean
|
||||
switchVisible: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'confirm-close'): void
|
||||
(event: 'confirm-delete'): void
|
||||
(event: 'confirm-navigate'): void
|
||||
(event: 'confirm-save'): void
|
||||
(event: 'confirm-switch'): void
|
||||
(event: 'update:close-visible', value: boolean): void
|
||||
(event: 'update:delete-visible', value: boolean): void
|
||||
(event: 'update:navigate-visible', value: boolean): void
|
||||
(event: 'update:save-visible', value: boolean): void
|
||||
(event: 'update:switch-visible', value: boolean): void
|
||||
}>()
|
||||
|
||||
const closeVisibleModel = computed({
|
||||
get: () => props.closeVisible,
|
||||
set: (value: boolean) => emit('update:close-visible', value),
|
||||
})
|
||||
|
||||
const saveVisibleModel = computed({
|
||||
get: () => props.saveVisible,
|
||||
set: (value: boolean) => emit('update:save-visible', value),
|
||||
})
|
||||
|
||||
const deleteVisibleModel = computed({
|
||||
get: () => props.deleteVisible,
|
||||
set: (value: boolean) => emit('update:delete-visible', value),
|
||||
})
|
||||
|
||||
const switchVisibleModel = computed({
|
||||
get: () => props.switchVisible,
|
||||
set: (value: boolean) => emit('update:switch-visible', value),
|
||||
})
|
||||
|
||||
const navigateVisibleModel = computed({
|
||||
get: () => props.navigateVisible,
|
||||
set: (value: boolean) => emit('update:navigate-visible', value),
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user