mirror of
https://github.com/rustfs/console.git
synced 2026-09-19 01:47:44 +08:00
feat : 事件目标UI
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header>
|
||||
<template #title>
|
||||
<h1 class="text-2xl font-bold">{{ t("Event Destinations") }}</h1>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-content class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<n-input v-model:value="searchTerm" :placeholder="t('Search')">
|
||||
<template #prefix>
|
||||
<Icon name="ri:search-2-line" />
|
||||
</template>
|
||||
</n-input>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<n-button @click="() => addForm()">
|
||||
<Icon name="ri:add-line" class="mr-2" />
|
||||
<span>{{ t("Add Event Destination") }}</span>
|
||||
</n-button>
|
||||
<n-button @click="async () => refresh()">
|
||||
<Icon name="ri:refresh-line" class="mr-2" />
|
||||
<span>{{ t("Refresh") }}</span>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<n-data-table
|
||||
class="border dark:border-neutral-700 rounded overflow-hidden"
|
||||
:columns="columns"
|
||||
:data="filteredData"
|
||||
:pagination="false"
|
||||
:bordered="false" />
|
||||
</page-content>
|
||||
<events-target-new ref="newFormRef"></events-target-new>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Icon } from "#components";
|
||||
import { NButton, NSpace, type DataTableColumns, NPopconfirm } from "naive-ui";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const message = useMessage();
|
||||
|
||||
const { t } = useI18n();
|
||||
const searchTerm = ref("");
|
||||
|
||||
interface RowData {
|
||||
type: string;
|
||||
}
|
||||
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
title: t("Status"),
|
||||
key: "bucket",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: t("Service"),
|
||||
key: "endpoint",
|
||||
},
|
||||
|
||||
{
|
||||
title: t("Actions"),
|
||||
key: "actions",
|
||||
align: "center",
|
||||
width: 140,
|
||||
render: (row: RowData) => {
|
||||
return h(
|
||||
NSpace,
|
||||
{
|
||||
justify: "center",
|
||||
},
|
||||
{
|
||||
default: () => [
|
||||
h(
|
||||
NPopconfirm,
|
||||
{ onPositiveClick: () => deleteItem(row) },
|
||||
{
|
||||
default: () => t("Confirm Delete"),
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{ size: "small", secondary: true },
|
||||
{
|
||||
default: () => "",
|
||||
icon: () => h(Icon, { name: "ri:delete-bin-5-line" }),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
],
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const { data, refresh } = await useAsyncData(
|
||||
"tier",
|
||||
async () => {
|
||||
// const response = await usetier.listTiers();
|
||||
// return response;
|
||||
return [];
|
||||
},
|
||||
{ default: () => [] }
|
||||
);
|
||||
|
||||
const filteredData = computed(() => {
|
||||
if (!searchTerm.value) {
|
||||
return data.value;
|
||||
}
|
||||
|
||||
const term = searchTerm.value.toLowerCase();
|
||||
return data.value.filter(
|
||||
(tier: any) =>
|
||||
tier.name.toLowerCase().includes(term) ||
|
||||
tier.endpoint.toLowerCase().includes(term) ||
|
||||
tier.bucket.toLowerCase().includes(term)
|
||||
);
|
||||
});
|
||||
|
||||
const deleteItem = async (row: RowData) => {
|
||||
// usetier
|
||||
// .removeTiers(config.name)
|
||||
// .then(() => {
|
||||
// message.success(t("Delete Success"));
|
||||
// refresh();
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// message.error(t("Delete Failed"));
|
||||
// });
|
||||
};
|
||||
|
||||
const newFormRef = ref();
|
||||
const addForm = async () => {
|
||||
newFormRef.value.open();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
+77
-67
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<page-header>
|
||||
<template #title>
|
||||
<h1 class="text-2xl font-bold">{{ t('Tiers') }}</h1>
|
||||
<h1 class="text-2xl font-bold">{{ t("Tiers") }}</h1>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-content class="flex flex-col gap-4">
|
||||
@@ -18,30 +18,38 @@
|
||||
<div class="flex items-center gap-4">
|
||||
<n-button @click="() => addForm()">
|
||||
<Icon name="ri:add-line" class="mr-2" />
|
||||
<span>{{ t('Add Tier') }}</span>
|
||||
<span>{{ t("Add Tier") }}</span>
|
||||
</n-button>
|
||||
<n-button @click="async () => refresh()">
|
||||
<Icon name="ri:refresh-line" class="mr-2" />
|
||||
<span>{{ t('Refresh') }}</span>
|
||||
<span>{{ t("Refresh") }}</span>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<n-data-table class="border dark:border-neutral-700 rounded overflow-hidden" :columns="columns" :data="filteredData" :pagination="false" :bordered="false" />
|
||||
<tiers-new-form ref='newFormRef' @search="refresh"></tiers-new-form>
|
||||
<tiers-change-key v-model:visible="changeKeyVisible" v-model:name="editName" ref='infoRef' @search="refresh"></tiers-change-key>
|
||||
<n-data-table
|
||||
class="border dark:border-neutral-700 rounded overflow-hidden"
|
||||
:columns="columns"
|
||||
:data="filteredData"
|
||||
:pagination="false"
|
||||
:bordered="false" />
|
||||
<tiers-new-form ref="newFormRef" @search="refresh"></tiers-new-form>
|
||||
<tiers-change-key
|
||||
v-model:visible="changeKeyVisible"
|
||||
v-model:name="editName"
|
||||
ref="infoRef"
|
||||
@search="refresh"></tiers-change-key>
|
||||
</page-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Icon } from '#components'
|
||||
import dayjs from 'dayjs'
|
||||
import { NButton, NSpace, type DataTableColumns ,NPopconfirm} from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const usetier = useTiers()
|
||||
import { Icon } from "#components";
|
||||
import { NButton, NSpace, type DataTableColumns, NPopconfirm } from "naive-ui";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const usetier = useTiers();
|
||||
|
||||
const { t } = useI18n()
|
||||
const searchTerm = ref('');
|
||||
const { t } = useI18n();
|
||||
const searchTerm = ref("");
|
||||
|
||||
interface S3Config {
|
||||
name: string;
|
||||
@@ -59,84 +67,84 @@ interface S3Config {
|
||||
|
||||
interface RowData {
|
||||
type: string;
|
||||
rustfs?: S3Config;
|
||||
minio?: S3Config;
|
||||
rustfs?: S3Config;
|
||||
minio?: S3Config;
|
||||
s3?: S3Config;
|
||||
}
|
||||
|
||||
const getConfig = (row: RowData): S3Config | undefined =>{
|
||||
const getConfig = (row: RowData): S3Config | undefined => {
|
||||
switch (row.type) {
|
||||
case 'rustfs':
|
||||
case "rustfs":
|
||||
return row.rustfs;
|
||||
case 'minio':
|
||||
case "minio":
|
||||
return row.minio;
|
||||
case 's3':
|
||||
case "s3":
|
||||
return row.s3;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const columns: DataTableColumns<RowData> = [
|
||||
{
|
||||
title: t('Tier Type'),
|
||||
key: 'type',
|
||||
title: t("Tier Type"),
|
||||
key: "type",
|
||||
render: (row) => row.type,
|
||||
},
|
||||
{
|
||||
title: t('Name'),
|
||||
key: 'name',
|
||||
title: t("Name"),
|
||||
key: "name",
|
||||
render: (row) => getConfig(row)?.name,
|
||||
},
|
||||
{
|
||||
title: t('Endpoint'),
|
||||
key: 'endpoint',
|
||||
title: t("Endpoint"),
|
||||
key: "endpoint",
|
||||
render: (row) => getConfig(row)?.endpoint,
|
||||
},
|
||||
{
|
||||
title: t('Bucket'),
|
||||
key: 'bucket',
|
||||
title: t("Bucket"),
|
||||
key: "bucket",
|
||||
render: (row) => getConfig(row)?.bucket,
|
||||
},
|
||||
{
|
||||
title: t('Region'),
|
||||
key: 'region',
|
||||
{
|
||||
title: t("Region"),
|
||||
key: "region",
|
||||
render: (row) => getConfig(row)?.region,
|
||||
},
|
||||
{
|
||||
title: t('Storage Class'),
|
||||
key: 'storageclass',
|
||||
title: t("Storage Class"),
|
||||
key: "storageclass",
|
||||
render: (row) => {
|
||||
// 只有 s3 类型才有 storageclass
|
||||
if (row.type === 's3') {
|
||||
if (row.type === "s3") {
|
||||
return row.s3?.storageclass;
|
||||
}
|
||||
return '-';
|
||||
return "-";
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Usage'),
|
||||
key: 'usage',
|
||||
title: t("Usage"),
|
||||
key: "usage",
|
||||
render: (row) => getConfig(row)?.usage,
|
||||
},
|
||||
{
|
||||
title: t('Objects'),
|
||||
key: 'objects',
|
||||
title: t("Objects"),
|
||||
key: "objects",
|
||||
render: (row) => getConfig(row)?.objects,
|
||||
},
|
||||
{
|
||||
title: t('Version'),
|
||||
key: 'versions',
|
||||
title: t("Version"),
|
||||
key: "versions",
|
||||
render: (row) => getConfig(row)?.versions,
|
||||
},
|
||||
{
|
||||
title: t('Actions'),
|
||||
key: 'actions',
|
||||
align: 'center',
|
||||
title: t("Actions"),
|
||||
key: "actions",
|
||||
align: "center",
|
||||
width: 140,
|
||||
render: (row: RowData) => {
|
||||
return h(
|
||||
NSpace,
|
||||
{
|
||||
justify: 'center',
|
||||
justify: "center",
|
||||
},
|
||||
{
|
||||
default: () => [
|
||||
@@ -144,7 +152,7 @@ const columns: DataTableColumns<RowData> = [
|
||||
NPopconfirm,
|
||||
{ onPositiveClick: () => deleteItem(row) },
|
||||
{
|
||||
default: () => t('Confirm Delete'),
|
||||
default: () => t("Confirm Delete"),
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
@@ -159,16 +167,15 @@ const columns: DataTableColumns<RowData> = [
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
size: "small",
|
||||
secondary: true,
|
||||
onClick: (e) => handleRowClick(row,e),
|
||||
onClick: (e) => handleRowClick(row, e),
|
||||
},
|
||||
{
|
||||
default: () => '',
|
||||
icon: () => h(Icon, { name: 'ri:edit-2-line' }),
|
||||
default: () => "",
|
||||
icon: () => h(Icon, { name: "ri:edit-2-line" }),
|
||||
}
|
||||
),
|
||||
|
||||
],
|
||||
}
|
||||
);
|
||||
@@ -177,10 +184,10 @@ const columns: DataTableColumns<RowData> = [
|
||||
];
|
||||
|
||||
const { data, refresh } = await useAsyncData(
|
||||
'tier',
|
||||
"tier",
|
||||
async () => {
|
||||
const response = await usetier.listTiers();
|
||||
return response
|
||||
return response;
|
||||
},
|
||||
{ default: () => [] }
|
||||
);
|
||||
@@ -191,17 +198,18 @@ const filteredData = computed(() => {
|
||||
}
|
||||
|
||||
const term = searchTerm.value.toLowerCase();
|
||||
return data.value.filter((tier:any) =>
|
||||
tier.name.toLowerCase().includes(term) ||
|
||||
tier.endpoint.toLowerCase().includes(term) ||
|
||||
tier.bucket.toLowerCase().includes(term)
|
||||
return data.value.filter(
|
||||
(tier: any) =>
|
||||
tier.name.toLowerCase().includes(term) ||
|
||||
tier.endpoint.toLowerCase().includes(term) ||
|
||||
tier.bucket.toLowerCase().includes(term)
|
||||
);
|
||||
});
|
||||
|
||||
const infoRef = ref();
|
||||
const changeKeyVisible = ref(false);
|
||||
const editName = ref();
|
||||
const handleRowClick = (row: RowData,e: Event) => {
|
||||
const handleRowClick = (row: RowData, e: Event) => {
|
||||
e.stopPropagation();
|
||||
changeKeyVisible.value = true;
|
||||
editName.value = getConfig(row)?.name;
|
||||
@@ -209,19 +217,21 @@ const handleRowClick = (row: RowData,e: Event) => {
|
||||
|
||||
const message = useMessage();
|
||||
const deleteItem = async (row: RowData) => {
|
||||
const config = getConfig(row) || {name:''};
|
||||
if(!config.name ) return;
|
||||
usetier.removeTiers(config.name ).then(()=>{
|
||||
message.success(t('Delete Success'))
|
||||
refresh();
|
||||
}).catch((error)=>{
|
||||
message.error(t('Delete Failed'))
|
||||
})
|
||||
const config = getConfig(row) || { name: "" };
|
||||
if (!config.name) return;
|
||||
usetier
|
||||
.removeTiers(config.name)
|
||||
.then(() => {
|
||||
message.success(t("Delete Success"));
|
||||
refresh();
|
||||
})
|
||||
.catch((error) => {
|
||||
message.error(t("Delete Failed"));
|
||||
});
|
||||
};
|
||||
|
||||
const newFormRef = ref();
|
||||
const addForm = async () => {
|
||||
newFormRef.value.open();
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user