Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add admin tags #865

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions frontend/src/components/admin_next/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import AdminUserList from "../users/AdminUserList.vue";
import AdminUserDetail from "../users/AdminUserDetail.vue";
import AdminSystemConfig from "../system_configs/AdminSystemConfig.vue";
import AdminSyncSetting from "../sync/AdminSyncSetting.vue";
import AdminTagsList from "../tags/AdminTagsList.vue";
import AdminTagsDetail from "../tags/AdminTagsDetail.vue";
import AdminTagsForm from "../tags/AdminTagsForm.vue";
import { Setting, User, Connection } from "@element-plus/icons-vue";
import { useCookies } from 'vue3-cookies'

Expand Down Expand Up @@ -64,6 +67,32 @@ export const MENU_SETTING = [
icon: "admin-menu-cloud",
type: "item",
},
{
path: `${BASE_URL}/tags`,
component: AdminTagsList,
name: adminLocale.tags.title,
parentName: PARENT_NAME.BASE_CONFIG,
icon: 'admin-menu-cloud',
type: 'item'
},
{
path: `${BASE_URL}/tags/new`,
component: AdminTagsForm,
name: adminLocale.tags.newTag,
parentName: PARENT_NAME.BASE_CONFIG
},
{
path: `${BASE_URL}/tags/:id/edit`,
component: AdminTagsForm,
name: adminLocale.tags.editTag,
parentName: PARENT_NAME.BASE_CONFIG
},
{
path: `${BASE_URL}/tags/:id`,
component: AdminTagsDetail,
name: adminLocale.tags.tagDetailTitle,
parentName: PARENT_NAME.BASE_CONFIG
},
];

