FPGA_WebLab/src/views/User/BoardTable.vue

233 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="flex flex-row justify-between items-center">
<h1 class="text-3xl font-bold mb-6">FPGA 设备管理</h1>
<div>
<button
class="btn btn-ghost group"
@click="tableManager.getAllBoards"
>
<RefreshCw class="w-4 h-4 mr-2 transition-transform duration-300 group-hover:rotate-180" />
刷新
</button>
<button
class="btn btn-ghost text-error hover:underline group"
@click="tableManager.toggleEditMode"
>
<Edit class="w-4 h-4 mr-2 transition-transform duration-200 group-hover:scale-110" />
编辑
</button>
</div>
</div>
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<!-- 搜索和列控制 -->
<div class="flex items-center my-2 gap-4">
<input
type="text"
placeholder="筛选 IP 地址..."
class="input input-bordered max-w-sm"
:value="
tableManager.getColumnByKey('devAddr')?.getFilterValue() as string
"
@input="
tableManager
.getColumnByKey('devAddr')
?.setFilterValue(($event.target as HTMLInputElement).value)
"
/>
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="btn btn-outline">
列显示
<svg
class="w-4 h-4 ml-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m19 9-7 7-7-7"
></path>
</svg>
</div>
<ul
tabindex="0"
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52"
>
<li
v-for="column in tableManager.getAllHideableColumns()"
:key="column.id"
>
<label class="label cursor-pointer">
<span class="label-text capitalize">{{ column.id }}</span>
<input
type="checkbox"
class="checkbox checkbox-sm"
:checked="column.getIsVisible()"
@change="
column.toggleVisibility(
!!($event.target as HTMLInputElement).checked,
)
"
/>
</label>
</li>
</ul>
</div>
<div class="flex gap-2 ml-auto">
<button
class="btn btn-primary group"
:disabled="!tableManager.isEditMode.value"
@click="showAddBoardDialog = true"
>
<Plus class="w-4 h-4 mr-2 transition-transform duration-200 group-hover:scale-110" />
新增实验板
</button>
<button
class="btn btn-error group"
:disabled="!tableManager.isEditMode.value"
@click="tableManager.deleteSelectedBoards"
>
<Trash2 class="w-4 h-4 mr-2 transition-transform duration-200 group-hover:scale-110 group-hover:animate-pulse" />
删除选中
</button>
</div>
</div>
<!-- 表格 -->
<div class="overflow-x-auto border border-base-300 rounded-lg">
<table class="table w-full">
<thead>
<tr
v-for="headerGroup in tableManager.getHeaderGroups()"
:key="headerGroup.id"
class="bg-base-300"
>
<th v-for="header in headerGroup.headers" :key="header.id">
<FlexRender
v-if="!header.isPlaceholder"
:render="header.column.columnDef.header"
:props="header.getContext()"
/>
</th>
</tr>
</thead>
<tbody>
<template v-if="tableManager.getRowModel().rows?.length">
<template
v-for="row in tableManager.getRowModel().rows"
:key="row.id"
>
<tr
class="hover"
:class="{ 'bg-primary/10': row.getIsSelected() }"
>
<td v-for="cell in row.getVisibleCells()" :key="cell.id">
<FlexRender
:render="cell.column.columnDef.cell"
:props="cell.getContext()"
/>
</td>
</tr>
<tr v-if="row.getIsExpanded()">
<td :colspan="row.getAllCells().length" class="bg-base-200">
<div class="p-4">
<pre class="text-sm">{{
JSON.stringify(row.original, null, 2)
}}</pre>
</div>
</td>
</tr>
</template>
</template>
<tr v-else>
<td
:colspan="tableManager.columns.length"
class="h-24 text-center text-base-content/60"
>
暂无数据
</td>
</tr>
</tbody>
</table>
</div>
<!-- 分页控制 -->
<div class="flex items-center justify-between py-4">
<div class="text-sm text-base-content/60">
已选择 {{ tableManager.getSelectedRows().length }} /
{{ tableManager.getAllRows().length }} 行
</div>
<div class="flex gap-2">
<button
class="btn btn-outline btn-sm"
:disabled="!tableManager.canPreviousPage()"
@click="tableManager.previousPage()"
>
上一页
</button>
<button
class="btn btn-outline btn-sm"
:disabled="!tableManager.canNextPage()"
@click="tableManager.nextPage()"
>
下一页
</button>
</div>
</div>
<div class="mt-6 bg-base-300 p-4 rounded-lg">
<p class="text-sm opacity-80">
<span class="font-semibold text-error">提示:</span>
请谨慎操作FPGA固化和热启动功能确保上传的位流文件无误以避免设备损坏。
</p>
</div>
</div>
</div>
<!-- 新增实验板对话框 -->
<AddBoardDialog
v-model:visible="showAddBoardDialog"
@success="handleAddBoardSuccess"
/>
</template>
<script lang="ts" setup>
import { FlexRender } from "@tanstack/vue-table";
import { onMounted, ref } from "vue";
import { RefreshCw, Edit, Plus, Trash2 } from "lucide-vue-next";
import { useProvideBoardManager } from "./BoardManager";
import { useProvideBoardTableManager } from "./BoardTableManager";
import AddBoardDialog from "./AddBoardDialog.vue";
// 使用 BoardManager
const boardManager = useProvideBoardManager()!;
// 使用表格管理器(不再需要参数)
const tableManager = useProvideBoardTableManager()!;
// 新增实验板对话框显示状态
const showAddBoardDialog = ref(false);
// 处理新增实验板成功事件
const handleAddBoardSuccess = () => {
showAddBoardDialog.value = false;
// 刷新数据在 BoardManager.addBoard 中已经处理
};
onMounted(() => {
// 初始化数据
boardManager.getAllBoards();
});
</script>
<style scoped lang="postcss">
@import "@/assets/main.css";
</style>