refactor: update breadcrumb bar visibility handling across components
This commit is contained in:
@@ -4,28 +4,28 @@
|
||||
@create="openAddDialog" @toggle-search="searchPanelOpen = !searchPanelOpen">
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
v-model="search.studentId" density="compact" hide-details placeholder="例如:S2024001"
|
||||
id="search-student-id" v-model="search.studentId" aria-labelledby="search-student-id-label" density="compact" hide-details name="searchStudentId" placeholder="例如:S2024001"
|
||||
variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field v-model="search.name" density="compact" hide-details placeholder="例如:王小明" variant="outlined" />
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field id="search-name" v-model="search.name" aria-labelledby="search-name-label" density="compact" hide-details name="searchName" placeholder="例如:王小明" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select v-model="search.department" density="compact" hide-details :items="departments" variant="outlined" />
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select id="search-department" v-model="search.department" aria-labelledby="search-department-label" density="compact" hide-details :items="departments" name="searchDepartment" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
v-model="search.grade" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" variant="outlined" />
|
||||
id="search-grade" v-model="search.grade" aria-labelledby="search-grade-label" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" name="searchGrade" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select v-model="search.status" density="compact" hide-details :items="statuses" variant="outlined" />
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select id="search-status" v-model="search.status" aria-labelledby="search-status-label" density="compact" hide-details :items="statuses" name="searchStatus" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
|
||||
<v-btn :prepend-icon="mdiBroom" variant="text" @click="resetSearch">清除</v-btn>
|
||||
@@ -34,8 +34,8 @@ v-model="search.grade" density="compact" hide-details item-title="title" item-va
|
||||
</template>
|
||||
<template #table>
|
||||
<v-data-table
|
||||
class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
:items="students" :items-per-page="10" items-per-page-text="每頁筆數" page-text="第 {0}-{1} 筆 / 共 {2} 筆"
|
||||
v-model:page="currentPage" class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
hide-default-footer :items="students" :items-per-page="itemsPerPage"
|
||||
:row-props="rowProps">
|
||||
<template #[`item.grade`]="{ item }">
|
||||
{{ gradeLabel(item.grade) }}
|
||||
@@ -60,6 +60,20 @@ color="error" :prepend-icon="mdiDelete" size="small" variant="text"
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div class="d-flex align-center justify-space-between px-4 py-3">
|
||||
<div class="text-body-2 text-medium-emphasis">
|
||||
{{ pageSummary }}
|
||||
</div>
|
||||
<div class="d-flex align-center ga-2">
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage = 1">第一頁</v-btn>
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage -= 1">上一頁</v-btn>
|
||||
<span class="text-body-2">{{ currentPage }} / {{ pageCount }}</span>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage += 1">下一頁</v-btn>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage = pageCount">最後頁</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
</mnt-page-cards>
|
||||
@@ -209,7 +223,7 @@ v-if="!isViewMode" color="primary" :disabled="!isDirty || isLoading" :loading="i
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil } from '@mdi/js'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
import MaintenanceCrudDialogs from '@/components/maintenance/MaintenanceCrudDialogs.vue'
|
||||
@@ -270,6 +284,17 @@ const studentStore = useStudentStore()
|
||||
const semesterStore = useSemesterStore()
|
||||
const students = computed(() => studentStore.students)
|
||||
type StudentPayload = Omit<StudentRecord, 'id'>
|
||||
const itemsPerPage = 10
|
||||
const currentPage = ref(1)
|
||||
const pageCount = computed(() => Math.max(1, Math.ceil(students.value.length / itemsPerPage)))
|
||||
const pageSummary = computed(() => {
|
||||
const total = students.value.length
|
||||
if (total === 0) return '第 0-0 筆 / 共 0 筆'
|
||||
|
||||
const start = (currentPage.value - 1) * itemsPerPage + 1
|
||||
const end = Math.min(currentPage.value * itemsPerPage, total)
|
||||
return `第 ${start}-${end} 筆 / 共 ${total} 筆`
|
||||
})
|
||||
|
||||
// 彈窗狀態與流程控制
|
||||
const dialogVisible = ref(false)
|
||||
@@ -452,6 +477,12 @@ function resetSearch () {
|
||||
}
|
||||
}
|
||||
|
||||
watch(pageCount, (value) => {
|
||||
if (currentPage.value > value) {
|
||||
currentPage.value = value
|
||||
}
|
||||
})
|
||||
|
||||
// 新增:開啟彈窗,使用預設值
|
||||
function openAddDialog () {
|
||||
loadSequence.value += 1
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
@create="openAddDialog" @toggle-search="searchPanelOpen = !searchPanelOpen">
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
v-model="search.studentId" density="compact" hide-details placeholder="例如:S2024001"
|
||||
id="search-student-id" v-model="search.studentId" aria-labelledby="search-student-id-label" density="compact" hide-details name="searchStudentId" placeholder="例如:S2024001"
|
||||
variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field v-model="search.name" density="compact" hide-details placeholder="例如:王小明" variant="outlined" />
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field id="search-name" v-model="search.name" aria-labelledby="search-name-label" density="compact" hide-details name="searchName" placeholder="例如:王小明" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select v-model="search.department" density="compact" hide-details :items="departments" variant="outlined" />
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select id="search-department" v-model="search.department" aria-labelledby="search-department-label" density="compact" hide-details :items="departments" name="searchDepartment" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
v-model="search.grade" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" variant="outlined" />
|
||||
id="search-grade" v-model="search.grade" aria-labelledby="search-grade-label" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" name="searchGrade" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select v-model="search.status" density="compact" hide-details :items="statuses" variant="outlined" />
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select id="search-status" v-model="search.status" aria-labelledby="search-status-label" density="compact" hide-details :items="statuses" name="searchStatus" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
|
||||
<v-btn :prepend-icon="mdiBroom" variant="text" @click="resetSearch">清除</v-btn>
|
||||
@@ -34,8 +34,8 @@ v-model="search.grade" density="compact" hide-details item-title="title" item-va
|
||||
</template>
|
||||
<template #table>
|
||||
<v-data-table
|
||||
class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
:items="students" :items-per-page="10" items-per-page-text="每頁筆數" page-text="第 {0}-{1} 筆 / 共 {2} 筆"
|
||||
v-model:page="currentPage" class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
hide-default-footer :items="students" :items-per-page="itemsPerPage"
|
||||
:row-props="rowProps">
|
||||
<template #[`item.grade`]="{ item }">
|
||||
{{ gradeLabel(item.grade) }}
|
||||
@@ -60,6 +60,20 @@ color="error" :prepend-icon="mdiDelete" size="small" variant="text"
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div class="d-flex align-center justify-space-between px-4 py-3">
|
||||
<div class="text-body-2 text-medium-emphasis">
|
||||
{{ pageSummary }}
|
||||
</div>
|
||||
<div class="d-flex align-center ga-2">
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage = 1">第一頁</v-btn>
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage -= 1">上一頁</v-btn>
|
||||
<span class="text-body-2">{{ currentPage }} / {{ pageCount }}</span>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage += 1">下一頁</v-btn>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage = pageCount">最後頁</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
</mnt-page-cards>
|
||||
@@ -236,9 +250,10 @@ v-model.number="addCourseForm.score" density="comfortable" hide-spin-buttons lab
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mdiBookPlus, mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil } from '@mdi/js'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
import CommonConfirmDialog from '@/components/maintenance/CommonConfirmDialog.vue'
|
||||
import MaintenanceCrudDialogs from '@/components/maintenance/MaintenanceCrudDialogs.vue'
|
||||
import MaintenanceStudentFormFields from '@/components/maintenance/MaintenanceStudentFormFields.vue'
|
||||
import MasterDetailBSemesterMobilePanel from '@/components/maintenance/master-detail-b/MasterDetailBSemesterMobilePanel.vue'
|
||||
@@ -297,6 +312,17 @@ const studentStore = useStudentStore()
|
||||
const semesterStore = useSemesterStore()
|
||||
const students = computed(() => studentStore.students)
|
||||
type StudentPayload = Omit<StudentRecord, 'id'>
|
||||
const itemsPerPage = 10
|
||||
const currentPage = ref(1)
|
||||
const pageCount = computed(() => Math.max(1, Math.ceil(students.value.length / itemsPerPage)))
|
||||
const pageSummary = computed(() => {
|
||||
const total = students.value.length
|
||||
if (total === 0) return '第 0-0 筆 / 共 0 筆'
|
||||
|
||||
const start = (currentPage.value - 1) * itemsPerPage + 1
|
||||
const end = Math.min(currentPage.value * itemsPerPage, total)
|
||||
return `第 ${start}-${end} 筆 / 共 ${total} 筆`
|
||||
})
|
||||
|
||||
// 彈窗狀態與流程控制
|
||||
const dialogVisible = ref(false)
|
||||
@@ -531,6 +557,12 @@ function resetSearch () {
|
||||
}
|
||||
}
|
||||
|
||||
watch(pageCount, (value) => {
|
||||
if (currentPage.value > value) {
|
||||
currentPage.value = value
|
||||
}
|
||||
})
|
||||
|
||||
// 新增:開啟彈窗,使用預設值
|
||||
function openAddDialog () {
|
||||
loadSequence.value += 1
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
@create="openAddDialog" @toggle-search="searchPanelOpen = !searchPanelOpen">
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
v-model="search.studentId" density="compact" hide-details placeholder="例如:S2024001"
|
||||
id="search-student-id" v-model="search.studentId" aria-labelledby="search-student-id-label" density="compact" hide-details name="searchStudentId" placeholder="例如:S2024001"
|
||||
variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field v-model="search.name" density="compact" hide-details placeholder="例如:王小明" variant="outlined" />
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field id="search-name" v-model="search.name" aria-labelledby="search-name-label" density="compact" hide-details name="searchName" placeholder="例如:王小明" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select v-model="search.department" density="compact" hide-details :items="departments" variant="outlined" />
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select id="search-department" v-model="search.department" aria-labelledby="search-department-label" density="compact" hide-details :items="departments" name="searchDepartment" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
v-model="search.grade" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" variant="outlined" />
|
||||
id="search-grade" v-model="search.grade" aria-labelledby="search-grade-label" density="compact" hide-details item-title="title" item-value="value"
|
||||
:items="gradeOptions" name="searchGrade" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select v-model="search.status" density="compact" hide-details :items="statuses" variant="outlined" />
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select id="search-status" v-model="search.status" aria-labelledby="search-status-label" density="compact" hide-details :items="statuses" name="searchStatus" variant="outlined" />
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
|
||||
<v-btn :prepend-icon="mdiBroom" variant="text" @click="resetSearch">清除</v-btn>
|
||||
@@ -34,8 +34,8 @@ v-model="search.grade" density="compact" hide-details item-title="title" item-va
|
||||
</template>
|
||||
<template #table>
|
||||
<v-data-table
|
||||
class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
:items="students" :items-per-page="10" items-per-page-text="每頁筆數" page-text="第 {0}-{1} 筆 / 共 {2} 筆"
|
||||
v-model:page="currentPage" class="student-table" density="compact" fixed-header :headers="tableHeaders" height="100%"
|
||||
hide-default-footer :items="students" :items-per-page="itemsPerPage"
|
||||
:row-props="rowProps">
|
||||
<template #[`item.grade`]="{ item }">
|
||||
{{ gradeLabel(item.grade) }}
|
||||
@@ -60,6 +60,20 @@ color="error" :prepend-icon="mdiDelete" size="small" variant="text"
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div class="d-flex align-center justify-space-between px-4 py-3">
|
||||
<div class="text-body-2 text-medium-emphasis">
|
||||
{{ pageSummary }}
|
||||
</div>
|
||||
<div class="d-flex align-center ga-2">
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage = 1">第一頁</v-btn>
|
||||
<v-btn :disabled="currentPage <= 1" size="small" variant="text" @click="currentPage -= 1">上一頁</v-btn>
|
||||
<span class="text-body-2">{{ currentPage }} / {{ pageCount }}</span>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage += 1">下一頁</v-btn>
|
||||
<v-btn :disabled="currentPage >= pageCount" size="small" variant="text" @click="currentPage = pageCount">最後頁</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
</mnt-page-cards>
|
||||
@@ -226,7 +240,7 @@ v-model.number="addCourseForm.score" density="comfortable" label="分數" type="
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil, mdiSchool } from '@mdi/js'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
import MaintenanceCrudDialogs from '@/components/maintenance/MaintenanceCrudDialogs.vue'
|
||||
@@ -287,6 +301,17 @@ const studentStore = useStudentStore()
|
||||
const semesterStore = useSemesterStore()
|
||||
const students = computed(() => studentStore.students)
|
||||
type StudentPayload = Omit<StudentRecord, 'id'>
|
||||
const itemsPerPage = 10
|
||||
const currentPage = ref(1)
|
||||
const pageCount = computed(() => Math.max(1, Math.ceil(students.value.length / itemsPerPage)))
|
||||
const pageSummary = computed(() => {
|
||||
const total = students.value.length
|
||||
if (total === 0) return '第 0-0 筆 / 共 0 筆'
|
||||
|
||||
const start = (currentPage.value - 1) * itemsPerPage + 1
|
||||
const end = Math.min(currentPage.value * itemsPerPage, total)
|
||||
return `第 ${start}-${end} 筆 / 共 ${total} 筆`
|
||||
})
|
||||
|
||||
// 彈窗狀態與流程控制
|
||||
const dialogVisible = ref(false)
|
||||
@@ -541,6 +566,12 @@ function resetSearch () {
|
||||
}
|
||||
}
|
||||
|
||||
watch(pageCount, (value) => {
|
||||
if (currentPage.value > value) {
|
||||
currentPage.value = value
|
||||
}
|
||||
})
|
||||
|
||||
// 新增:開啟彈窗,使用預設值
|
||||
function openAddDialog () {
|
||||
loadSequence.value += 1
|
||||
|
||||
@@ -7,54 +7,69 @@
|
||||
>
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
id="search-student-id"
|
||||
v-model="search.studentId"
|
||||
aria-labelledby="search-student-id-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
name="searchStudentId"
|
||||
placeholder="例如:S2024001"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field
|
||||
id="search-name"
|
||||
v-model="search.name"
|
||||
aria-labelledby="search-name-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
name="searchName"
|
||||
placeholder="例如:王小明"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select
|
||||
id="search-department"
|
||||
v-model="search.department"
|
||||
aria-labelledby="search-department-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
:items="departments"
|
||||
name="searchDepartment"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
id="search-grade"
|
||||
v-model="search.grade"
|
||||
aria-labelledby="search-grade-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:items="gradeOptions"
|
||||
name="searchGrade"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select
|
||||
id="search-status"
|
||||
v-model="search.status"
|
||||
aria-labelledby="search-status-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
:items="statuses"
|
||||
name="searchStatus"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
@@ -65,15 +80,15 @@
|
||||
</template>
|
||||
<template #table>
|
||||
<v-data-table
|
||||
v-model:page="currentPage"
|
||||
class="student-table"
|
||||
density="compact"
|
||||
fixed-header
|
||||
:headers="tableHeaders"
|
||||
height="100%"
|
||||
hide-default-footer
|
||||
:items="students"
|
||||
:items-per-page="10"
|
||||
items-per-page-text="每頁筆數"
|
||||
page-text="第 {0}-{1} 筆 / 共 {2} 筆"
|
||||
:items-per-page="itemsPerPage"
|
||||
:row-props="rowProps"
|
||||
>
|
||||
<template #[`item.grade`]="{ item }">
|
||||
@@ -115,6 +130,48 @@
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div class="d-flex align-center justify-space-between px-4 py-3">
|
||||
<div class="text-body-2 text-medium-emphasis">
|
||||
{{ pageSummary }}
|
||||
</div>
|
||||
<div class="d-flex align-center ga-2">
|
||||
<v-btn
|
||||
:disabled="currentPage <= 1"
|
||||
size="small"
|
||||
variant="text"
|
||||
@click="currentPage = 1"
|
||||
>
|
||||
第一頁
|
||||
</v-btn>
|
||||
<v-btn
|
||||
:disabled="currentPage <= 1"
|
||||
size="small"
|
||||
variant="text"
|
||||
@click="currentPage -= 1"
|
||||
>
|
||||
上一頁
|
||||
</v-btn>
|
||||
<span class="text-body-2">{{ currentPage }} / {{ pageCount }}</span>
|
||||
<v-btn
|
||||
:disabled="currentPage >= pageCount"
|
||||
size="small"
|
||||
variant="text"
|
||||
@click="currentPage += 1"
|
||||
>
|
||||
下一頁
|
||||
</v-btn>
|
||||
<v-btn
|
||||
:disabled="currentPage >= pageCount"
|
||||
size="small"
|
||||
variant="text"
|
||||
@click="currentPage = pageCount"
|
||||
>
|
||||
最後頁
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
</mnt-page-cards>
|
||||
@@ -399,7 +456,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil } from '@mdi/js'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import MaintenanceCrudDialogs from '@/components/maintenance/MaintenanceCrudDialogs.vue'
|
||||
import MntDialogCard from '@/components/maintenance/MntDialogCard.vue'
|
||||
@@ -472,6 +529,17 @@ const searchPanelOpen = ref(false)
|
||||
const studentStore = useStudentStore()
|
||||
const students = computed(() => studentStore.students)
|
||||
type StudentPayload = Omit<StudentRecord, 'id'>
|
||||
const itemsPerPage = 10
|
||||
const currentPage = ref(1)
|
||||
const pageCount = computed(() => Math.max(1, Math.ceil(students.value.length / itemsPerPage)))
|
||||
const pageSummary = computed(() => {
|
||||
const total = students.value.length
|
||||
if (total === 0) return '第 0-0 筆 / 共 0 筆'
|
||||
|
||||
const start = (currentPage.value - 1) * itemsPerPage + 1
|
||||
const end = Math.min(currentPage.value * itemsPerPage, total)
|
||||
return `第 ${start}-${end} 筆 / 共 ${total} 筆`
|
||||
})
|
||||
|
||||
// 彈窗狀態與流程控制
|
||||
const dialogVisible = ref(false)
|
||||
@@ -577,6 +645,12 @@ function resetSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
watch(pageCount, (value) => {
|
||||
if (currentPage.value > value) {
|
||||
currentPage.value = value
|
||||
}
|
||||
})
|
||||
|
||||
// 新增:開啟彈窗,使用預設值
|
||||
function openAddDialog() {
|
||||
loadSequence.value += 1
|
||||
|
||||
Reference in New Issue
Block a user