Compare commits
2 Commits
915f3b7f2f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| aa49d78a84 | |||
| afbdea6b13 |
@@ -130,7 +130,7 @@ src/
|
||||
│
|
||||
├── components/
|
||||
│ ├── sections/ ← 新增:Section / Shelf 層
|
||||
│ │ ├── SectionSearchPanel.vue
|
||||
│ │ ├
|
||||
│ │ ├── SectionDataTable.vue
|
||||
│ │ └── SectionFormPanel.vue
|
||||
│ │
|
||||
|
||||
@@ -114,7 +114,6 @@ router -> App.vue -> AppShell -> layout -> view -> page component -> section ->
|
||||
|
||||
`components/sections` 是頁面區塊容器:
|
||||
|
||||
- [SectionSearchPanel.vue](../src/components/sections/SectionSearchPanel.vue)
|
||||
- [SectionDataTable.vue](../src/components/sections/SectionDataTable.vue)
|
||||
- [SectionFormPanel.vue](../src/components/sections/SectionFormPanel.vue)
|
||||
- [SectionFormPage.vue](../src/components/sections/SectionFormPage.vue)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<v-chip color="info" variant="tonal">筆數 {{ filteredStudents.length }}</v-chip>
|
||||
<v-spacer />
|
||||
<v-btn flat :prepend-icon="mdiMagnify" @click="isSearchVisible = !isSearchVisible"
|
||||
>條件搜尋</v-btn
|
||||
>顯示條件搜尋</v-btn
|
||||
>
|
||||
<v-switch v-model="isBulkEditEnabled" color="primary" hide-details label="啟用編輯" />
|
||||
</v-card-title>
|
||||
@@ -19,37 +19,31 @@
|
||||
<v-card-text class="pb-0 pt-2">
|
||||
<v-row v-if="isSearchVisible" class="mb-2" density="compact">
|
||||
<v-col cols="12" md="3">
|
||||
<div class="text-body-1 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
v-model="search.studentId"
|
||||
clearable
|
||||
density="compact"
|
||||
hide-details
|
||||
label="學號"
|
||||
:label-char-count="2"
|
||||
placeholder="例如:S2024001"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<div class="text-body-1 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
v-model="search.name"
|
||||
clearable
|
||||
density="compact"
|
||||
hide-details
|
||||
label="姓名"
|
||||
:label-char-count="2"
|
||||
placeholder="例如:王小明"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<div class="text-body-1 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
v-model="search.department"
|
||||
:class="{ 'select-hide-arrow': !isBulkEditEnabled }"
|
||||
clearable
|
||||
density="compact"
|
||||
hide-details
|
||||
label="系所"
|
||||
:label-char-count="2"
|
||||
:items="departments"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -374,6 +368,8 @@
|
||||
<script setup lang="ts">
|
||||
import { mdiContentSave, mdiDelete, mdiMagnify, mdiRestore } from '@mdi/js'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
|
||||
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
|
||||
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
|
||||
import { useEditableStudentGrid } from '@/composables/maint/useEditableStudentGrid'
|
||||
|
||||
@@ -414,7 +410,9 @@ const {
|
||||
|
||||
const itemsPerPage = 10
|
||||
const currentPage = ref(1)
|
||||
const pageCount = computed(() => Math.max(1, Math.ceil(filteredStudents.value.length / itemsPerPage)))
|
||||
const pageCount = computed(() =>
|
||||
Math.max(1, Math.ceil(filteredStudents.value.length / itemsPerPage))
|
||||
)
|
||||
const pageSummary = computed(() => {
|
||||
const total = filteredStudents.value.length
|
||||
if (total === 0) return '第 0-0 筆 / 共 0 筆'
|
||||
@@ -443,8 +441,7 @@ const singleDeleteMessage = computed(() => {
|
||||
})
|
||||
|
||||
const selectedDeleteMessage = computed(
|
||||
() =>
|
||||
`確定要刪除目前選取的 ${selectedRowIds.value.length} 筆資料嗎?此操作會在儲存後正式生效。`
|
||||
() => `確定要刪除目前選取的 ${selectedRowIds.value.length} 筆資料嗎?此操作會在儲存後正式生效。`
|
||||
)
|
||||
|
||||
watch(pageCount, (value) => {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:icon="mdAndUp ? false : mdiMagnify"
|
||||
:prepend-icon="mdAndUp ? mdiMagnify : undefined"
|
||||
size="small"
|
||||
:text="mdAndUp ? '搜尋條件' : false"
|
||||
:text="mdAndUp ? '顯示搜尋條件' : false"
|
||||
variant="text"
|
||||
@click="$emit('toggle-search')"
|
||||
>
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { mdiBroom, mdiMagnify } from '@mdi/js'
|
||||
|
||||
interface GradeOption {
|
||||
title: string
|
||||
value: number
|
||||
}
|
||||
|
||||
interface SearchState {
|
||||
studentId: string
|
||||
name: string
|
||||
department: string
|
||||
grade: number | null
|
||||
status: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
departments: string[]
|
||||
gradeOptions: GradeOption[]
|
||||
statuses: string[]
|
||||
}>()
|
||||
|
||||
const search = defineModel<SearchState>({ required: true })
|
||||
|
||||
defineEmits<{
|
||||
(e: 'reset'): void
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-col cols="12" md="2">
|
||||
<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 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 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 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 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="$emit('reset')">清除</v-btn>
|
||||
<v-btn color="primary" disabled :prepend-icon="mdiMagnify" variant="tonal">查詢</v-btn>
|
||||
</v-col>
|
||||
</template>
|
||||
@@ -5,7 +5,7 @@ export const routes: RouteRecordRaw[] = [
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('@/views/Home.vue'),
|
||||
meta: { layout: 'default', requiresAuth: true },
|
||||
meta: { layout: 'default', requiresAuth: false },
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
@@ -17,7 +17,7 @@ export const routes: RouteRecordRaw[] = [
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/views/Login.vue'),
|
||||
meta: { layout: 'none', guestOnly: true },
|
||||
meta: { layout: 'none', guestOnly: false },
|
||||
},
|
||||
{
|
||||
path: '/single-record-maintenance',
|
||||
|
||||
+57
-129
@@ -2,7 +2,8 @@
|
||||
import { mdiEyeOutline, mdiFolderOutline } from '@mdi/js'
|
||||
import { useHomePage } from '@/composables/page-drivers/useHomePage'
|
||||
|
||||
const { handleMessageCenter, handleNews, handleQuick, isNewsDialogOpen, pageModel, selectedNews } = useHomePage()
|
||||
const { handleMessageCenter, handleNews, handleQuick, isNewsDialogOpen, pageModel, selectedNews } =
|
||||
useHomePage()
|
||||
|
||||
interface NewsItem {
|
||||
id: number
|
||||
@@ -24,63 +25,55 @@ function resolveNewsItem(wrapped: unknown): NewsItem {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container class="pa-0" fluid>
|
||||
<div class="d-flex flex-column ga-5 pt-1 pb-4 pr-2 pl-0">
|
||||
<v-sheet
|
||||
class="d-flex flex-column flex-sm-row align-start align-sm-center ga-4 pa-5 elevation-1"
|
||||
color="surface"
|
||||
>
|
||||
<v-avatar color="primary" size="52" variant="tonal">
|
||||
<span class="text-h5">👋</span>
|
||||
</v-avatar>
|
||||
<div>
|
||||
<div class="text-h5 font-weight-bold">歡迎使用校務資訊系統</div>
|
||||
<div class="text-body-2 text-medium-emphasis mt-1">
|
||||
<v-sheet>
|
||||
<v-container fluid class="pa-0 px-2">
|
||||
<v-card variant="flat">
|
||||
<v-card-title> 歡迎使用校務資訊系統 </v-card-title>
|
||||
<v-card-text class="text-grey">
|
||||
使用頂部搜尋框快速找到功能,或從左側選單瀏覽所有系統模組
|
||||
</div>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<section class="d-flex flex-column">
|
||||
<div class="d-flex align-center ga-2 text-h6 font-weight-bold">📰 最新消息</div>
|
||||
<v-data-iterator class="mt-2" item-key="id" :items="pageModel.newsItems" :items-per-page="-1">
|
||||
<v-card variant="flat" border="thin primary" class="pa-4">
|
||||
<v-card-title class="mb-4"> 最新消息 </v-card-title>
|
||||
<v-data-iterator item-key="id" :items="pageModel.newsItems" :items-per-page="-1">
|
||||
<template #default="{ items }">
|
||||
<v-row density="compact">
|
||||
<v-col v-for="wrapped in items" :key="resolveNewsItem(wrapped).id" cols="12">
|
||||
<v-card
|
||||
class="news-item d-flex flex-column flex-sm-row ga-4 pa-4 bg-surface"
|
||||
variant="outlined"
|
||||
@click="handleNews(resolveNewsItem(wrapped))"
|
||||
>
|
||||
<v-sheet class="news-badge">
|
||||
<div class="news-badge-date">{{ resolveNewsItem(wrapped).date }}</div>
|
||||
<div class="news-badge-month">{{ resolveNewsItem(wrapped).month }}</div>
|
||||
</v-sheet>
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex flex-wrap align-center font-weight-bold">
|
||||
<v-card @click="handleNews(resolveNewsItem(wrapped))">
|
||||
<div class="d-flex flex-no-wrap">
|
||||
<v-avatar rounded="0" size="64" class="flex-column bg-primary">
|
||||
<div>
|
||||
{{ resolveNewsItem(wrapped).date }}
|
||||
</div>
|
||||
<div>
|
||||
{{ resolveNewsItem(wrapped).month }}
|
||||
</div>
|
||||
</v-avatar>
|
||||
<div class="flex-fill">
|
||||
<v-card-title>
|
||||
{{ resolveNewsItem(wrapped).title }}
|
||||
<v-chip
|
||||
v-if="resolveNewsItem(wrapped).isNew"
|
||||
class="ml-2"
|
||||
color="primary"
|
||||
color="yellow"
|
||||
size="x-small"
|
||||
variant="flat"
|
||||
>
|
||||
NEW
|
||||
</v-chip>
|
||||
</div>
|
||||
<div class="text-body-2 text-medium-emphasis mt-2">
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-4">
|
||||
{{ resolveNewsItem(wrapped).desc }}
|
||||
</div>
|
||||
<div class="d-flex ga-4 mt-3 text-caption text-medium-emphasis">
|
||||
<div class="d-flex align-center ga-1">
|
||||
</v-card-text>
|
||||
<v-card-text class="pt-0">
|
||||
<v-row align="center">
|
||||
<v-icon size="14" :icon="mdiFolderOutline" />
|
||||
<span>{{ resolveNewsItem(wrapped).dept }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-center ga-1">
|
||||
<v-col cols="1"> {{ resolveNewsItem(wrapped).dept }}</v-col>
|
||||
<v-icon size="14" :icon="mdiEyeOutline" />
|
||||
<span>{{ resolveNewsItem(wrapped).views }} 次瀏覽</span>
|
||||
</div>
|
||||
<v-col>{{ resolveNewsItem(wrapped).views }} 次瀏覽</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
@@ -88,116 +81,51 @@ function resolveNewsItem(wrapped: unknown): NewsItem {
|
||||
</v-row>
|
||||
</template>
|
||||
</v-data-iterator>
|
||||
</section>
|
||||
|
||||
<v-card
|
||||
class="d-flex align-center justify-space-between ga-3 px-5 py-4"
|
||||
color="secondary"
|
||||
rounded="xl"
|
||||
variant="tonal"
|
||||
@click="handleMessageCenter"
|
||||
>
|
||||
<div class="d-flex align-center ga-4">
|
||||
<v-avatar color="secondary" size="44" variant="flat">
|
||||
<span class="text-h6">✉️</span>
|
||||
</v-avatar>
|
||||
<div>
|
||||
<div class="text-subtitle-1 font-weight-bold">訊息中心</div>
|
||||
<div class="text-body-2 font-weight-bold text-on-secondary">12 筆未讀</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-body-2 font-weight-medium">查看全部 →</div>
|
||||
</v-card>
|
||||
|
||||
<section class="d-flex flex-column pb-4">
|
||||
<div class="d-flex align-center ga-2 text-h6 font-weight-bold">🚀 快速存取</div>
|
||||
<v-row class="mt-2" density="compact">
|
||||
<v-col v-for="item in pageModel.quickItems" :key="item.title" cols="6" md="2" sm="4">
|
||||
<v-card class="pa-4 mt-4" @click="handleMessageCenter">
|
||||
<v-card-title class="mb-4"> 訊息中心 </v-card-title>
|
||||
<v-card-text class="text-body-large text-secondary">
|
||||
有 {{ Math.floor(Math.random() * 10) }} 筆未讀
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-card variant="flat" border="thin primary" class="pa-4 mt-4">
|
||||
<v-row density="compact" align="center">
|
||||
<v-card-title> 快速存取 </v-card-title>
|
||||
<v-col v-for="item in pageModel.quickItems" :key="item.title">
|
||||
<v-card
|
||||
class="d-flex flex-column align-center ga-2 text-center py-4 px-2 quick-item"
|
||||
variant="outlined"
|
||||
class="d-flex flex-column align-center ga-1 text-center py-3 px-2"
|
||||
color="primary-variant"
|
||||
variant="tonal"
|
||||
@click="handleQuick(item)"
|
||||
>
|
||||
<div class="text-h5">{{ item.icon }}</div>
|
||||
<div class="text-body-2 font-weight-medium">{{ item.title }}</div>
|
||||
<div class="text-body-medium font-weight-medium">{{ item.title }}</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</section>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-container>
|
||||
|
||||
<v-dialog
|
||||
v-model="isNewsDialogOpen"
|
||||
max-width="640"
|
||||
>
|
||||
<v-dialog v-model="isNewsDialogOpen" max-width="640">
|
||||
<v-card v-if="selectedNews">
|
||||
<v-card-title class="text-h6 font-weight-bold bg-primary-variant pa-4">
|
||||
{{ selectedNews.title }}
|
||||
</v-card-title>
|
||||
<v-card-subtitle class="text-body-2 pt-4 text-medium-emphasis">
|
||||
{{ selectedNews.month }} {{ selectedNews.date }} ·
|
||||
{{ selectedNews.dept }} · {{ selectedNews.views }} 次瀏覽
|
||||
{{ selectedNews.month }} {{ selectedNews.date }} · {{ selectedNews.dept }} ·
|
||||
{{ selectedNews.views }} 次瀏覽
|
||||
</v-card-subtitle>
|
||||
<v-card-text class="pt-4">
|
||||
{{ selectedNews.desc }}
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn color="primary" variant="text" @click="isNewsDialogOpen = false">
|
||||
關閉
|
||||
</v-btn>
|
||||
<v-btn color="primary" variant="text" @click="isNewsDialogOpen = false"> 關閉 </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</v-sheet>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.news-item {
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.news-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 24px rgba(var(--v-theme-on-surface), 0.12);
|
||||
}
|
||||
|
||||
.news-badge {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgb(var(--v-theme-primary));
|
||||
color: rgb(var(--v-theme-on-primary));
|
||||
border-radius: 12px;
|
||||
padding: 10px 6px;
|
||||
min-height: 64px;
|
||||
min-width: 64px;
|
||||
}
|
||||
|
||||
.news-badge-date {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.news-badge-month {
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.quick-item {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.quick-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 24px rgba(var(--v-theme-on-surface), 0.12);
|
||||
}
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
|
||||
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
|
||||
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
|
||||
import DetailNavigation from '@/components/maint/master-detail/DetailNavigation.vue'
|
||||
import DetailSidePanel from '@/components/maint/master-detail/DetailSidePanel.vue'
|
||||
@@ -7,7 +9,6 @@ import MntDialogCard from '@/components/maint/MntDialogCard.vue'
|
||||
import MntRecordNavToolbar from '@/components/maint/MntRecordNavToolbar.vue'
|
||||
import MaintShell from '@/components/maint/MaintShell.vue'
|
||||
import SectionDataTable from '@/components/sections/SectionDataTable.vue'
|
||||
import SectionSearchPanel from '@/components/sections/SectionSearchPanel.vue'
|
||||
import { useMasterDetailAMaintenancePage } from '@/composables/page-drivers/useMasterDetailAMaintenancePage'
|
||||
|
||||
const {
|
||||
@@ -27,13 +28,62 @@ const {
|
||||
@create="openAddDialog"
|
||||
>
|
||||
<template #search-fields>
|
||||
<SectionSearchPanel
|
||||
v-model="search"
|
||||
:departments="masterDetailProps.departments"
|
||||
:grade-options="masterDetailProps.gradeOptions"
|
||||
:statuses="masterDetailProps.statuses"
|
||||
@reset="resetSearch"
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormTextField
|
||||
id="search-student-id"
|
||||
v-model="search.studentId"
|
||||
label="學號"
|
||||
:label-char-count="2"
|
||||
name="searchStudentId"
|
||||
placeholder="例如:S2024001"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormTextField
|
||||
id="search-name"
|
||||
v-model="search.name"
|
||||
label="姓名"
|
||||
:label-char-count="2"
|
||||
name="searchName"
|
||||
placeholder="例如:王小明"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-department"
|
||||
v-model="search.department"
|
||||
label="系所"
|
||||
:label-char-count="2"
|
||||
:items="departments"
|
||||
name="searchDepartment"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-grade"
|
||||
v-model="search.grade"
|
||||
label="年級"
|
||||
:label-char-count="2"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:items="gradeOptions"
|
||||
name="searchGrade"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-status"
|
||||
v-model="search.status"
|
||||
label="狀態"
|
||||
:label-char-count="2"
|
||||
:items="statuses"
|
||||
name="searchStatus"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
|
||||
<v-btn variant="text" @click="resetSearch">清除</v-btn>
|
||||
<v-btn color="primary" disabled variant="tonal">查詢</v-btn>
|
||||
</v-col>
|
||||
</template>
|
||||
<template #table>
|
||||
<SectionDataTable
|
||||
|
||||
@@ -9,70 +9,55 @@
|
||||
<!-- 搜尋欄位放在 MaintShell 的 search-fields slot,讓外殼固定、欄位由頁面決定。 -->
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
id="search-student-id"
|
||||
v-model="search.studentId"
|
||||
aria-labelledby="search-student-id-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="學號"
|
||||
:label-char-count="2"
|
||||
name="searchStudentId"
|
||||
placeholder="例如:S2024001"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
id="search-name"
|
||||
v-model="search.name"
|
||||
aria-labelledby="search-name-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="姓名"
|
||||
:label-char-count="2"
|
||||
name="searchName"
|
||||
placeholder="例如:王小明"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-department"
|
||||
v-model="search.department"
|
||||
aria-labelledby="search-department-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="系所"
|
||||
:label-char-count="2"
|
||||
:items="departments"
|
||||
name="searchDepartment"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-grade"
|
||||
v-model="search.grade"
|
||||
aria-labelledby="search-grade-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="年級"
|
||||
:label-char-count="2"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:items="gradeOptions"
|
||||
name="searchGrade"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-status"
|
||||
v-model="search.status"
|
||||
aria-labelledby="search-status-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="狀態"
|
||||
:label-char-count="2"
|
||||
: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">
|
||||
@@ -505,6 +490,8 @@ import { mdiBookPlus, mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil } from
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
|
||||
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
|
||||
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
|
||||
import DetailCollapseGropus from '@/components/maint/master-detail/DetailCollapseGropus.vue'
|
||||
import DetailFullHeightPanel from '@/components/maint/master-detail/DetailFullHeightPanel.vue'
|
||||
|
||||
@@ -9,70 +9,55 @@
|
||||
<!-- 搜尋欄位放在 MaintShell 的 search-fields slot,讓外殼固定、欄位由頁面決定。 -->
|
||||
<template #search-fields>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-student-id-label" class="text-body-2 text-medium-emphasis pl-2">學號</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
id="search-student-id"
|
||||
v-model="search.studentId"
|
||||
aria-labelledby="search-student-id-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="學號"
|
||||
:label-char-count="2"
|
||||
name="searchStudentId"
|
||||
placeholder="例如:S2024001"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-name-label" class="text-body-2 text-medium-emphasis pl-2">姓名</div>
|
||||
<v-text-field
|
||||
<BaseFormTextField
|
||||
id="search-name"
|
||||
v-model="search.name"
|
||||
aria-labelledby="search-name-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="姓名"
|
||||
:label-char-count="2"
|
||||
name="searchName"
|
||||
placeholder="例如:王小明"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-department-label" class="text-body-2 text-medium-emphasis pl-2">系所</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-department"
|
||||
v-model="search.department"
|
||||
aria-labelledby="search-department-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="系所"
|
||||
:label-char-count="2"
|
||||
:items="departments"
|
||||
name="searchDepartment"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-grade-label" class="text-body-2 text-medium-emphasis pl-2">年級</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-grade"
|
||||
v-model="search.grade"
|
||||
aria-labelledby="search-grade-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="年級"
|
||||
:label-char-count="2"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:items="gradeOptions"
|
||||
name="searchGrade"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<div id="search-status-label" class="text-body-2 text-medium-emphasis pl-2">狀態</div>
|
||||
<v-select
|
||||
<BaseFormSelect
|
||||
id="search-status"
|
||||
v-model="search.status"
|
||||
aria-labelledby="search-status-label"
|
||||
density="compact"
|
||||
hide-details
|
||||
label="狀態"
|
||||
:label-char-count="2"
|
||||
: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">
|
||||
@@ -492,6 +477,8 @@ import { mdiBroom, mdiDelete, mdiEye, mdiMagnify, mdiPencil, mdiSchool } from '@
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
|
||||
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
|
||||
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
|
||||
import MasterDetailCCourseMobilePanel from '@/components/maint/master-detail/CourseMobilePanel.vue'
|
||||
import DetailSimpleList from '@/components/maint/master-detail/DetailSimpleList.vue'
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
|
||||
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
|
||||
import MaintShell from '@/components/maint/MaintShell.vue'
|
||||
import SectionDataTable from '@/components/sections/SectionDataTable.vue'
|
||||
import SectionFormPanel from '@/components/sections/SectionFormPanel.vue'
|
||||
import SectionSearchPanel from '@/components/sections/SectionSearchPanel.vue'
|
||||
import { useSingleRecordMaintenancePage } from '@/composables/page-drivers/useSingleRecordMaintenancePage'
|
||||
|
||||
const {
|
||||
@@ -21,13 +22,62 @@ const {
|
||||
@create="commands.openAddDialog"
|
||||
>
|
||||
<template #search-fields>
|
||||
<SectionSearchPanel
|
||||
v-model="search"
|
||||
:departments="departments"
|
||||
:grade-options="gradeOptions"
|
||||
:statuses="statuses"
|
||||
@reset="resetSearch"
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormTextField
|
||||
id="search-student-id"
|
||||
v-model="search.studentId"
|
||||
label="學號"
|
||||
:label-char-count="2"
|
||||
name="searchStudentId"
|
||||
placeholder="例如:S2024001"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormTextField
|
||||
id="search-name"
|
||||
v-model="search.name"
|
||||
label="姓名"
|
||||
:label-char-count="2"
|
||||
name="searchName"
|
||||
placeholder="例如:王小明"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-department"
|
||||
v-model="search.department"
|
||||
label="系所"
|
||||
:label-char-count="2"
|
||||
:items="departments"
|
||||
name="searchDepartment"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-grade"
|
||||
v-model="search.grade"
|
||||
label="年級"
|
||||
:label-char-count="2"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:items="gradeOptions"
|
||||
name="searchGrade"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<BaseFormSelect
|
||||
id="search-status"
|
||||
v-model="search.status"
|
||||
label="狀態"
|
||||
:label-char-count="2"
|
||||
:items="statuses"
|
||||
name="searchStatus"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
|
||||
<v-btn variant="text" @click="resetSearch">清除</v-btn>
|
||||
<v-btn color="primary" disabled variant="tonal">查詢</v-btn>
|
||||
</v-col>
|
||||
</template>
|
||||
<template #table>
|
||||
<SectionDataTable
|
||||
|
||||
Reference in New Issue
Block a user