mirror of
https://github.com/cuigh/swirl
synced 2025-06-26 18:16:50 +00:00
Make event objects more extensible
This commit is contained in:
@@ -4,8 +4,9 @@ export interface Event {
|
||||
id: string;
|
||||
type: string;
|
||||
action: string;
|
||||
code: number;
|
||||
name: string;
|
||||
args: {
|
||||
[key: string]: string;
|
||||
};
|
||||
userId: string;
|
||||
username: string;
|
||||
time: number;
|
||||
|
||||
@@ -291,236 +291,3 @@ export function createChart(dom: HTMLElement, info: ChartInfo): Chart {
|
||||
throw new Error('unknown chart type: ' + info.type)
|
||||
}
|
||||
}
|
||||
|
||||
// export class ChartDashboardOptions {
|
||||
// name: string;
|
||||
// key?: string;
|
||||
// period?: number = 30;
|
||||
// refreshInterval?: number = 15; // seconds
|
||||
// }
|
||||
|
||||
// export class ChartDashboard {
|
||||
// private $panel: JQuery;
|
||||
// private readonly opts: ChartDashboardOptions;
|
||||
// private charts: Chart[] = [];
|
||||
// private timer: number;
|
||||
// private dlg: ChartDialog;
|
||||
|
||||
// constructor(elem: string | Element | JQuery, charts: ChartData[], opts?: ChartDashboardOptions) {
|
||||
// this.opts = $.extend(new ChartDashboardOptions(), opts);
|
||||
// this.$panel = $(elem);
|
||||
// this.dlg = new ChartDialog(this);
|
||||
|
||||
// charts.forEach(opts => this.createGraph(opts));
|
||||
|
||||
// // events
|
||||
// Dispatcher.bind(this.$panel).on("remove-chart", e => {
|
||||
// let name = $(e.target).closest("div.column").data("name");
|
||||
// Modal.confirm(`Are you sure to delete chart: <strong>${name}</strong>?`, "Delete chart", dlg => {
|
||||
// this.removeGraph(name);
|
||||
// dlg.close();
|
||||
// });
|
||||
// });
|
||||
// $(window).resize(e => {
|
||||
// $.each(this.charts, (i: number, g: Chart) => {
|
||||
// g.resize();
|
||||
// });
|
||||
// });
|
||||
|
||||
// this.refresh();
|
||||
// }
|
||||
|
||||
// refresh() {
|
||||
// if (!this.timer) {
|
||||
// this.loadData();
|
||||
// if (this.opts.refreshInterval > 0) {
|
||||
// this.timer = setTimeout(this.refreshData.bind(this), this.opts.refreshInterval * 1000);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private refreshData() {
|
||||
// this.loadData();
|
||||
// if (this.opts.refreshInterval > 0) {
|
||||
// this.timer = setTimeout(this.refreshData.bind(this), this.opts.refreshInterval * 1000);
|
||||
// }
|
||||
// }
|
||||
|
||||
// stop() {
|
||||
// clearTimeout(this.timer);
|
||||
// this.timer = 0;
|
||||
// }
|
||||
|
||||
// setPeriod(period: number) {
|
||||
// this.opts.period = period;
|
||||
// this.loadData();
|
||||
// }
|
||||
|
||||
// addGraph(opts: ChartData) {
|
||||
// this.createGraph(opts);
|
||||
// this.loadData();
|
||||
// }
|
||||
|
||||
// private createGraph(opts: ChartData) {
|
||||
// for (let i = 0; i < this.charts.length; i++) {
|
||||
// let chart = this.charts[i];
|
||||
// if (chart.getOptions().name === opts.name) {
|
||||
// // chart already added.
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// let chart = ChartFactory.create(opts);
|
||||
// if (chart != null) {
|
||||
// this.$panel.append(chart.getElem());
|
||||
// chart.init();
|
||||
// this.charts.push(chart);
|
||||
// }
|
||||
// }
|
||||
|
||||
// removeGraph(name: string) {
|
||||
// let index = -1;
|
||||
// for (let i = 0; i < this.charts.length; i++) {
|
||||
// let c = this.charts[i];
|
||||
// if (c.getOptions().name === name) {
|
||||
// index = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (index >= 0) {
|
||||
// let $elem = this.charts[index].getElem();
|
||||
// this.charts.splice(index, 1);
|
||||
// $elem.remove();
|
||||
// }
|
||||
// }
|
||||
|
||||
// save(asDefault: boolean = false) {
|
||||
// let charts: any = [];
|
||||
// this.$panel.children().each((index: number, elem: Element) => {
|
||||
// let name = $(elem).data("name");
|
||||
// for (let i = 0; i < this.charts.length; i++) {
|
||||
// let c = this.charts[i];
|
||||
// if (c.getOptions().name === name) {
|
||||
// charts.push({
|
||||
// name: c.getOptions().name,
|
||||
// width: c.getOptions().width,
|
||||
// height: c.getOptions().height,
|
||||
// });
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// let args = {
|
||||
// name: this.opts.name,
|
||||
// key: asDefault ? '' : (this.opts.key || ''),
|
||||
// charts: charts,
|
||||
// };
|
||||
// $ajax.post(`/system/chart/save_dashboard`, args).json<AjaxResult>((r: AjaxResult) => {
|
||||
// if (r.success) {
|
||||
// Notification.show("success", "Successfully saved.");
|
||||
// } else {
|
||||
// Notification.show("danger", r.message);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// getOptions(): ChartDashboardOptions {
|
||||
// return this.opts;
|
||||
// }
|
||||
|
||||
// private loadData() {
|
||||
// if (this.charts.length == 0) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// let args: any = {
|
||||
// charts: this.charts.map(c => c.getOptions().name).join(","),
|
||||
// period: this.opts.period,
|
||||
// };
|
||||
// if (this.opts.key) {
|
||||
// args.key = this.opts.key;
|
||||
// }
|
||||
// $ajax.get(`/system/chart/data`, args).json((d: { [index: string]: any[] }) => {
|
||||
// $.each(this.charts, (i: number, g: Chart) => {
|
||||
// if (d[g.getOptions().name]) {
|
||||
// g.setData(d[g.getOptions().name]);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// class ChartDialog {
|
||||
// private dashboard: ChartDashboard;
|
||||
// private fb: FilterBox;
|
||||
// private charts: any;
|
||||
// private $charts: JQuery;
|
||||
|
||||
// constructor(dashboard: ChartDashboard) {
|
||||
// this.dashboard = dashboard;
|
||||
// this.fb = new FilterBox("#txt-query", this.filterCharts.bind(this));
|
||||
// $("#btn-add").click(this.showAddDlg.bind(this));
|
||||
// $("#btn-add-chart").click(this.addChart.bind(this));
|
||||
// $("#btn-save").click(() => {
|
||||
// this.dashboard.save();
|
||||
// });
|
||||
// $("#btn-save-as-default").click(() => {
|
||||
// this.dashboard.save(true);
|
||||
// });
|
||||
// }
|
||||
|
||||
// private showAddDlg() {
|
||||
// let $panel = $("#nav-charts");
|
||||
// $panel.find("label.panel-block").remove();
|
||||
|
||||
// // load charts
|
||||
// $ajax.get(`/system/chart/query`, { dashboard: this.dashboard.getOptions().name }).json((charts: any) => {
|
||||
// for (let i = 0; i < charts.length; i++) {
|
||||
// let c = charts[i];
|
||||
// $panel.append(`<label class="panel-block">
|
||||
// <input type="checkbox" value="${c.name}" data-index="${i}">${c.name}: ${c.title}
|
||||
// </label>`);
|
||||
// }
|
||||
// this.charts = charts;
|
||||
// this.$charts = $panel.find("label.panel-block");
|
||||
// });
|
||||
|
||||
// let dlg = new Modal("#dlg-add-chart");
|
||||
// dlg.show();
|
||||
// }
|
||||
|
||||
// private filterCharts(text: string) {
|
||||
// if (!text) {
|
||||
// this.$charts.show();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this.$charts.each((i, elem) => {
|
||||
// let $elem = $(elem);
|
||||
// let texts: string[] = [
|
||||
// this.charts[i].name.toLowerCase(),
|
||||
// this.charts[i].title.toLowerCase(),
|
||||
// this.charts[i].desc.toLowerCase(),
|
||||
// ];
|
||||
// for (let i = 0; i < texts.length; i++) {
|
||||
// let index = texts[i].indexOf(text);
|
||||
// if (index >= 0) {
|
||||
// $elem.show();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// $elem.hide();
|
||||
// })
|
||||
// }
|
||||
|
||||
// private addChart() {
|
||||
// this.$charts.each((i, e) => {
|
||||
// if ($(e).find(":checked").length > 0) {
|
||||
// let c = this.charts[i];
|
||||
// this.dashboard.addGraph(c);
|
||||
// }
|
||||
// });
|
||||
// Modal.close();
|
||||
// }
|
||||
// }
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="tab-pane" :class="{active: active}" :style="{borderColor: themeVars.primaryColor}">
|
||||
<div class="tab-pane" :class="{ active: active }" :style="{ borderColor: themeVars.primaryColor }">
|
||||
<router-link
|
||||
:to="href"
|
||||
:style="{color: active ? themeVars.primaryColor : themeVars.textColorBase}"
|
||||
:style="{ color: active ? themeVars.primaryColor : themeVars.textColorBase }"
|
||||
>
|
||||
<slot />
|
||||
</router-link>
|
||||
@@ -11,16 +11,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useThemeVars } from "naive-ui";
|
||||
import { RouterLink } from "vue-router";
|
||||
import { RouterLink, RouteLocationRaw } from "vue-router";
|
||||
|
||||
const props = defineProps({
|
||||
active: Boolean,
|
||||
title: String,
|
||||
href: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
interface Props {
|
||||
active?: boolean;
|
||||
title?: string;
|
||||
href: RouteLocationRaw;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const themeVars = useThemeVars();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<x-page-header>
|
||||
<template #action>
|
||||
<n-button secondary size="small" @click="$router.push('/system/charts')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'chart_list' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<back-icon />
|
||||
@@ -219,7 +219,7 @@ const rules: any = {
|
||||
const form = ref();
|
||||
const { submit, submiting } = useForm(form, () => chartApi.save(model.value), () => {
|
||||
window.message.info(t('texts.action_success'));
|
||||
router.push("/system/charts")
|
||||
router.push({ name: 'chart_list' })
|
||||
})
|
||||
|
||||
function newMetric() {
|
||||
|
||||
@@ -9,18 +9,24 @@
|
||||
</template>
|
||||
{{ t('buttons.import') }}
|
||||
</n-button>
|
||||
<n-button secondary size="small" @click="$router.push('/system/charts/new')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'chart_new' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<add-icon />
|
||||
</n-icon>
|
||||
</template>{{ t('buttons.new') }}
|
||||
</template>
|
||||
{{ t('buttons.new') }}
|
||||
</n-button>
|
||||
</template>
|
||||
</x-page-header>
|
||||
<n-space class="page-body" vertical :size="12">
|
||||
<n-space :size="12">
|
||||
<n-input size="small" v-model:value="filter.title" :placeholder="t('fields.title')" clearable />
|
||||
<n-input
|
||||
size="small"
|
||||
v-model:value="filter.title"
|
||||
:placeholder="t('fields.title')"
|
||||
clearable
|
||||
/>
|
||||
<n-select
|
||||
size="small"
|
||||
:placeholder="t('fields.dashboard')"
|
||||
@@ -84,7 +90,7 @@ const columns = [
|
||||
title: t('fields.title'),
|
||||
key: "title",
|
||||
fixed: "left" as const,
|
||||
render: (c: Chart) => renderLink(`/system/charts/${c.id}`, c.title),
|
||||
render: (c: Chart) => renderLink({ name: 'chart_detail', params: { id: c.id } }, c.title),
|
||||
},
|
||||
{
|
||||
title: t('fields.type'),
|
||||
@@ -136,7 +142,7 @@ const columns = [
|
||||
{
|
||||
type: 'warning',
|
||||
text: t('buttons.edit'),
|
||||
action: () => router.push(`/system/charts/${c.id}/edit`),
|
||||
action: () => router.push({ name: 'chart_edit', params: { id: c.id } }),
|
||||
},
|
||||
{
|
||||
type: 'info',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<x-page-header :subtitle="model.title">
|
||||
<template #action>
|
||||
<n-button secondary size="small" @click="$router.push('/system/charts')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'chart_list' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<back-icon />
|
||||
@@ -12,7 +12,7 @@
|
||||
<n-button
|
||||
secondary
|
||||
size="small"
|
||||
@click="$router.push(`/system/charts/${model.id}/edit`)"
|
||||
@click="$router.push({ name: 'chart_edit', params: { id: model.id } })"
|
||||
>{{ t('buttons.edit') }}</n-button>
|
||||
</template>
|
||||
</x-page-header>
|
||||
@@ -55,13 +55,19 @@
|
||||
<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_by')">
|
||||
<x-anchor :url="`/system/users/${model.createdBy?.id}`">{{ model.createdBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.createdBy?.id } }"
|
||||
v-if="model.createdBy?.id"
|
||||
>{{ model.createdBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_at')">
|
||||
<n-time :time="model.createdAt" format="y-MM-dd HH:mm:ss" />
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_by')">
|
||||
<x-anchor :url="`/system/users/${model.updatedBy?.id}`">{{ model.updatedBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.updatedBy?.id } }"
|
||||
v-if="model.updatedBy?.id"
|
||||
>{{ model.updatedBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_at')">
|
||||
<n-time :time="model.updatedAt" format="y-MM-dd HH:mm:ss" />
|
||||
|
||||
@@ -153,7 +153,6 @@ const columns = [
|
||||
key: "id",
|
||||
width: 210,
|
||||
fixed: "left" as const,
|
||||
// render: (e: Event) => renderLink(`/system/events/${e.id}`, e.id),
|
||||
},
|
||||
{
|
||||
title: t('fields.type'),
|
||||
@@ -172,15 +171,12 @@ const columns = [
|
||||
{
|
||||
title: t('fields.object'),
|
||||
key: "name",
|
||||
render(e: Event) {
|
||||
const u = url(e)
|
||||
return u ? renderLink(u, e.name) : e.name
|
||||
},
|
||||
render: renderObject,
|
||||
},
|
||||
{
|
||||
title: t('fields.operator'),
|
||||
key: "name",
|
||||
render: (e: Event) => renderLink(`/system/users/${e.userId}`, e.username),
|
||||
render: (e: Event) => e.userId ? renderLink({ name: 'user_detail', params: { id: e.userId } }, e.username) : null,
|
||||
},
|
||||
{
|
||||
title: t('fields.time'),
|
||||
@@ -190,40 +186,40 @@ const columns = [
|
||||
];
|
||||
const { state, pagination, fetchData, changePageSize } = useDataTable(eventApi.search, filter)
|
||||
|
||||
function url(e: Event): RouteLocationRaw | null {
|
||||
if (e.type === 'Setting') {
|
||||
return { name: 'setting' }
|
||||
} else if (!e.code) {
|
||||
return null
|
||||
}
|
||||
|
||||
function renderObject(e: Event) {
|
||||
switch (e.type) {
|
||||
case "User":
|
||||
return { name: 'user_detail', params: { id: e.code } }
|
||||
case "Role":
|
||||
return { name: 'role_detail', params: { id: e.code } }
|
||||
case "Chart":
|
||||
return { name: 'chart_detail', params: { id: e.code } }
|
||||
case "Registry":
|
||||
return { name: 'registry_detail', params: { id: e.code } }
|
||||
case "Node":
|
||||
return { name: 'node_detail', params: { id: e.code } }
|
||||
case "Network":
|
||||
return { name: 'network_detail', params: { name: e.code } }
|
||||
case "Service":
|
||||
return { name: 'service_detail', params: { name: e.code } }
|
||||
case "Stack":
|
||||
return { name: 'stack_detail', params: { name: e.code } }
|
||||
case "Config":
|
||||
return { name: 'config_detail', params: { id: e.code } }
|
||||
case "Secret":
|
||||
return { name: 'secret_detail', params: { id: e.code } }
|
||||
return renderLink({ name: e.type.toLowerCase() + '_detail', params: { id: e.args.id } }, e.args.name)
|
||||
case "Network":
|
||||
case "Service":
|
||||
case "Stack":
|
||||
return renderLink({ name: e.type.toLowerCase() + '_detail', params: { name: e.args.name } }, e.args.name)
|
||||
case "Image":
|
||||
return { name: 'image_detail', params: { node: '-', id: e.code } }
|
||||
if (e.args.id) {
|
||||
return renderLink({ name: 'image_detail', params: { node: e.args.node || '-', id: e.args.id } }, e.args.id)
|
||||
} else {
|
||||
return renderLink({ name: 'image_list' }, t('objects.image'))
|
||||
}
|
||||
case "Container":
|
||||
return { name: 'container_detail', params: { node: '-', id: e.code } }
|
||||
if (e.args.id) {
|
||||
return renderLink({ name: 'container_detail', params: { node: e.args.node || '-', id: e.args.id } }, e.args.name)
|
||||
} else {
|
||||
return renderLink({ name: 'container_list' }, t('objects.container'))
|
||||
}
|
||||
case "Volume":
|
||||
return { name: 'volume_detail', params: { node: '-', name: e.code } }
|
||||
if (e.args.name) {
|
||||
return renderLink({ name: 'volume_detail', params: { node: e.args.node || '-', name: e.args.name } }, e.args.name)
|
||||
} else {
|
||||
return renderLink({ name: 'volume_list' }, t('objects.volume'))
|
||||
}
|
||||
case "Setting":
|
||||
return renderLink({ name: 'setting' }, t('objects.setting'))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -23,13 +23,19 @@
|
||||
<x-description-item :label="t('fields.url')">{{ model.url }}</x-description-item>
|
||||
<x-description-item :label="t('fields.login_name')">{{ model.username }}</x-description-item>
|
||||
<x-description-item :label="t('fields.created_by')">
|
||||
<x-anchor :url="`/system/users/${model.createdBy?.id}`">{{ model.createdBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.createdBy?.id } }"
|
||||
v-if="model.createdBy?.id"
|
||||
>{{ model.createdBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_at')">
|
||||
<n-time :time="model.createdAt" format="y-MM-dd HH:mm:ss" />
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_by')">
|
||||
<x-anchor :url="`/system/users/${model.updatedBy?.id}`">{{ model.updatedBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.updatedBy?.id } }"
|
||||
v-if="model.updatedBy?.id"
|
||||
>{{ model.updatedBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_at')">
|
||||
<n-time :time="model.updatedAt" format="y-MM-dd HH:mm:ss" />
|
||||
|
||||
@@ -111,7 +111,7 @@ const rules: any = {
|
||||
const form = ref();
|
||||
const { submit, submiting } = useForm(form, () => roleApi.save(model.value), () => {
|
||||
window.message.info(t('texts.action_success'));
|
||||
router.push("/system/roles")
|
||||
router.push({ name: 'role_list' })
|
||||
})
|
||||
|
||||
function checkGroup(key: string, checked: boolean = true) {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<tbody>
|
||||
<tr v-for="(r, index) of model.roles" :key="r.id">
|
||||
<td>
|
||||
<x-anchor :url="`/system/roles/${r.id}`">{{ r.id }}</x-anchor>
|
||||
<x-anchor :url="{ name: 'role_detail', params: { id: r.id } }">{{ r.id }}</x-anchor>
|
||||
</td>
|
||||
<td>{{ r.name }}</td>
|
||||
<td>{{ r.desc }}</td>
|
||||
|
||||
@@ -22,24 +22,30 @@
|
||||
<x-description-item :label="t('fields.name')">{{ model.name }}</x-description-item>
|
||||
<x-description-item :span="2" :label="t('fields.desc')">{{ model.desc }}</x-description-item>
|
||||
<x-description-item :label="t('fields.created_by')">
|
||||
<x-anchor :url="`/system/users/${model.createdBy?.id}`">{{ model.createdBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.createdBy?.id } }"
|
||||
v-if="model.createdBy?.id"
|
||||
>{{ model.createdBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_at')">
|
||||
<n-time :time="model.createdAt" format="y-MM-dd HH:mm:ss" />
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_by')">
|
||||
<x-anchor :url="`/system/users/${model.updatedBy?.id}`">{{ model.updatedBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.updatedBy?.id } }"
|
||||
v-if="model.updatedBy?.id"
|
||||
>{{ model.updatedBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_at')">
|
||||
<n-time :time="model.updatedAt" format="y-MM-dd HH:mm:ss" />
|
||||
</x-description-item>
|
||||
</x-description>
|
||||
<x-panel :title="t('fields.perms')">
|
||||
<n-grid cols="1 640:2 960:3 1440:4" x-gap="6" y-gap="6">
|
||||
<n-gi span="1" v-for="g in ps">
|
||||
<x-pair-tag type="warning" :label="g.group" :value="g.items" />
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid cols="1 640:2 960:3 1440:4" x-gap="6" y-gap="6">
|
||||
<n-gi span="1" v-for="g in ps">
|
||||
<x-pair-tag type="warning" :label="g.group" :value="g.items" />
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</x-panel>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<n-dynamic-input v-model:value="model.labels" #="{ index, value }" :on-create="newLabel">
|
||||
<n-input :placeholder="t('fields.name')" v-model:value="value.name" />
|
||||
<div style="height: 34px; line-height: 34px; margin: 0 8px">=</div>
|
||||
<n-input :placeholder="t('fields.name')" v-model:value="value.value" />
|
||||
<n-input :placeholder="t('fields.value')" v-model:value="value.value" />
|
||||
</n-dynamic-input>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
|
||||
@@ -21,13 +21,19 @@
|
||||
<x-description :label-width="90">
|
||||
<x-description-item :label="t('fields.name')" :span="2">{{ model.name }}</x-description-item>
|
||||
<x-description-item :label="t('fields.created_by')">
|
||||
<x-anchor :url="`/system/users/${model.createdBy?.id}`">{{ model.createdBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.createdBy?.id } }"
|
||||
v-if="model.createdBy?.id"
|
||||
>{{ model.createdBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_at')">
|
||||
<n-time :time="model.createdAt" format="y-MM-dd HH:mm:ss" />
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_by')">
|
||||
<x-anchor :url="`/system/users/${model.updatedBy?.id}`">{{ model.updatedBy?.name }}</x-anchor>
|
||||
<x-anchor
|
||||
:url="{ name: 'user_detail', params: { id: model.updatedBy?.id } }"
|
||||
v-if="model.updatedBy?.id"
|
||||
>{{ model.updatedBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_at')">
|
||||
<n-time :time="model.updatedAt" format="y-MM-dd HH:mm:ss" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<x-page-header :subtitle="user.id">
|
||||
<template #action>
|
||||
<n-button secondary size="small" @click="$router.push('/system/users')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'user_list' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<back-icon />
|
||||
@@ -18,16 +18,28 @@
|
||||
<n-input :placeholder="t('fields.username')" v-model:value="user.name" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('fields.login_name')" path="loginName">
|
||||
<n-input :placeholder="t('fields.login_name')" v-model:value="user.loginName" />
|
||||
<n-input :placeholder="t('fields.login_name')" v-model:value="user.loginName" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('fields.password')" path="password" v-if="!user.id">
|
||||
<n-input type="password" :placeholder="t('fields.password')" v-model:value="user.password" />
|
||||
<n-input
|
||||
type="password"
|
||||
:placeholder="t('fields.password')"
|
||||
v-model:value="user.password"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('fields.password_confirm')" path="passwordConfirm" v-if="!user.id">
|
||||
<n-input type="password" :placeholder="t('fields.password_confirm')" v-model:value="user.passwordConfirm" />
|
||||
<n-form-item-gi
|
||||
:label="t('fields.password_confirm')"
|
||||
path="passwordConfirm"
|
||||
v-if="!user.id"
|
||||
>
|
||||
<n-input
|
||||
type="password"
|
||||
:placeholder="t('fields.password_confirm')"
|
||||
v-model:value="user.passwordConfirm"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('fields.email')" path="email">
|
||||
<n-input :placeholder="t('fields.email')" v-model:value="user.email" />
|
||||
<n-input :placeholder="t('fields.email')" v-model:value="user.email" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('fields.admin')" path="admin">
|
||||
<n-switch v-model:value="user.admin">
|
||||
@@ -47,7 +59,12 @@
|
||||
<n-radio key="ldap" value="ldap">LDAP</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :label="t('objects.role', 2)" span="2" path="roles" v-if="roles && roles.length">
|
||||
<n-form-item-gi
|
||||
:label="t('objects.role', 2)"
|
||||
span="2"
|
||||
path="roles"
|
||||
v-if="roles && roles.length"
|
||||
>
|
||||
<n-checkbox-group v-model:value="user.roles">
|
||||
<n-space item-style="display: flex;">
|
||||
<n-checkbox :value="r.id" :label="r.name" v-for="r of roles" />
|
||||
@@ -119,7 +136,7 @@ const rules: any = {
|
||||
const form = ref();
|
||||
const { submit, submiting } = useForm(form, () => userApi.save(user.value), () => {
|
||||
window.message.info(t('texts.action_success'));
|
||||
router.push("/system/users")
|
||||
router.push({ name: 'user_list' })
|
||||
})
|
||||
|
||||
async function fetchData() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<x-page-header>
|
||||
<template #action>
|
||||
<n-button secondary size="small" @click="$router.push('/system/users/new')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'user_new' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<add-icon />
|
||||
@@ -13,19 +13,12 @@
|
||||
</x-page-header>
|
||||
<n-space class="page-body" vertical :size="12">
|
||||
<x-tab>
|
||||
<x-tab-pane href="/system/users" :active="!$route.query.filter">{{ t('fields.all') }}</x-tab-pane>
|
||||
<x-tab-pane :href="{ name: 'user_list' }" :active="!$route.query.filter">{{ t('fields.all') }}</x-tab-pane>
|
||||
<x-tab-pane
|
||||
href="/system/users?filter=admins"
|
||||
:active="$route.query.filter === 'admins'"
|
||||
>{{ t('fields.admins') }}</x-tab-pane>
|
||||
<x-tab-pane
|
||||
href="/system/users?filter=active"
|
||||
:active="$route.query.filter === 'active'"
|
||||
>{{ t('fields.active') }}</x-tab-pane>
|
||||
<x-tab-pane
|
||||
href="/system/users?filter=blocked"
|
||||
:active="$route.query.filter === 'blocked'"
|
||||
>{{ t('fields.blocked') }}</x-tab-pane>
|
||||
:href="{ name: 'user_list', query: { filter: tab } }"
|
||||
:active="$route.query.filter === tab"
|
||||
v-for="tab in ['admins', 'active', 'blocked']"
|
||||
>{{ t('fields.' + tab) }}</x-tab-pane>
|
||||
</x-tab>
|
||||
<n-space :size="12">
|
||||
<n-input size="small" v-model:value="args.name" :placeholder="t('fields.name')" clearable />
|
||||
@@ -84,7 +77,7 @@ const columns = [
|
||||
{
|
||||
title: t('fields.id'),
|
||||
key: "id",
|
||||
render: (row: User) => renderLink(`/system/users/${row.id}`, row.id),
|
||||
render: (row: User) => renderLink({ name: 'user_detail', params: { id: row.id } }, row.id),
|
||||
},
|
||||
{
|
||||
title: t('fields.name'),
|
||||
@@ -124,7 +117,7 @@ const columns = [
|
||||
row.status ?
|
||||
{ type: 'warning', text: t('buttons.block'), action: () => setStatus(row, 0), prompt: t('prompts.block'), } :
|
||||
{ type: 'success', text: t('buttons.enable'), action: () => setStatus(row, 1) },
|
||||
{ type: 'warning', text: t('buttons.edit'), action: () => router.push(`/system/users/${row.id}/edit`) },
|
||||
{ type: 'warning', text: t('buttons.edit'), action: () => router.push({ name: 'user_edit', params: { id: row.id } }) },
|
||||
{ type: 'error', text: t('buttons.delete'), action: () => remove(row, index), prompt: t('prompts.delete') },
|
||||
])
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<x-page-header :subtitle="model.user.name">
|
||||
<template #action>
|
||||
<n-button secondary size="small" @click="$router.push('/system/users')">
|
||||
<n-button secondary size="small" @click="$router.push({ name: 'user_list' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<back-icon />
|
||||
@@ -12,7 +12,7 @@
|
||||
<n-button
|
||||
secondary
|
||||
size="small"
|
||||
@click="$router.push(`/system/users/${model.user.id}/edit`)"
|
||||
@click="$router.push({ name: 'user_edit', params: { id: model.user.id } })"
|
||||
>{{ t('buttons.edit') }}</n-button>
|
||||
</template>
|
||||
</x-page-header>
|
||||
@@ -45,7 +45,8 @@
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_by')">
|
||||
<x-anchor
|
||||
:url="`/system/users/${model.user.createdBy?.id}`"
|
||||
:url="{ name: 'user_detail', params: { id: model.user.createdBy?.id } }"
|
||||
v-if="model.user.createdBy?.id"
|
||||
>{{ model.user.createdBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.created_at')">
|
||||
@@ -53,7 +54,8 @@
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_by')">
|
||||
<x-anchor
|
||||
:url="`/system/users/${model.user.updatedBy?.id}`"
|
||||
:url="{ name: 'user_detail', params: { id: model.user.updatedBy?.id } }"
|
||||
v-if="model.user.updatedBy?.id"
|
||||
>{{ model.user.updatedBy?.name }}</x-anchor>
|
||||
</x-description-item>
|
||||
<x-description-item :label="t('fields.updated_at')">
|
||||
|
||||
Reference in New Issue
Block a user