mirror of
https://github.com/MCSManager/MCSManager.git
synced 2025-01-12 14:54:34 +08:00
Fix: AntdvConfigProvider
This commit is contained in:
parent
aafcd324de
commit
8abff6590a
2
frontend/components.d.ts
vendored
2
frontend/components.d.ts
vendored
@ -36,6 +36,7 @@ declare module 'vue' {
|
||||
AnyAppForm: typeof import('./src/components/fc/CmdAssistantDialog/AnyAppForm.vue')['default']
|
||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
AppConfigProvider: typeof import('./src/components/AppConfigProvider.vue')['default']
|
||||
AppHeader: typeof import('./src/components/AppHeader.vue')['default']
|
||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||
@ -68,6 +69,7 @@ declare module 'vue' {
|
||||
CopyButton: typeof import('./src/components/CopyButton.vue')['default']
|
||||
DataStatistic: typeof import('./src/components/DataStatistic.vue')['default']
|
||||
Editor: typeof import('./src/components/Editor.vue')['default']
|
||||
Empty: typeof import('./src/components/Empty.vue')['default']
|
||||
FadeUpAnimation: typeof import('./src/components/FadeUpAnimation.vue')['default']
|
||||
IconBtn: typeof import('./src/components/IconBtn.vue')['default']
|
||||
InnerCard: typeof import('./src/components/InnerCard.vue')['default']
|
||||
|
@ -1,49 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import AppConfigProvider from "./components/AppConfigProvider.vue";
|
||||
import { RouterView } from "vue-router";
|
||||
import AppHeader from "./components/AppHeader.vue";
|
||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||
import enUS from "ant-design-vue/es/locale/en_US";
|
||||
import dayjs from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import "dayjs/locale/en";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { onMounted } from "vue";
|
||||
import { useAppConfigStore } from "@/stores/useAppConfigStore";
|
||||
import { theme } from "ant-design-vue";
|
||||
import InputDialogProvider from "./components/InputDialogProvider.vue";
|
||||
import { Button, Select, Input, Table } from "ant-design-vue";
|
||||
import MyselfInfoDialog from "./components/MyselfInfoDialog.vue";
|
||||
import { closeAppLoading } from "./tools/dom";
|
||||
|
||||
const { getCurrentLanguage, isDarkTheme } = useAppConfigStore();
|
||||
const locale = ref(enUS);
|
||||
const { isDarkTheme } = useAppConfigStore();
|
||||
|
||||
// Ant Design Vue i18n
|
||||
// This will also have to be changed if a new language is added.
|
||||
if (getCurrentLanguage().toLowerCase() === "zh_cn") {
|
||||
dayjs.locale("zh-cn");
|
||||
locale.value = zhCN;
|
||||
} else {
|
||||
dayjs.locale("en-us");
|
||||
}
|
||||
|
||||
const isDarkUI = isDarkTheme();
|
||||
const appTheme = {
|
||||
algorithm: theme.defaultAlgorithm,
|
||||
token: {
|
||||
fontSizeLG: 14,
|
||||
fontSizeSM: 12,
|
||||
fontSizeXL: 18
|
||||
}
|
||||
};
|
||||
|
||||
if (isDarkUI) {
|
||||
if (isDarkTheme()) {
|
||||
document.body.classList.add("app-dark-theme");
|
||||
appTheme.algorithm = theme.darkAlgorithm;
|
||||
} else {
|
||||
document.body.classList.add("app-light-theme");
|
||||
}
|
||||
|
||||
import { Button, Select, Input, Table, ConfigProvider } from "ant-design-vue";
|
||||
import MyselfInfoDialog from "./components/MyselfInfoDialog.vue";
|
||||
import { closeAppLoading } from "./tools/dom";
|
||||
|
||||
[Button, Select, Input, Table].forEach((element) => {
|
||||
element.props.size.default = "large";
|
||||
});
|
||||
@ -54,7 +27,7 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigProvider :theme="appTheme" :locale="locale">
|
||||
<AppConfigProvider>
|
||||
<div class="global-app-container">
|
||||
<AppHeader></AppHeader>
|
||||
<RouterView :key="$route.fullPath" />
|
||||
@ -63,5 +36,5 @@ onMounted(async () => {
|
||||
<!-- Global Components -->
|
||||
<InputDialogProvider></InputDialogProvider>
|
||||
<MyselfInfoDialog></MyselfInfoDialog>
|
||||
</ConfigProvider>
|
||||
</AppConfigProvider>
|
||||
</template>
|
||||
|
42
frontend/src/components/AppConfigProvider.vue
Normal file
42
frontend/src/components/AppConfigProvider.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||
import enUS from "ant-design-vue/es/locale/en_US";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import "dayjs/locale/en";
|
||||
import dayjs from "dayjs";
|
||||
import { ref } from "vue";
|
||||
import { useAppConfigStore } from "@/stores/useAppConfigStore";
|
||||
import { theme } from "ant-design-vue";
|
||||
import { ConfigProvider } from "ant-design-vue";
|
||||
|
||||
const { getCurrentLanguage, isDarkTheme } = useAppConfigStore();
|
||||
const locale = ref(enUS);
|
||||
|
||||
// init language with lib
|
||||
if (getCurrentLanguage().toLowerCase() === "zh_cn") {
|
||||
dayjs.locale("zh-cn");
|
||||
locale.value = zhCN;
|
||||
} else {
|
||||
dayjs.locale("en-us");
|
||||
}
|
||||
|
||||
const isDarkUI = isDarkTheme();
|
||||
const appTheme = {
|
||||
algorithm: theme.defaultAlgorithm,
|
||||
token: {
|
||||
fontSizeLG: 14,
|
||||
fontSizeSM: 12,
|
||||
fontSizeXL: 18
|
||||
}
|
||||
};
|
||||
|
||||
if (isDarkUI) {
|
||||
appTheme.algorithm = theme.darkAlgorithm;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigProvider :theme="appTheme" :locale="locale">
|
||||
<slot></slot>
|
||||
</ConfigProvider>
|
||||
</template>
|
13
frontend/src/components/Empty.vue
Normal file
13
frontend/src/components/Empty.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
description?: string;
|
||||
}>();
|
||||
</script>
|
||||
<template>
|
||||
<a-empty>
|
||||
<template #description>
|
||||
<span class="color-info">{{ description }}</span>
|
||||
</template>
|
||||
<!-- <a-button type="primary">Create Now</a-button> -->
|
||||
</a-empty>
|
||||
</template>
|
@ -18,6 +18,7 @@ import { throttle } from "lodash";
|
||||
import { useScreen } from "@/hooks/useScreen";
|
||||
import type { ColumnsType } from "ant-design-vue/es/table";
|
||||
import type { AntTableCell } from "../../types/ant";
|
||||
import AppConfigProvider from "../AppConfigProvider.vue";
|
||||
|
||||
const props = defineProps<MountComponent>();
|
||||
const { isPhone } = useScreen();
|
||||
@ -140,114 +141,121 @@ const handleChangeNode = async (item: NodeStatus) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:open="open"
|
||||
centered
|
||||
:mask-closable="false"
|
||||
:title="t('TXT_CODE_8145d25a')"
|
||||
:ok-text="t('TXT_CODE_abfe9512')"
|
||||
:cancel-text="t('TXT_CODE_a0451c97')"
|
||||
@ok="submit"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<a-typography-paragraph>
|
||||
<a-typography-text type="secondary">
|
||||
{{ t("TXT_CODE_50697989") }}
|
||||
</a-typography-text>
|
||||
</a-typography-paragraph>
|
||||
<a-row :gutter="[24, 24]" style="height: 100%">
|
||||
<a-col :span="24">
|
||||
<BetweenMenus>
|
||||
<template #left>
|
||||
<a-dropdown>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item
|
||||
v-for="item in nodes"
|
||||
:key="item.uuid"
|
||||
:disabled="!item.available"
|
||||
@click="handleChangeNode(item)"
|
||||
>
|
||||
<DatabaseOutlined v-if="item.available" />
|
||||
<FrownOutlined v-else />
|
||||
{{ computeNodeName(item.ip, item.available, item.remarks) }}
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="toNodesPage">
|
||||
<FormOutlined />
|
||||
{{ t("TXT_CODE_28e53fed") }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button :class="isPhone && 'mb-10 w-100'">
|
||||
{{
|
||||
computeNodeName(
|
||||
currentRemoteNode?.ip || "",
|
||||
currentRemoteNode?.available || true,
|
||||
currentRemoteNode?.remarks
|
||||
)
|
||||
}}
|
||||
<DownOutlined />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<template #right>
|
||||
<div class="search-input" :class="isPhone && 'w-100'">
|
||||
<a-input
|
||||
v-model:value="operationForm.instanceName"
|
||||
:placeholder="t('TXT_CODE_ce132192')"
|
||||
@press-enter="handleQueryInstance"
|
||||
@change="handleQueryInstance"
|
||||
>
|
||||
<template #prefix>
|
||||
<search-outlined />
|
||||
</template>
|
||||
</a-input>
|
||||
</div>
|
||||
</template>
|
||||
</BetweenMenus>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div v-if="instances" class="flex-between align-center">
|
||||
<a-typography-text>
|
||||
{{ t("TXT_CODE_379fa48a") }} {{ selectedItems.length }} {{ t("TXT_CODE_5cd3b4bd") }}
|
||||
</a-typography-text>
|
||||
<a-pagination
|
||||
v-model:current="operationForm.currentPage"
|
||||
v-model:pageSize="operationForm.pageSize"
|
||||
:total="instances.maxPage * operationForm.pageSize"
|
||||
show-size-changer
|
||||
@change="initInstancesData"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<template v-if="instancesList">
|
||||
<AppConfigProvider>
|
||||
<a-modal
|
||||
v-model:open="open"
|
||||
centered
|
||||
:mask-closable="false"
|
||||
:title="t('TXT_CODE_8145d25a')"
|
||||
:ok-text="t('TXT_CODE_abfe9512')"
|
||||
:cancel-text="t('TXT_CODE_a0451c97')"
|
||||
@ok="submit"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<a-typography-paragraph>
|
||||
<a-typography-text type="secondary">
|
||||
{{ t("TXT_CODE_50697989") }}
|
||||
</a-typography-text>
|
||||
</a-typography-paragraph>
|
||||
<a-row :gutter="[24, 24]" style="height: 100%">
|
||||
<a-col :span="24">
|
||||
<a-table
|
||||
:loading="isLoading"
|
||||
:data-source="instancesList"
|
||||
:columns="columns"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
:scroll="{
|
||||
x: 'max-content'
|
||||
}"
|
||||
>
|
||||
<template #bodyCell="{ column, record }: AntTableCell">
|
||||
<template v-if="column.key === 'operation'">
|
||||
<a-button v-if="findItem(record)" danger size="middle" @click="removeItem(record)">
|
||||
{{ t("TXT_CODE_65fcbd09") }}
|
||||
<BetweenMenus>
|
||||
<template #left>
|
||||
<a-dropdown>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item
|
||||
v-for="item in nodes"
|
||||
:key="item.uuid"
|
||||
:disabled="!item.available"
|
||||
@click="handleChangeNode(item)"
|
||||
>
|
||||
<DatabaseOutlined v-if="item.available" />
|
||||
<FrownOutlined v-else />
|
||||
{{ computeNodeName(item.ip, item.available, item.remarks) }}
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="toNodesPage">
|
||||
<FormOutlined />
|
||||
{{ t("TXT_CODE_28e53fed") }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button :class="isPhone && 'mb-10 w-100'">
|
||||
{{
|
||||
computeNodeName(
|
||||
currentRemoteNode?.ip || "",
|
||||
currentRemoteNode?.available || true,
|
||||
currentRemoteNode?.remarks
|
||||
)
|
||||
}}
|
||||
<DownOutlined />
|
||||
</a-button>
|
||||
<a-button v-else size="middle" @click="selectItem(record)">
|
||||
{{ t("TXT_CODE_7b2c5414") }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</a-table>
|
||||
<template #right>
|
||||
<div class="search-input" :class="isPhone && 'w-100'">
|
||||
<a-input
|
||||
v-model:value="operationForm.instanceName"
|
||||
:placeholder="t('TXT_CODE_ce132192')"
|
||||
@press-enter="handleQueryInstance"
|
||||
@change="handleQueryInstance"
|
||||
>
|
||||
<template #prefix>
|
||||
<search-outlined />
|
||||
</template>
|
||||
</a-input>
|
||||
</div>
|
||||
</template>
|
||||
</BetweenMenus>
|
||||
</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
<a-col :span="24">
|
||||
<div v-if="instances" class="flex-between align-center">
|
||||
<a-typography-text>
|
||||
{{ t("TXT_CODE_379fa48a") }} {{ selectedItems.length }} {{ t("TXT_CODE_5cd3b4bd") }}
|
||||
</a-typography-text>
|
||||
<a-pagination
|
||||
v-model:current="operationForm.currentPage"
|
||||
v-model:pageSize="operationForm.pageSize"
|
||||
:total="instances.maxPage * operationForm.pageSize"
|
||||
show-size-changer
|
||||
@change="initInstancesData"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<template v-if="instancesList">
|
||||
<a-col :span="24">
|
||||
<a-table
|
||||
:loading="isLoading"
|
||||
:data-source="instancesList"
|
||||
:columns="columns"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
:scroll="{
|
||||
x: 'max-content'
|
||||
}"
|
||||
>
|
||||
<template #bodyCell="{ column, record }: AntTableCell">
|
||||
<template v-if="column.key === 'operation'">
|
||||
<a-button
|
||||
v-if="findItem(record)"
|
||||
danger
|
||||
size="middle"
|
||||
@click="removeItem(record)"
|
||||
>
|
||||
{{ t("TXT_CODE_65fcbd09") }}
|
||||
</a-button>
|
||||
<a-button v-else size="middle" @click="selectItem(record)">
|
||||
{{ t("TXT_CODE_7b2c5414") }}
|
||||
</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</AppConfigProvider>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -24,7 +24,7 @@ import { router } from "@/config/router";
|
||||
import { remoteInstances, remoteNodeList } from "@/services/apis";
|
||||
import { batchStart, batchStop, batchKill, batchDelete } from "@/services/apis/instance";
|
||||
import type { NodeStatus } from "../types/index";
|
||||
import { message, notification, Modal } from "ant-design-vue";
|
||||
import { notification, Modal } from "ant-design-vue";
|
||||
import { computeNodeName } from "../tools/nodes";
|
||||
import type { InstanceMoreDetail } from "../hooks/useInstance";
|
||||
import { useInstanceMoreDetail } from "../hooks/useInstance";
|
||||
@ -55,7 +55,7 @@ const instancesMoreInfo = computed(() => {
|
||||
const instanceMoreInfo = useInstanceMoreDetail(instance);
|
||||
newInstances.push(instanceMoreInfo);
|
||||
}
|
||||
return newInstances;
|
||||
return newInstances || [];
|
||||
});
|
||||
|
||||
const initNodes = async () => {
|
||||
@ -324,7 +324,11 @@ onMounted(async () => {
|
||||
<DownOutlined />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-button type="primary" @click="toCreateAppPage">
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="!currentRemoteNode?.available"
|
||||
@click="toCreateAppPage"
|
||||
>
|
||||
{{ t("TXT_CODE_53408064") }}
|
||||
</a-button>
|
||||
</template>
|
||||
@ -410,7 +414,7 @@ onMounted(async () => {
|
||||
<template v-if="isLoading">
|
||||
<Loading></Loading>
|
||||
</template>
|
||||
<template v-if="instancesMoreInfo">
|
||||
<template v-else-if="instancesMoreInfo.length > 0">
|
||||
<a-col v-for="item in instancesMoreInfo" :key="item.instanceUuid" :span="24" :md="6">
|
||||
<CardPanel
|
||||
class="instance-card"
|
||||
@ -455,10 +459,10 @@ onMounted(async () => {
|
||||
</a-col>
|
||||
</template>
|
||||
<div
|
||||
v-if="!instancesMoreInfo || instancesMoreInfo.length === 0"
|
||||
v-else-if="instancesMoreInfo.length === 0"
|
||||
class="flex align-center justify-center h-100 w-100"
|
||||
>
|
||||
<a-empty :description="t('无内容,请在右上角下拉框选择节点')" />
|
||||
<Empty :description="t('无内容,请在右上角下拉框选择节点,或点击新建应用')" />
|
||||
</div>
|
||||
</a-row>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user