feat: add support for displaying enabled plugins on actuator page (#4897)

pull/4878/head^2
Ryan Wang 2023-11-27 21:33:31 +08:00 committed by GitHub
parent 03a9fc5080
commit 3306b1f881
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 212 additions and 71 deletions

View File

@ -9,49 +9,80 @@ import {
Toast, Toast,
VDescription, VDescription,
VDescriptionItem, VDescriptionItem,
VTag,
VLoading,
} from "@halo-dev/components"; } from "@halo-dev/components";
import { computed, onMounted, ref } from "vue"; import { computed } from "vue";
import type { Info, GlobalInfo, Startup } from "@/types"; import type { Info, GlobalInfo, Startup } from "@/types";
import axios from "axios"; import axios from "axios";
import { formatDatetime } from "@/utils/date"; import { formatDatetime } from "@/utils/date";
import { useClipboard } from "@vueuse/core"; import { useClipboard } from "@vueuse/core";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useThemeStore } from "@console/stores/theme";
import type { Plugin } from "@halo-dev/api-client";
import { apiClient } from "@/utils/api-client";
import { useQuery } from "@tanstack/vue-query";
import { usePermission } from "@/utils/permission";
const { t } = useI18n(); const { t } = useI18n();
const themeStore = useThemeStore();
const { currentUserHasPermission } = usePermission();
const info = ref<Info>(); const { data: info } = useQuery<Info>({
const globalInfo = ref<GlobalInfo>(); queryKey: ["system-info"],
const startup = ref<Startup>(); queryFn: async () => {
const { data } = await axios.get<Info>(
`${import.meta.env.VITE_API_URL}/actuator/info`,
{
withCredentials: true,
}
);
return data;
},
retry: 0,
});
const handleFetchActuatorInfo = async () => { const { data: globalInfo } = useQuery<GlobalInfo>({
const { data } = await axios.get( queryKey: ["system-global-info"],
`${import.meta.env.VITE_API_URL}/actuator/info`, queryFn: async () => {
{ const { data } = await axios.get<GlobalInfo>(
withCredentials: true, `${import.meta.env.VITE_API_URL}/actuator/globalinfo`,
} {
); withCredentials: true,
info.value = data; }
}; );
return data;
},
retry: 0,
});
const handleFetchActuatorGlobalInfo = async () => { const { data: startup } = useQuery<Startup>({
const { data } = await axios.get( queryKey: ["system-startup-info"],
`${import.meta.env.VITE_API_URL}/actuator/globalinfo`, queryFn: async () => {
{ const { data } = await axios.get<Startup>(
withCredentials: true, `${import.meta.env.VITE_API_URL}/actuator/startup`,
} {
); withCredentials: true,
globalInfo.value = data; }
}; );
return data;
},
retry: 0,
});
const handleFetchActuatorStartup = async () => { const { data: plugins, isLoading: isPluginsLoading } = useQuery<Plugin[]>({
const { data } = await axios.get( queryKey: ["enabled-plugins"],
`${import.meta.env.VITE_API_URL}/actuator/startup`, queryFn: async () => {
{ const { data } = await apiClient.plugin.listPlugins({
withCredentials: true, page: 0,
} size: 0,
); enabled: true,
startup.value = data; });
};
return data.items;
},
enabled: computed(() => currentUserHasPermission(["system:plugins:view"])),
});
const isExternalUrlValid = computed(() => { const isExternalUrlValid = computed(() => {
if (!globalInfo.value?.useAbsolutePermalink) { if (!globalInfo.value?.useAbsolutePermalink) {
@ -67,43 +98,101 @@ const isExternalUrlValid = computed(() => {
return url.host === currentHost && url.protocol === currentProtocol; return url.host === currentHost && url.protocol === currentProtocol;
}); });
onMounted(() => {
handleFetchActuatorInfo();
handleFetchActuatorGlobalInfo();
handleFetchActuatorStartup();
});
// copy system information to clipboard // copy system information to clipboard
const { copy, isSupported } = useClipboard({ legacy: true }); const { copy, isSupported } = useClipboard({ legacy: true });
interface CopyItem {
label: string;
value?: string;
href?: string;
children?: CopyItem[];
}
const handleCopy = () => { const handleCopy = () => {
if (!isSupported.value) { if (!isSupported.value) {
Toast.warning(t("core.actuator.actions.copy.toast_browser_not_supported")); Toast.warning(t("core.actuator.actions.copy.toast_browser_not_supported"));
return; return;
} }
const text = ` const copyItems: CopyItem[] = [
- ${t("core.actuator.copy_results.external_url", { {
external_url: globalInfo.value?.externalUrl, label: t("core.actuator.fields.external_url"),
})} value: globalInfo.value?.externalUrl || "",
- ${t("core.actuator.copy_results.start_time", { },
start_time: formatDatetime(startup.value?.timeline.startTime), {
})} label: t("core.actuator.fields.start_time"),
- ${t("core.actuator.fields.version", { version: info.value?.build?.version })} value: formatDatetime(startup.value?.timeline.startTime) || "",
- ${t("core.actuator.copy_results.build_time", { },
build_time: formatDatetime(info.value?.build?.time), {
})} label: t("core.actuator.fields.version"),
- Git Commit${info.value?.git?.commit.id} value: info.value?.build?.version || "",
- Java${info.value?.java.runtime.name} / ${info.value?.java.runtime.version} },
- ${t("core.actuator.copy_results.database", { {
database: [info.value?.database.name, info.value?.database.version].join( label: t("core.actuator.fields.build_time"),
" / " value: formatDatetime(info.value?.build?.time) || "",
), },
})} {
- ${t("core.actuator.copy_results.os", { label: "Git Commit",
os: [info.value?.os.name, info.value?.os.version].join(" / "), value: info.value?.git?.commit.id || "",
})} },
`; {
label: "Java",
value:
[info.value?.java.runtime.name, info.value?.java.runtime.version]
.filter(Boolean)
.join(" / ")
.trim() || "",
},
{
label: t("core.actuator.fields.database"),
value:
[info.value?.database.name, info.value?.database.version]
.filter(Boolean)
.join(" / ") || "",
},
{
label: t("core.actuator.fields.os"),
value:
[info.value?.os.name, info.value?.os.version]
.filter(Boolean)
.join(" / ") || "",
},
{
label: t("core.actuator.fields.activated_theme"),
value: themeStore.activatedTheme?.spec.displayName || "",
href:
themeStore.activatedTheme?.spec.repo ||
themeStore.activatedTheme?.spec.homepage,
},
{
label: t("core.actuator.fields.enabled_plugins"),
children: plugins.value?.map((plugin) => ({
value: plugin.spec.displayName,
href: plugin.spec.repo || plugin.spec.homepage,
})) as CopyItem[],
},
];
const text = copyItems
.map((item) => {
if (item.children?.length) {
const childrenText = item.children
.map(
(child) =>
` - ${
child.href ? `[${child.value}](${child.href})` : child.value
}`
)
.filter(Boolean)
.join("\n");
return `- ${item.label}:\n${childrenText}`;
} else {
return `- ${item.label}: ${
item.href ? `[${item.value}](${item.href})` : item.value || ""
}`;
}
})
.join("\n");
copy(text); copy(text);
@ -182,17 +271,55 @@ const handleDownloadLogfile = () => {
</VAlert> </VAlert>
</VDescriptionItem> </VDescriptionItem>
<VDescriptionItem <VDescriptionItem
v-if="startup?.timeline.startTime"
:label="$t('core.actuator.fields.start_time')" :label="$t('core.actuator.fields.start_time')"
:content="formatDatetime(startup?.timeline.startTime)" :content="formatDatetime(startup?.timeline.startTime)"
/> />
<VDescriptionItem <VDescriptionItem
:label="$t('core.actuator.fields.timezone')" v-if="themeStore.activatedTheme"
:content="globalInfo?.timeZone" :label="$t('core.actuator.fields.activated_theme')"
/> >
<VTag @click="$router.push({ name: 'ThemeDetail' })">
<template v-if="themeStore.activatedTheme.spec.logo" #leftIcon>
<img
class="h-3.5 w-3.5 rounded-sm"
:src="themeStore.activatedTheme.spec.logo"
:alt="themeStore.activatedTheme.spec.displayName"
/>
</template>
{{ themeStore.activatedTheme.spec.displayName }}
</VTag>
</VDescriptionItem>
<VDescriptionItem <VDescriptionItem
:label="$t('core.actuator.fields.locale')" v-permission="['system:plugins:view']"
:content="globalInfo?.locale" :label="$t('core.actuator.fields.enabled_plugins')"
/> >
<VLoading v-if="isPluginsLoading" />
<span v-else-if="!plugins?.length">
{{ $t("core.common.text.none") }}
</span>
<div v-else class="flex flex-wrap gap-1.5">
<VTag
v-for="plugin in plugins"
:key="plugin.metadata.name"
@click="
$router.push({
name: 'PluginDetail',
params: { name: plugin.metadata.name },
})
"
>
<template v-if="plugin.status?.logo" #leftIcon>
<img
class="h-3.5 w-3.5 rounded-sm"
:src="plugin.status?.logo"
:alt="plugin.spec.displayName"
/>
</template>
{{ plugin.spec.displayName }}
</VTag>
</div>
</VDescriptionItem>
</VDescription> </VDescription>
</div> </div>
</div> </div>
@ -249,6 +376,14 @@ const handleDownloadLogfile = () => {
<VDescriptionItem :label="$t('core.actuator.fields.os')"> <VDescriptionItem :label="$t('core.actuator.fields.os')">
{{ info.os.name }} {{ info.os.version }} / {{ info.os.arch }} {{ info.os.name }} {{ info.os.version }} / {{ info.os.arch }}
</VDescriptionItem> </VDescriptionItem>
<VDescriptionItem
:label="$t('core.actuator.fields.timezone')"
:content="globalInfo?.timeZone"
/>
<VDescriptionItem
:label="$t('core.actuator.fields.locale')"
:content="globalInfo?.locale"
/>
<VDescriptionItem <VDescriptionItem
:label="$t('core.actuator.fields.log')" :label="$t('core.actuator.fields.log')"
vertical-center vertical-center

View File

@ -1019,13 +1019,15 @@ core:
fields: fields:
external_url: External url external_url: External url
start_time: Start time start_time: Start time
timezone: Timezone timezone: System Timezone
locale: Locale locale: System Locale
version: Version version: Version
build_time: Build time build_time: Build time
database: Database database: Database
os: Operating system os: Operating system
log: System log log: System log
activated_theme: Activated theme
enabled_plugins: Enabled plugins
fields_values: fields_values:
external_url: external_url:
not_setup: Not setup not_setup: Not setup

View File

@ -1019,13 +1019,15 @@ core:
fields: fields:
external_url: 外部访问地址 external_url: 外部访问地址
start_time: 启动时间 start_time: 启动时间
timezone: 时区 timezone: 系统时区
locale: 语言 locale: 系统语言
version: 版本 version: 版本
build_time: 构建时间 build_time: 构建时间
database: 数据库 database: 数据库
os: 操作系统 os: 操作系统
log: 运行日志 log: 运行日志
activated_theme: 已激活主题
enabled_plugins: 已启动插件
fields_values: fields_values:
external_url: external_url:
not_setup: 未设置 not_setup: 未设置

View File

@ -1019,13 +1019,15 @@ core:
fields: fields:
external_url: 外部訪問地址 external_url: 外部訪問地址
start_time: 啟動時間 start_time: 啟動時間
timezone: 時區 timezone: 系統時區
locale: 語言 locale: 系統語言
version: 版本 version: 版本
build_time: 構建時間 build_time: 構建時間
database: 資料庫 database: 資料庫
os: 操作系統 os: 操作系統
log: 運行日誌 log: 運行日誌
activated_theme: 已啟動主題
enabled_plugins: 已啟動插件
fields_values: fields_values:
external_url: external_url:
not_setup: 未設置 not_setup: 未設置