Add chart detail page

This commit is contained in:
cuigh
2021-12-15 20:15:25 +08:00
parent 118b5173ab
commit bd7b8364d9
12 changed files with 183 additions and 32 deletions

View File

@@ -187,6 +187,8 @@ export default {
"right": "Right",
"top": "Top",
"bottom": "Bottom",
"legend": "Legend",
"query": "Query",
"enabled": "Enabled",
"security": "Security",
"authentication": "Authentication",
@@ -304,6 +306,7 @@ export default {
"chart_list": "Charts",
"chart_new": "New chart",
"chart_edit": "Edit chart",
"chart_detail": "Chart detail",
"event_list": "Events",
"setting": "Settings",
"403": "403 Forbidden",

View File

@@ -187,6 +187,8 @@ export default {
"right": "右",
"top": "上",
"bottom": "下",
"legend": "图例",
"query": "查询",
"enabled": "启用",
"security": "安全",
"authentication": "认证",
@@ -304,6 +306,7 @@ export default {
"chart_list": "图表列表",
"chart_new": "新建图表",
"chart_edit": "编辑图表",
"chart_detail": "图表详情",
"event_list": "事件列表",
"setting": "设置",
"403": "403 禁止访问",

View File

@@ -140,7 +140,7 @@ import chartApi from "@/api/chart";
import type { Chart } from "@/api/chart";
import { useRoute } from "vue-router";
import { router } from "@/router/router";
import { useForm, requiredRule } from "@/utils/form";
import { useForm, requiredRule, customRule } from "@/utils/form";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
@@ -212,6 +212,9 @@ const dashboards = [
]
const rules: any = {
title: requiredRule(),
metrics: customRule((rule: any, value: any[]) => {
return !!value && value.length > 0
}, t('tips.required_rule')),
};
const form = ref();
const { submit, submiting } = useForm(form, () => chartApi.save(model.value), () => {

View File

@@ -84,7 +84,7 @@ const columns = [
title: t('fields.title'),
key: "title",
fixed: "left" as const,
render: (c: Chart) => renderLink(`/system/charts/${c.id}/edit`, c.title),
render: (c: Chart) => renderLink(`/system/charts/${c.id}`, c.title),
},
{
title: t('fields.type'),

108
ui/src/pages/chart/View.vue Normal file
View File

@@ -0,0 +1,108 @@
<template>
<x-page-header :subtitle="model.title">
<template #action>
<n-button secondary size="small" @click="$router.push('/system/charts')">
<template #icon>
<n-icon>
<back-icon />
</n-icon>
</template>
{{ t('buttons.return') }}
</n-button>
<n-button
secondary
size="small"
@click="$router.push(`/system/charts/${model.id}/edit`)"
>{{ t('buttons.edit') }}</n-button>
</template>
</x-page-header>
<n-space class="page-body" vertical :size="16">
<x-description :label-width="90">
<x-description-item :label="t('fields.id')">{{ model.id }}</x-description-item>
<x-description-item :label="t('fields.name')">{{ model.title }}</x-description-item>
<x-description-item :span="2" :label="t('fields.desc')">{{ model.desc }}</x-description-item>
<x-description-item :label="t('fields.width')">{{ model.width }}</x-description-item>
<x-description-item :label="t('fields.height')">{{ model.height }}</x-description-item>
<x-description-item :label="t('fields.unit')">{{ model.unit }}</x-description-item>
<x-description-item :label="t('fields.margin')">
<n-space :size="4" v-if="model.margin">
<x-pair-tag
type="warning"
:label="t('fields.left')"
:value="model.margin.left.toString()"
v-if="model.margin?.left"
/>
<x-pair-tag
type="warning"
:label="t('fields.right')"
:value="model.margin.right.toString()"
v-if="model.margin?.right"
/>
<x-pair-tag
type="warning"
:label="t('fields.top')"
:value="model.margin.top.toString()"
v-if="model.margin?.top"
/>
<x-pair-tag
type="warning"
:label="t('fields.bottom')"
:value="model.margin.bottom.toString()"
v-if="model.margin?.bottom"
/>
</n-space>
</x-description-item>
<x-description-item :label="t('fields.dashboard')">{{ model.dashboard }}</x-description-item>
<x-description-item :label="t('fields.type')">{{ model.type }}</x-description-item>
<x-description-item :label="t('fields.created_at')">{{ model.createdAt }}</x-description-item>
<x-description-item :label="t('fields.updated_at')">{{ model.updatedAt }}</x-description-item>
</x-description>
<x-panel :title="t('fields.metrics')">
<n-table size="small" :bordered="true" :single-line="false">
<thead>
<tr>
<th>{{ t('fields.legend') }}</th>
<th>{{ t('fields.query') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="m in model.metrics">
<td>{{ m.legend }}</td>
<td>{{ m.query }}</td>
</tr>
</tbody>
</n-table>
</x-panel>
</n-space>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import {
NButton,
NSpace,
NIcon,
NTable,
} from "naive-ui";
import { ArrowBackCircleOutline as BackIcon } from "@vicons/ionicons5";
import XPageHeader from "@/components/PageHeader.vue";
import XPairTag from "@/components/PairTag.vue";
import XPanel from "@/components/Panel.vue";
import chartApi from "@/api/chart";
import type { Chart } from "@/api/chart";
import { useRoute } from "vue-router";
import { XDescription, XDescriptionItem } from "@/components/description";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const route = useRoute();
const model = ref({} as Chart);
async function fetchData() {
const id = route.params.id as string;
let r = await chartApi.find(id);
model.value = r.data as Chart;
}
onMounted(fetchData);
</script>

View File

@@ -21,7 +21,12 @@
style="width: 140px"
clearable
/>
<n-input size="small" v-model:value="filter.name" :placeholder="t('fields.object')" clearable />
<n-input
size="small"
v-model:value="filter.name"
:placeholder="t('fields.object')"
clearable
/>
<n-button size="small" type="primary" @click="() => fetchData()">{{ t('buttons.search') }}</n-button>
</n-space>
<n-data-table
@@ -107,10 +112,6 @@ const types: any = [
label: 'Service',
value: 'Service'
},
{
label: 'Template',
value: 'Template'
},
{
label: 'Stack',
value: 'Stack'
@@ -192,14 +193,14 @@ const { state, pagination, fetchData, changePageSize } = useDataTable(eventApi.s
function url(e: Event): string {
switch (e.type) {
case "Authentication":
case "User":
return `/system/users/${e.code}`
case "Role":
return `/system/roles/${e.code}`
case "User":
return `/system/users/${e.code}`
case "Chart":
return `/system/charts/${e.code}`
case "Setting":
return '/system/setting'
return '/system/settings'
case "Registry":
return `/swarm/registries/${e.code}`
case "Node":
@@ -208,8 +209,6 @@ function url(e: Event): string {
return `/swarm/networks/${e.code}`
case "Service":
return `/swarm/services/${e.code}`
case "Template":
return `/swarm/templates/${e.code}`
case "Stack":
return `/swarm/stacks/${e.code}`
case "Config":

View File

@@ -281,6 +281,11 @@ const routes: RouteRecordRaw[] = [
path: "/system/charts",
component: () => import('../pages/chart/List.vue'),
},
{
name: "chart_detail",
path: "/system/charts/:id",
component: () => import('../pages/chart/View.vue'),
},
{
name: "chart_new",
path: "/system/charts/new",