88 lines
2.4 KiB
Vue
88 lines
2.4 KiB
Vue
<template>
|
|
<el-card class="panel">
|
|
<div class="header">
|
|
<span>分类</span>
|
|
<div v-if="canMaintain">
|
|
<el-button type="primary" size="small" @click="openForm()">新建</el-button>
|
|
</div>
|
|
</div>
|
|
<el-menu :default-active="activeCategory" @select="onSelect">
|
|
<el-menu-item index="">全部</el-menu-item>
|
|
<el-menu-item v-for="c in sortedCategories" :key="c.id" :index="c.id">
|
|
<span>{{ c.name }}</span>
|
|
<el-tag v-if="c.study_id" size="small" type="success" class="ml-4">项目</el-tag>
|
|
<el-tag v-else size="small" class="ml-4">全局</el-tag>
|
|
<el-button
|
|
v-if="canEdit(c)"
|
|
type="text"
|
|
size="small"
|
|
style="margin-left: auto"
|
|
@click.stop="openForm(c)"
|
|
>
|
|
编辑
|
|
</el-button>
|
|
</el-menu-item>
|
|
</el-menu>
|
|
<FaqCategoryForm v-model="showForm" :category="editing" :is-admin="isAdmin" @success="emit('refresh')" />
|
|
</el-card>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref } from "vue";
|
|
import FaqCategoryForm from "./FaqCategoryForm.vue";
|
|
import type { FaqCategory } from "../api/faqs";
|
|
import { useAuthStore } from "../store/auth";
|
|
import { useStudyStore } from "../store/study";
|
|
|
|
const props = defineProps<{
|
|
categories: FaqCategory[];
|
|
modelValue: string;
|
|
}>();
|
|
const emit = defineEmits(["update:modelValue", "refresh"]);
|
|
|
|
const auth = useAuthStore();
|
|
const study = useStudyStore();
|
|
|
|
const showForm = ref(false);
|
|
const editing = ref<FaqCategory | null>(null);
|
|
|
|
const isAdmin = computed(() => auth.user?.role === "ADMIN");
|
|
const canMaintain = computed(() => isAdmin.value || auth.user?.role === "PM");
|
|
|
|
const sortedCategories = computed(() =>
|
|
[...props.categories].sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0))
|
|
);
|
|
|
|
const activeCategory = computed(() => props.modelValue || "");
|
|
|
|
const canEdit = (c: FaqCategory) => {
|
|
if (isAdmin.value) return true;
|
|
return auth.user?.role === "PM" && c.study_id === study.currentStudy?.id;
|
|
};
|
|
|
|
const onSelect = (id: string) => {
|
|
emit("update:modelValue", id);
|
|
};
|
|
|
|
const openForm = (cat?: FaqCategory) => {
|
|
editing.value = cat || null;
|
|
showForm.value = true;
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.panel {
|
|
padding: 0;
|
|
}
|
|
.header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 12px;
|
|
border-bottom: 1px solid #ebeef5;
|
|
}
|
|
.ml-4 {
|
|
margin-left: 4px;
|
|
}
|
|
</style>
|