export const menuRenderList = PARENT_NAME_LIST.reduce((acc, item) => {
Expand Down
79 changes: 79 additions & 0 deletions frontend/src/components/admin_next/tags/AdminTagsDetail.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<Container
:title="$t('admin.tags.tagDetailTitle')"
subtitle=""
:showBack="true"
:breadcrumbs="[
{
text: $t('admin.tags.title'),
to: '/admin_panel/tags'
},
{ text: `Tags #${tagInfo.name}` }
]">
<Card :title="`Tags #${tagInfo.name}`">
<ul class="">
<li class="flex mb-4">
<label class="admin-field-label">Name</label>
<p class="admin-field">{{ tagInfo.username }}</p>
</li>
<li class="flex mb-4">
<label class="admin-field-label">Show Name</label>
<p class="admin-field">{{ tagInfo.show_name }}</p>
</li>
<li class="flex mb-4">
<label class="admin-field-label">Category</label>
<p class="admin-field">{{ tagInfo.category }}</p>
</li>
<li class="flex mb-4">
<label class="admin-field-label">Scope</label>
<p class="admin-field">{{ tagInfo.scope }}</p>
</li>
<li class="flex mb-4">
<label class="admin-field-label">Group</label>
<p class="admin-field">{{ tagInfo.group }}</p>
</li>
<li class="flex mb-4">
<label class="admin-field-label">Created At</label>
<p class="admin-field">
{{ dayjs(tagInfo.created_at).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</li>
</ul>
<template #footer>
<div class="card-footer">
<router-link :to="`/admin_panel/tags/${tagInfo.id}/edit`">
<CsgButton
class="btn btn-primary btn-md"
:name="$t('admin.tags.editBtn')" />
</router-link>
</div>
</template>
</Card>
</Container>
</template>

<script setup>
import { Container, Card, Pagination, Table } from '../admin_component'
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import dayjs from 'dayjs'
import useFetchApi from '../../../packs/useFetchApi'
const route = useRoute()
const tagInfo = ref({})
const fetchTag = async () => {
const { data } = await useFetchApi(`/tags/${route.params.id}`).json()
if (data.value) {
const result = data.value
tagInfo.value = result.data
} else {
ElMessage.error('Failed to fetch user')
}
}
onMounted(() => {
fetchTag()
})
</script>
208 changes: 208 additions & 0 deletions frontend/src/components/admin_next/tags/AdminTagsForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
<template>
<Container
:title="dataForm.name ? `Edit Tag #${dataForm.name}` : 'Create Tag'"
:showBack="true"
:breadcrumbs="[
{ text: $t('admin.tags.title'), to: `${BASE_URL}/tags` },
breadcrumbsTitle === 'edit'
? {
text: `Edit Tag #${dataForm.name}`,
to: `${BASE_URL}/tags/${dataForm.name}`
}
: { text: 'Tags', to: `${BASE_URL}/tags` },
{ text: breadcrumbsTitle }
]">
<el-form
ref="dataFormRef"
:model="dataForm"
:rules="rules"
class="w-full flex flex-col gap-[14px]"
label-position="top">
<el-form-item
label="Name"
prop="name"
class="w-full">
<el-input v-model="dataForm.name" />
</el-form-item>
<el-form-item
label="Show Name"
prop="show_name"
class="w-full">
<el-input v-model="dataForm.show_name" />
</el-form-item>
<el-form-item
label="Category"
prop="category"
class="w-full">
<el-input v-model="dataForm.category" />
</el-form-item>
<el-form-item
label="Scope"
prop="scope"
class="w-full">
<el-select
v-model="dataForm.scope"
size="large"
placeholder="scope name">
<el-option
label="model"
value="model"></el-option>
<el-option
label="dataset"
value="dataset"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="Group"
prop="group"
class="w-full">
<el-input v-model="dataForm.group" />
</el-form-item>
<el-form-item
label="Built In"
prop="built_in"
class="w-full">
<el-switch
v-model="dataForm.built_in"
size="large" />
</el-form-item>
<el-form-item class="w-full">
<div class="flex justify-end w-full">
<CsgButton
class="btn btn-primary btn-md"
:name="$t('admin.syncSetting.submit')"
@click="handleSubmit" />
</div>
</el-form-item>
</el-form>
</Container>
</template>

<script setup>
import { Container, Pagination, Table } from '../admin_component'
import { ref, onMounted, computed } from 'vue'
import useFetchApi from '../../../packs/useFetchApi'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import { BASE_URL } from '../router'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const router = useRouter()
const breadcrumbsTitle = computed(() =>
router.currentRoute.value.fullPath === '/admin_panel/tags/new'
? 'new'
: 'edit'
)
const dataForm = ref({
built_in: true,
category: '',
group: '',
name: '',
scope: '',
show_name: ''
})
const dataFormRef = ref(null)
const rules = {
name: [{ required: true, message: 'name is required', trigger: 'blur' }],
scope: [{ required: true, message: 'scope is required', trigger: 'change' }]
}
const handleSubmit = () => {
dataFormRef.value.validate((valid) => {
if (valid) {
createOrUpdate()
} else {
return false
}
})
}
const createOrUpdate = () => {
if (dataForm.value.id) {
update()
} else {
create()
}
}
const create = async () => {
const { data } = await useFetchApi(`/tags`, {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(dataForm.value)
})
.post()
.json()
if (data.value) {
ElMessage({
message: t('admin.createSuccess'),
type: 'success'
})
router.push({ path: '/admin_panel/tags' })
} else {
ElMessage.error('Failed to create Tag')
}
}
const update = async () => {
const { data } = await useFetchApi(`/tags/${dataForm.value.id}`, {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(dataForm.value)
})
.put()
.json()
if (data.value) {
ElMessage({
message: t('admin.updateSuccess'),
type: 'success'
})
router.push(`/admin_panel/tags`)
} else {
ElMessage.error('Failed to update Tag')
}
}
const fetchTag = async () => {
const id = router.currentRoute.value.params.id
const { data } = await useFetchApi(`/tags/${id}`).json()
if (data.value) {
const result = data.value
dataForm.value = result.data
} else {
ElMessage.error('Failed to fetch user')
}
}
onMounted(() => {
if (breadcrumbsTitle.value == 'edit') {
fetchTag()
}
})
</script>

<style>
.el-form-item {
margin-bottom: 24px;
}
.el-form-item__label {
margin-bottom: 6px;
}
:deep(.el-input__wrapper) {
border-radius: 8px;
}
:deep(.el-textarea__inner) {
border-radius: 8px;
}
:deep(.el-upload--picture-card) {
border: 0px;
}
.hide .el-upload.el-upload--picture-card {
display: none;
}
</style>
Loading
Loading