mirror of https://github.com/halo-dev/halo
refactor: abnormal status display of plugin management (#3945)
#### What type of PR is this? /kind improvement /area console /milestone 2.6.x #### What this PR does / why we need it: 重构 Console 端插件异常状态的判断和显示,改动如下: 1. 移除插件名称旁边的启用状态。 2. 切换按钮的状态是期望值,意思就是不与插件实际状态一致。 3. 小红点出现的时机为:插件的实际状态与期望状态不一致以及插件本身出了异常。 4. 插件详情页面支持横幅显示插件异常状态。 <img width="1358" alt="image" src="https://github.com/halo-dev/halo/assets/21301288/42408d1f-7975-4aef-9373-d828994501b3"> <img width="1383" alt="image" src="https://github.com/halo-dev/halo/assets/21301288/033efdef-470b-4570-94c1-da64d9ea0db9"> #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3940 #### Special notes for your reviewer: 测试方式: 1. 想办法将插件状态变成异常,比如在开发环境将 runtime-mode 改为 deployment。 2. 检查 Console 端插件管理中的 UI 表现是否和上面的描述一致。 #### Does this PR introduce a user-facing change? ```release-note 重构 Console 插件管理的异常状态显示。 ```pull/3939/head^2
parent
017d5b8d8f
commit
8deea08231
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
VAlert,
|
||||
VDescription,
|
||||
VDescriptionItem,
|
||||
VSwitch,
|
||||
VTag,
|
||||
} from "@halo-dev/components";
|
||||
import type { Ref } from "vue";
|
||||
import { computed, inject } from "vue";
|
||||
|
@ -16,7 +16,7 @@ import { formatDatetime } from "@/utils/date";
|
|||
import { useQuery } from "@tanstack/vue-query";
|
||||
|
||||
const plugin = inject<Ref<Plugin | undefined>>("plugin");
|
||||
const { changeStatus, isStarted } = usePluginLifeCycle(plugin);
|
||||
const { changeStatus } = usePluginLifeCycle(plugin);
|
||||
|
||||
interface RoleTemplateGroup {
|
||||
module: string | null | undefined;
|
||||
|
@ -70,23 +70,25 @@ const pluginRoleTemplateGroups = computed<RoleTemplateGroup[]>(() => {
|
|||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
{{ $t("core.plugin.detail.header.title") }}
|
||||
</h3>
|
||||
<p class="mt-1 flex max-w-2xl items-center gap-2">
|
||||
<span class="text-sm text-gray-500">
|
||||
{{ plugin?.spec.version }}
|
||||
</span>
|
||||
<VTag>
|
||||
{{
|
||||
isStarted
|
||||
? $t("core.common.status.activated")
|
||||
: $t("core.common.status.not_activated")
|
||||
}}
|
||||
</VTag>
|
||||
</p>
|
||||
</div>
|
||||
<div v-permission="['system:plugins:manage']">
|
||||
<VSwitch :model-value="isStarted" @change="changeStatus" />
|
||||
<VSwitch :model-value="plugin?.spec.enabled" @change="changeStatus" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
plugin?.status?.phase === 'FAILED' &&
|
||||
plugin?.status?.conditions?.length
|
||||
"
|
||||
class="w-full px-4 pb-2 sm:px-6"
|
||||
>
|
||||
<VAlert
|
||||
type="error"
|
||||
:title="plugin?.status?.conditions?.[0].reason"
|
||||
:description="plugin?.status?.conditions?.[0].message"
|
||||
:closable="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<VDescription>
|
||||
<VDescriptionItem
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
VSpace,
|
||||
VSwitch,
|
||||
VTag,
|
||||
VStatusDot,
|
||||
VEntity,
|
||||
VEntityField,
|
||||
|
@ -42,7 +40,8 @@ const { plugin } = toRefs(props);
|
|||
|
||||
const upgradeModal = ref(false);
|
||||
|
||||
const { isStarted, changeStatus, uninstall } = usePluginLifeCycle(plugin);
|
||||
const { getFailedMessage, changeStatus, uninstall } =
|
||||
usePluginLifeCycle(plugin);
|
||||
|
||||
const onUpgradeModalClose = () => {
|
||||
emit("reload");
|
||||
|
@ -72,13 +71,6 @@ const handleResetSettingConfig = async () => {
|
|||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getFailedMessage = (plugin: Plugin) => {
|
||||
if (plugin.status?.conditions?.length) {
|
||||
const lastCondition = plugin.status.conditions[0];
|
||||
return [lastCondition.reason, lastCondition.message].join(":");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<PluginUploadModal
|
||||
|
@ -104,28 +96,12 @@ const getFailedMessage = (plugin: Plugin) => {
|
|||
name: 'PluginDetail',
|
||||
params: { name: plugin?.metadata.name },
|
||||
}"
|
||||
>
|
||||
<template #extra>
|
||||
<VSpace>
|
||||
<VTag>
|
||||
{{
|
||||
isStarted
|
||||
? $t("core.common.status.activated")
|
||||
: $t("core.common.status.not_activated")
|
||||
}}
|
||||
</VTag>
|
||||
</VSpace>
|
||||
</template>
|
||||
</VEntityField>
|
||||
/>
|
||||
</template>
|
||||
<template #end>
|
||||
<VEntityField v-if="plugin?.status?.phase === 'FAILED'">
|
||||
<template #description>
|
||||
<VStatusDot
|
||||
v-tooltip="getFailedMessage(plugin)"
|
||||
state="error"
|
||||
animate
|
||||
/>
|
||||
<VStatusDot v-tooltip="getFailedMessage()" state="error" animate />
|
||||
</template>
|
||||
</VEntityField>
|
||||
<VEntityField v-if="plugin?.metadata.deletionTimestamp">
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useI18n } from "vue-i18n";
|
|||
|
||||
interface usePluginLifeCycleReturn {
|
||||
isStarted: ComputedRef<boolean | undefined>;
|
||||
getFailedMessage: () => string | undefined;
|
||||
changeStatus: () => void;
|
||||
uninstall: (deleteExtensions?: boolean) => void;
|
||||
}
|
||||
|
@ -23,6 +24,18 @@ export function usePluginLifeCycle(
|
|||
);
|
||||
});
|
||||
|
||||
const getFailedMessage = () => {
|
||||
if (!plugin?.value) return;
|
||||
|
||||
if (!isStarted.value) {
|
||||
const lastCondition = plugin.value.status?.conditions?.[0];
|
||||
|
||||
return (
|
||||
[lastCondition?.reason, lastCondition?.message].join(":") || "Unknown"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const changeStatus = () => {
|
||||
if (!plugin?.value) return;
|
||||
|
||||
|
@ -135,6 +148,7 @@ export function usePluginLifeCycle(
|
|||
|
||||
return {
|
||||
isStarted,
|
||||
getFailedMessage,
|
||||
changeStatus,
|
||||
uninstall,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue