feat: 概览兼容移动端 (#1109)

#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
This commit is contained in:
wangdan-fit2cloud 2023-05-23 13:51:43 +08:00 committed by GitHub
parent c052887d58
commit 0d084861e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
95 changed files with 326 additions and 204 deletions

View file

@ -77,8 +77,10 @@ declare module 'vue' {
FileList: typeof import('./src/components/file-list/index.vue')['default']
FileRole: typeof import('./src/components/file-role/index.vue')['default']
Footer: typeof import('./src/components/app-layout/footer/index.vue')['default']
FormButton: typeof import('./src/components/layout-content/form-button.vue')['default']
Group: typeof import('./src/components/group/index.vue')['default']
InfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
LayoutContent: typeof import('./src/components/layout-content/index.vue')['default']
Line: typeof import('./src/components/v-charts/components/Line.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
Logo: typeof import('./src/components/app-layout/menu/components/Logo.vue')['default']

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/fav/favicon.png" />
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>loading...</title>
</head>
<body>

View file

@ -1,9 +1,9 @@
@font-face {
font-family: "panel"; /* Project id 3575356 */
src: url('iconfont.woff2?t=1681715760705') format('woff2'),
url('iconfont.woff?t=1681715760705') format('woff'),
url('iconfont.ttf?t=1681715760705') format('truetype'),
url('iconfont.svg?t=1681715760705#panel') format('svg');
src: url('iconfont.woff2?t=1684465849452') format('woff2'),
url('iconfont.woff?t=1684465849452') format('woff'),
url('iconfont.ttf?t=1684465849452') format('truetype'),
url('iconfont.svg?t=1684465849452#panel') format('svg');
}
.panel {
@ -14,6 +14,10 @@
-moz-osx-font-smoothing: grayscale;
}
.p-caidan:before {
content: "\e61d";
}
.p-yanzhengma1:before {
content: "\e744";
}

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,13 @@
"css_prefix_text": "p-",
"description": "",
"glyphs": [
{
"icon_id": "7708032",
"name": "菜单",
"font_class": "caidan",
"unicode": "e61d",
"unicode_decimal": 58909
},
{
"icon_id": "7131916",
"name": "验证码",

View file

@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="caidan" unicode="&#58909;" d="M896 663.272727h-744.727273a34.909091 34.909091 0 0 0 0 69.818182h744.727273a34.909091 34.909091 0 0 0 0-69.818182zM896 11.636364h-744.727273a34.909091 34.909091 0 0 0 0 69.818181h744.727273a34.909091 34.909091 0 0 0 0-69.818181zM709.818182 337.454545h-558.545455a34.909091 34.909091 0 0 0 0 69.818182h558.545455a34.909091 34.909091 0 0 0 0-69.818182z" horiz-adv-x="1024" />
<glyph glyph-name="yanzhengma1" unicode="&#59204;" d="M544 627h124c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32H544v-116a32.5 32.5 0 0 0-0.056-1.916C670.218 429.588 768 321.96299999999997 768 191.5 768 50.39099999999996 653.609-64 512.5-64 371.391-64 257 50.39099999999996 257 191.5c0 130.12 97.27 237.523 223.064 253.46A32.488 32.488 0 0 0 480 447V800c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32v-45h192c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32H544v-64z m-31.5-627C618.263 0 704 85.73699999999997 704 191.5S618.263 383 512.5 383 321 297.26300000000003 321 191.5 406.737 0 512.5 0z" horiz-adv-x="1024" />
<glyph glyph-name="tengxunyun1" unicode="&#58961;" d="M512 725.333333c130.474667 0 240.938667-83.797333 277.930667-199.296a198.826667 198.826667 0 0 1-41.557334 0.597334 222.293333 222.293333 0 0 1-49.706666-10.624C668.202667 586.666667 596.096 636.245333 512 636.245333c-100.266667 0-183.466667-70.528-199.381333-163.029333a279.04 279.04 0 0 1-89.429334 3.84C241.28 617.045333 363.690667 725.333333 512 725.333333zM258.474667 478.677333c54.442667 0 104.192-20.181333 142.165333-53.418666 16.085333-14.08 45.226667-39.68 87.381333-76.8l-7.381333 6.528-61.568-60.885334-54.4 54.4c-34.218667 34.261333-66.090667 47.957333-106.197333 47.957334a133.589333 133.589333 0 0 1 0-267.221334c10.666667 0 29.312-0.768 56.064-2.346666l-90.453334-77.141334A215.893333 215.893333 0 0 0 258.432 478.72zM674.346667 461.525333a215.808 215.808 0 0 0 168.618666-397.354666c-15.36-6.485333-38.186667-15.957333-63.146666-16.213334-72.106667-0.597333-244.181333-0.896-516.352-0.938666h-42.666667a206248.106667 206248.106667 0 0 1 397.013333 380.714666c18.261333 17.578667 41.130667 27.264 56.533334 33.792z m41.856-80.554666c-9.258667-3.925333-23.04-9.770667-34.048-20.352-30.165333-29.098667-109.952-105.642667-239.445334-229.632h53.418667c148.181333 0 242.773333 0.213333 283.733333 0.554666 15.061333 0.128 28.842667 5.845333 38.101334 9.813334a130.133333 130.133333 0 0 1-101.76 239.616z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View file

@ -71,7 +71,6 @@ import { onMounted, reactive, ref } from 'vue';
import Status from '@/components/status/index.vue';
import { ElMessageBox } from 'element-plus';
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import { MsgSuccess } from '@/utils/message';
const props = defineProps({

View file

@ -58,7 +58,6 @@
<script lang="ts" setup>
import { ref } from 'vue';
import i18n from '@/lang';
import ComplexTable from '@/components/complex-table/index.vue';
import { CreateGroup, DeleteGroup, GetGroupList, UpdateGroup } from '@/api/modules/group';
import Header from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message';

View file

@ -0,0 +1,11 @@
import { type App } from 'vue';
import LayoutContent from './layout-content/index.vue';
import RouterButton from './router-button/index.vue';
import ComplexTable from './complex-table/index.vue';
export default {
install(app: App) {
app.component(LayoutContent.name, LayoutContent);
app.component(RouterButton.name, RouterButton);
app.component(ComplexTable.name, ComplexTable);
},
};

View file

@ -132,8 +132,19 @@ const showBack = computed(() => {
.main-box {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 5px;
overflow: auto;
overflow-x: hidden !important;
// background-color: #f0f2f5;
border-radius: 4px;
// box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
&::-webkit-scrollbar {
background-color: white;
}
}
.main-content {
margin-top: 20px;
}

View file

@ -79,7 +79,6 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import { reactive, ref } from 'vue';
import { computeSize } from '@/utils/util';
import { useDeleteData } from '@/hooks/use-delete-data';

View file

@ -0,0 +1,4 @@
export enum DeviceType {
Mobile,
Desktop,
}

View file

@ -1,7 +1,4 @@
<template>
<div>
<slot></slot>
</div>
<div class="footer flx-justify-between">
<div class="footer-left">
<a href="https://fit2cloud.com/" target="_blank">Copyright © 2014-2023 FIT2CLOUD 飞致云</a>
@ -18,10 +15,10 @@ import SystemUpgrade from '@/components/system-upgrade/index.vue';
<style scoped lang="scss">
.footer {
height: 45px;
background: #ffffff;
border-top: 1px solid #e4e7ed;
box-sizing: border-box;
padding: 10px 20px;
a {
font-size: 12px;
color: #858585;
@ -34,13 +31,5 @@ import SystemUpgrade from '@/components/system-upgrade/index.vue';
text-decoration: none;
letter-spacing: 0.5px;
}
.footer-left {
margin-left: 20px;
}
.footer-right {
float: right;
margin-right: 20px;
}
}
</style>

View file

@ -0,0 +1,24 @@
<script setup lang="ts">
import { MenuStore } from '@/store/modules/menu';
const menuStore = MenuStore();
</script>
<template>
<div class="mobile-header">
<svg-icon class="caidan" iconName="p-caidan" @click="menuStore.setCollapse()"></svg-icon>
</div>
</template>
<style lang="scss" scoped>
.mobile-header {
background: rgba(255, 255, 255, 0.65);
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.2);
padding: 10px;
text-align: left;
z-index: 999;
.caidan {
margin-left: 10px;
font-size: 10px;
cursor: pointer;
}
}
</style>

View file

@ -3,7 +3,7 @@
<el-sub-menu
v-if="subItem.children && subItem.children.length > 1"
:index="subItem.path"
popper-class="menu-popper"
popper-class="sidebar-container-popper"
>
<template #title>
<el-icon class="sub-icon">

View file

@ -75,7 +75,7 @@
}
}
.menu-popper {
.sidebar-container-popper {
.el-menu {
background-color: var(--el-menu-bg-color) !important;
padding: 4px 8px;

View file

@ -1,7 +1,6 @@
<template>
<div
class="menu"
:style="{ width: isCollapse ? '75px' : '180px' }"
class="sidebar-container"
element-loading-text="Loading..."
:element-loading-spinner="loadingSvg"
element-loading-svg-view-box="-10, -10, 50, 50"
@ -15,7 +14,7 @@
:collapse="isCollapse"
:collapse-transition="false"
:unique-opened="true"
popper-class="menu-popper"
popper-class="sidebar-container-popper"
>
<SubItem :menuList="routerMenus"></SubItem>
<el-menu-item :index="''">
@ -39,7 +38,7 @@ import { MenuStore } from '@/store/modules/menu';
import { loadingSvg } from '@/utils/svg';
import Logo from './components/Logo.vue';
import Collapse from './components/Collapse.vue';
import SubItem from './components/sub-item.vue';
import SubItem from './components/SubItem.vue';
import router, { menuList } from '@/routers/router';
import { logOutApi } from '@/api/modules/auth';
import i18n from '@/lang';
@ -97,7 +96,7 @@ onMounted(async () => {
<style lang="scss">
@import './index.scss';
.menu {
.sidebar-container {
position: relative;
display: flex;
flex-direction: column;
@ -114,7 +113,7 @@ onMounted(async () => {
border-right: none;
}
}
.menu-footer {
.sidebar-container-footer {
height: 30px;
background-color: #c0c0c0;
text-align: center;

View file

@ -0,0 +1,4 @@
export { default as Sidebar } from './Sidebar/index.vue';
export { default as Footer } from './AppFooter.vue';
export { default as AppMain } from './AppMain.vue';
export { default as MobileHeader } from './MobileHeader.vue';

View file

@ -0,0 +1,53 @@
import { watch, onBeforeMount, onMounted, onBeforeUnmount } from 'vue';
import { useRoute } from 'vue-router';
import { MenuStore } from '@/store/modules/menu';
import { GlobalStore } from '@/store';
import { DeviceType } from '@/enums/app';
/** 参考 Bootstrap 的响应式设计 WIDTH = 600 */
const WIDTH = 600;
/** 根据大小变化重新布局 */
export default () => {
const route = useRoute();
const globalStore = GlobalStore();
const menuStore = MenuStore();
const _isMobile = () => {
const rect = document.body.getBoundingClientRect();
return rect.width - 1 < WIDTH;
};
const _resizeHandler = () => {
if (!document.hidden) {
const isMobile = _isMobile();
globalStore.toggleDevice(isMobile ? DeviceType.Mobile : DeviceType.Desktop);
if (isMobile) {
menuStore.closeSidebar(true);
}
}
};
watch(
() => route.name,
() => {
if (globalStore.device === DeviceType.Mobile && !menuStore.isCollapse) {
menuStore.closeSidebar(false);
}
},
);
onBeforeMount(() => {
window.addEventListener('resize', _resizeHandler);
});
onMounted(() => {
if (_isMobile()) {
globalStore.toggleDevice(DeviceType.Mobile);
menuStore.closeSidebar(true);
}
});
onBeforeUnmount(() => {
window.removeEventListener('resize', _resizeHandler);
});
};

View file

@ -1,37 +0,0 @@
.el-container {
display: flex;
width: 100%;
min-width: 970px;
height: 100%;
.el-aside {
width: auto;
overflow: inherit;
}
.el-header,
.el-footer {
height: auto;
padding: 0;
}
.el-main {
box-sizing: border-box;
// padding: 20px 33px;
overflow-x: hidden;
background-color: #f4f4f4;
// background: #f0f2f5;
.main-box {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 5px;
overflow: auto;
overflow-x: hidden !important;
// background-color: #f0f2f5;
border-radius: 4px;
// box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
&::-webkit-scrollbar {
background-color: white;
}
}
}
}

View file

@ -1,31 +1,134 @@
<template>
<el-container>
<el-aside>
<Menu>
<slot name="menu"></slot>
</Menu>
</el-aside>
<el-container>
<el-main>
<div>
<View></View>
</div>
</el-main>
<el-footer>
<Footer>
<slot name="footer"></slot>
</Footer>
</el-footer>
</el-container>
</el-container>
<div :class="classObj" class="app-wrapper">
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
<div class="app-sidebar">
<Sidebar />
</div>
<div class="main-container">
<mobile-header v-if="classObj.mobile" />
<app-main class="app-main" />
<Footer class="app-footer" />
</div>
</div>
</template>
<script setup lang="ts">
import Menu from './layout-menu.vue';
import Footer from './layout-footer.vue';
import View from './layout-view.vue';
import { computed } from 'vue';
import { Sidebar, Footer, AppMain, MobileHeader } from './components';
import useResize from './hooks/useResize';
import { GlobalStore } from '@/store';
import { MenuStore } from '@/store/modules/menu';
import { DeviceType } from '@/enums/app';
useResize();
const menuStore = MenuStore();
const globalStore = GlobalStore();
const classObj = computed(() => {
return {
hideSidebar: menuStore.isCollapse,
openSidebar: !menuStore.isCollapse,
mobile: globalStore.device === DeviceType.Mobile,
withoutAnimation: menuStore.withoutAnimation,
};
});
const handleClickOutside = () => {
menuStore.closeSidebar(false);
};
</script>
<style scoped lang="scss">
@import './index.scss';
.app-wrapper {
position: relative;
width: 100%;
}
.drawer-bg {
background-color: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.main-container {
display: flex;
flex-direction: column;
flex: 1;
flex-basis: auto;
position: relative;
min-height: 100%;
height: calc(100vh);
transition: margin-left 0.28s;
margin-left: var(--panel-menu-width);
background-color: #f4f4f4;
overflow-x: hidden;
}
.app-main {
padding: 20px;
flex: 1;
flex-basis: auto;
overflow: auto;
}
.app-sidebar {
transition: width 0.28s;
width: var(--panel-menu-width) !important;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
}
.hideSidebar {
.main-container {
margin-left: var(--panel-menu-hide-width);
}
.app-sidebar {
width: var(--panel-menu-hide-width) !important;
}
.fixed-header {
width: calc(100% - var(--panel-menu-hide-width));
}
}
// for mobile response
.mobile {
.main-container {
margin-left: 0px;
}
.app-sidebar {
transition: transform 0.28s;
width: var(--panel-menu-width) !important;
background: #ffffff;
}
.app-footer {
display: block;
text-align: center;
}
&.openSidebar {
position: fixed;
top: 0;
}
&.hideSidebar {
.app-sidebar {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(calc(0px - var(--panel-menu-width)), 0, 0);
}
}
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
}
}
</style>

View file

@ -1,3 +0,0 @@
<template>
<slot></slot>
</template>

View file

@ -1,3 +0,0 @@
<template>
<slot></slot>
</template>

View file

@ -11,6 +11,7 @@ import router from '@/routers/index';
import I18n from '@/lang/index';
import pinia from '@/store/index';
import SvgIcon from './components/svg-icon/svg-icon.vue';
import Components from '@/components';
import ElementPlus from 'element-plus';
import Fit2CloudPlus from 'fit2cloud-ui-plus';
@ -29,4 +30,5 @@ app.use(router);
app.use(I18n);
app.use(pinia);
app.use(directives);
app.use(Components);
app.mount('#app');

View file

@ -1,5 +1,4 @@
/**
* @description: default layout
*/
// export const Layout = () => import('@/layout/index.vue');
export const Layout = () => import('@/components/app-layout/index.vue');
export const Layout = () => import('@/layout/index.vue');

View file

@ -3,6 +3,7 @@ import { GlobalState, ThemeConfigProp } from './interface';
import { createPinia } from 'pinia';
import piniaPersistConfig from '@/config/pinia-persist';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import { DeviceType } from '@/enums/app';
import i18n from '@/lang';
export const GlobalStore = defineStore({
@ -24,6 +25,7 @@ export const GlobalStore = defineStore({
agreeLicense: false,
hasNewVersion: false,
ignoreCaptcha: true,
device: DeviceType.Desktop,
}),
getters: {},
actions: {
@ -52,6 +54,9 @@ export const GlobalStore = defineStore({
setAgreeLicense(agree: boolean) {
this.agreeLicense = agree;
},
toggleDevice(value: DeviceType) {
this.device = value;
},
},
persist: piniaPersistConfig('GlobalState'),
});

View file

@ -1,5 +1,5 @@
import { RouteRecordRaw } from 'vue-router';
import { DeviceType } from '@/enums/app';
export interface ThemeConfigProp {
panelName: string;
primary: string;
@ -20,11 +20,13 @@ export interface GlobalState {
agreeLicense: boolean;
hasNewVersion: boolean;
ignoreCaptcha: boolean;
device: DeviceType;
}
export interface MenuState {
isCollapse: boolean;
menuList: RouteRecordRaw[];
withoutAnimation: boolean;
}
export interface AuthState {

View file

@ -9,11 +9,13 @@ export const MenuStore = defineStore({
state: (): MenuState => ({
isCollapse: false,
menuList: [],
withoutAnimation: false,
}),
getters: {},
actions: {
async setCollapse() {
this.isCollapse = !this.isCollapse;
this.withoutAnimation = false;
},
async setMenuList(menuList: RouteRecordRaw[]) {
const menus = menuList.filter((item) => {
@ -21,6 +23,10 @@ export const MenuStore = defineStore({
});
this.menuList = menus;
},
closeSidebar(withoutAnimation: boolean) {
this.isCollapse = true;
this.withoutAnimation = withoutAnimation;
},
},
persist: piniaPersistConfig('MenuStore'),
});

View file

@ -230,7 +230,7 @@
}
}
.menu-popper {
.sidebar-container-popper {
.el-menu--popup-right-start {
background-color: rgba(0, 94, 235, 0.1);
}
@ -328,4 +328,4 @@
.no-active-button {
background: none;
border: none;
}
}

View file

@ -111,14 +111,14 @@ html.dark {
::-webkit-scrollbar-thumb {
background-color: var(--el-border-color-darker);
}
// menu
.menu-popper {
// sidebar
.sidebar-container-popper {
border: 1px solid #66686c;
.el-menu--popup-container {
border: none;
}
}
.menu {
.sidebar-container {
border-right: 1px solid var(--el-border-color-light);
}
.el-menu {
@ -157,14 +157,19 @@ html.dark {
}
// layout
.el-container {
.el-main {
.app-wrapper {
.main-container {
background-color: var(--panel-main-bg-color) !important;
}
.footer {
.app-footer {
background-color: var(--panel-main-bg-color) !important;
border-top: var(--panel-border);
}
.mobile-header {
background-color: var(--panel-main-bg-color) !important;
border-bottom: var(--panel-border);
color: #ffffff;
}
}
.system-label {
color: var(--el-menu-text-color);

View file

@ -6,7 +6,8 @@ html {
--el-menu-bg-color: rgba(0, 94, 235, 0.1) !important;
--el-menu-item-bg-color: rgba(255, 255, 255, 0.3);
--el-menu-item-bg-color-active: #ffffff;
--panel-menu-width: 180px;
--panel-menu-hide-width: 75px;
--panel-text-color: #1f2329;
--panel-border: 1px solid #f2f2f2;
--panel-button-active: #ffffff;

View file

@ -1,6 +1,7 @@
@use 'fit2cloud-ui-plus/src/styles/index.scss' as *;
@use './element.scss';
@use './element-dark.scss';
@use './moblie.scss';
@use './reset.scss';
@use './var.scss';
@use 'md-editor-v3/lib/style.css';

View file

@ -0,0 +1,9 @@
.mobile {
.monitor-tags {
position: inherit;
top: 13px;
}
.mobile-monitor-chart {
margin-top: 20px !important;
}
}

View file

@ -104,7 +104,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import { App } from '@/api/interface/app';
import { onMounted, reactive, ref } from 'vue';
import { GetAppListUpdate, GetAppTags, SearchApp, SyncApp } from '@/api/modules/app';

View file

@ -92,7 +92,6 @@
<script lang="ts" setup>
import { GetApp, GetAppDetail } from '@/api/modules/app';
import LayoutContent from '@/layout/layout-content.vue';
import MdEditor from 'md-editor-v3';
import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';

View file

@ -10,8 +10,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
import i18n from '@/lang';
import { onMounted, ref } from 'vue';
import { SearchAppInstalled } from '@/api/modules/app';

View file

@ -205,7 +205,6 @@ import {
AppInstalledDeleteCheck,
GetAppTags,
} from '@/api/modules/app';
import LayoutContent from '@/layout/layout-content.vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';

View file

@ -115,13 +115,11 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import Tooltip from '@/components/tooltip/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import CreateDialog from '@/views/container/container/create/index.vue';
import MonitorDialog from '@/views/container/container/monitor/index.vue';
import ContainerLogDialog from '@/views/container/container/log/index.vue';
import TerminalDialog from '@/views/container/container/terminal/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import Status from '@/components/status/index.vue';
import { dateFormat } from '@/utils/util';
import { composeOperator, ContainerOperator, inspect, searchContainer } from '@/api/modules/container';

View file

@ -92,10 +92,8 @@
<script lang="ts" setup>
import Tooltip from '@/components/tooltip/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import { reactive, onMounted, ref } from 'vue';
import LayoutContent from '@/layout/layout-content.vue';
import EditDialog from '@/views/container/compose/edit/index.vue';
import CreateDialog from '@/views/container/compose/create/index.vue';
import DeleteDialog from '@/views/container/compose/delete/index.vue';

View file

@ -127,9 +127,7 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Tooltip from '@/components/tooltip/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import ReNameDialog from '@/views/container/container/rename/index.vue';
import CreateDialog from '@/views/container/container/create/index.vue';

View file

@ -79,12 +79,10 @@
<script lang="ts" setup>
import Tooltip from '@/components/tooltip/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFormat } from '@/utils/util';
import { Container } from '@/api/interface/container';
import LayoutContent from '@/layout/layout-content.vue';
import Pull from '@/views/container/image/pull/index.vue';
import Tag from '@/views/container/image/tag/index.vue';
import Push from '@/views/container/image/push/index.vue';

View file

@ -9,8 +9,6 @@
<script lang="ts" setup>
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{

View file

@ -90,9 +90,7 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Tooltip from '@/components/tooltip/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import CreateDialog from '@/views/container/network/create/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';

View file

@ -75,8 +75,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import OperatorDialog from '@/views/container/repo/operator/index.vue';
import { reactive, onMounted, ref } from 'vue';

View file

@ -176,7 +176,6 @@
import { ElMessageBox, FormInstance } from 'element-plus';
import { onMounted, reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import LayoutContent from '@/layout/layout-content.vue';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';

View file

@ -64,8 +64,6 @@
<script lang="ts" setup>
import Tooltip from '@/components/tooltip/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFormatSimple } from '@/utils/util';

View file

@ -75,9 +75,7 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Tooltip from '@/components/tooltip/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import CreateDialog from '@/views/container/volume/create/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';

View file

@ -153,15 +153,12 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import Tooltip from '@/components/tooltip/index.vue';
import OperatrDialog from '@/views/cronjob/operate/index.vue';
import Records from '@/views/cronjob/record/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import { loadZero } from '@/utils/util';
import { onMounted, reactive, ref } from 'vue';
import RouterButton from '@/components/router-button/index.vue';
import { deleteCronjob, getCronjobPage, handleOnce, updateStatus } from '@/api/modules/cronjob';
import i18n from '@/lang';
import { Cronjob } from '@/api/interface/cronjob';

View file

@ -320,7 +320,6 @@ import { dateFormat } from '@/utils/util';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import { DownloadByPath, LoadFile } from '@/api/modules/files';
import LayoutContent from '@/layout/layout-content.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';

View file

@ -8,9 +8,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{
label: 'MySQL',

View file

@ -144,8 +144,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import OperateDialog from '@/views/database/mysql/create/index.vue';
import DeleteDialog from '@/views/database/mysql/delete/index.vue';
import PasswordDialog from '@/views/database/mysql/password/index.vue';

View file

@ -110,7 +110,6 @@
<script lang="ts" setup>
import { FormInstance } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue';
import ContainerLog from '@/components/container-log/index.vue';
import Status from '@/views/database/mysql/setting/status/index.vue';
import Variables from '@/views/database/mysql/setting/variables/index.vue';

View file

@ -57,7 +57,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Setting from '@/views/database/redis/setting/index.vue';
import Password from '@/views/database/redis/password/index.vue';
import Terminal from '@/components/terminal/index.vue';

View file

@ -131,7 +131,6 @@ import { FormInstance } from 'element-plus';
import { nextTick, reactive, ref, shallowRef } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import LayoutContent from '@/layout/layout-content.vue';
import { oneDark } from '@codemirror/theme-one-dark';
import { LoadFile } from '@/api/modules/files';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';

View file

@ -112,7 +112,6 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { Database } from '@/api/interface/database';
import { redisPersistenceConf, updateRedisPersistenceConf } from '@/api/modules/database';

View file

@ -25,7 +25,7 @@
</el-alert>
<el-row :gutter="20" style="margin-top: 20px">
<el-col :span="16">
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
<CardWithHeader :header="$t('home.overview')" height="146px">
<template #body>
<div class="h-overview">
@ -67,7 +67,7 @@
<Status ref="statuRef" style="margin-top: -7px" />
</template>
</CardWithHeader>
<CardWithHeader :header="$t('menu.monitor')" style="margin-top: 20px">
<CardWithHeader :header="$t('menu.monitor')" style="margin-top: 20px; margin-bottom: 20px">
<template #header-r>
<el-radio-group
style="float: right; margin-left: 5px"
@ -118,12 +118,13 @@
<el-tag>{{ $t('monitor.read') }}: {{ currentChartInfo.ioReadBytes }} MB</el-tag>
<el-tag>{{ $t('monitor.write') }}: {{ currentChartInfo.ioWriteBytes }} MB</el-tag>
<el-tag>
{{ $t('home.rwPerSecond') }}: {{ currentChartInfo.ioCount }} {{ $t('home.time') }}
{{ $t('home.rwPerSecond') }}: {{ currentChartInfo.ioCount }}
{{ $t('home.time') }}
</el-tag>
<el-tag>{{ $t('home.ioDelay') }}: {{ currentChartInfo.ioTime }} ms</el-tag>
</div>
<div v-if="chartOption === 'io'" style="margin-top: 40px">
<div v-if="chartOption === 'io'" style="margin-top: 40px" class="mobile-monitor-chart">
<v-charts
height="305px"
id="ioChart"
@ -133,7 +134,7 @@
:dataZoom="true"
/>
</div>
<div v-if="chartOption === 'network'" style="margin-top: 40px">
<div v-if="chartOption === 'network'" style="margin-top: 40px" class="mobile-monitor-chart">
<v-charts
height="305px"
id="networkChart"
@ -147,7 +148,7 @@
</template>
</CardWithHeader>
</el-col>
<el-col :span="8">
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
<CardWithHeader :header="$t('home.systemInfo')">
<template #body>
<el-descriptions :column="1" class="h-systemInfo">
@ -223,7 +224,6 @@ import i18n from '@/lang';
import { Dashboard } from '@/api/interface/dashboard';
import { dateFormatForSecond, computeSize } from '@/utils/util';
import { useRouter } from 'vue-router';
import RouterButton from '@/components/router-button/index.vue';
import { loadBaseInfo, loadCurrentInfo } from '@/api/modules/dashboard';
import { getIOOptions, getNetworkOptions } from '@/api/modules/monitor';
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';

View file

@ -1,6 +1,6 @@
<template>
<el-row :gutter="10">
<el-col :span="6" align="center">
<el-col :xs="12" :sm="12" :md="6" :lg="6" :xl="6" align="center">
<el-popover placement="bottom" :width="300" trigger="hover">
<div>
<el-tooltip
@ -36,14 +36,14 @@
( {{ formatNumber(currentInfo.cpuUsed) }} / {{ currentInfo.cpuTotal }} ) Core
</span>
</el-col>
<el-col :span="6" align="center">
<el-col :xs="12" :sm="12" :md="6" :lg="6" :xl="6" align="center">
<div id="memory" class="chartClass"></div>
<span class="input-help">
( {{ formatNumber(currentInfo.memoryUsed / 1024 / 1024) }} /
{{ formatNumber(currentInfo.memoryTotal / 1024 / 1024) }} ) MB
</span>
</el-col>
<el-col :span="6" align="center">
<el-col :xs="12" :sm="12" :md="6" :lg="6" :xl="6" align="center">
<el-popover placement="bottom" :width="200" trigger="hover">
<el-tag class="tagClass">
{{ $t('home.loadAverage', [1]) }}: {{ formatNumber(currentInfo.load1) }}
@ -60,7 +60,16 @@
</el-popover>
<span class="input-help">{{ loadStatus(currentInfo.loadUsagePercent) }}</span>
</el-col>
<el-col :span="6" align="center" v-for="(item, index) of currentInfo.diskData" :key="index">
<el-col
:xs="12"
:sm="12"
:md="6"
:lg="6"
:xl="6"
align="center"
v-for="(item, index) of currentInfo.diskData"
:key="index"
>
<el-popover placement="bottom" :width="300" trigger="hover">
<el-row :gutter="5">
<el-col :span="12">

View file

@ -189,8 +189,6 @@ import { GetFilesList, DeleteFile, GetFileContent, ComputeDirSize, DownloadFile
import { computeSize, dateFormat, getIcon, getRandomStr } from '@/utils/util';
import { File } from '@/api/interface/file';
import { useDeleteData } from '@/hooks/use-delete-data';
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import i18n from '@/lang';
import CreateFile from './create/index.vue';
import ChangeRole from './change-role/index.vue';

View file

@ -9,8 +9,6 @@
<script lang="ts" setup>
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{

View file

@ -111,12 +111,10 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import OperatrDialog from '@/views/host/firewall/ip/operate/index.vue';
import FireRouter from '@/views/host/firewall/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import FireStatus from '@/views/host/firewall/status/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import { onMounted, reactive, ref } from 'vue';
import { batchOperateRule, searchFireRule, updateAddrRule } from '@/api/modules/host';
import { Host } from '@/api/interface/host';

View file

@ -143,12 +143,10 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import FireRouter from '@/views/host/firewall/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import OperatrDialog from '@/views/host/firewall/port/operate/index.vue';
import FireStatus from '@/views/host/firewall/status/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import { onMounted, reactive, ref } from 'vue';
import { batchOperateRule, searchFireRule, updatePortRule } from '@/api/modules/host';
import { Host } from '@/api/interface/host';

View file

@ -9,8 +9,6 @@
<script lang="ts" setup>
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{

View file

@ -50,7 +50,6 @@
<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';
import { FormInstance } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue';
import { cleanMonitors, getSettingInfo, getSystemAvailable, updateSetting } from '@/api/modules/setting';
import MonitorRouter from '@/views/host/monitor/index.vue';
import { useDeleteData } from '@/hooks/use-delete-data';

View file

@ -73,8 +73,6 @@
</template>
<script setup lang="ts">
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { Command } from '@/api/interface/command';
import { addCommand, editCommand, deleteCommand, getCommandPage } from '@/api/modules/host';
import { reactive, ref } from 'vue';

View file

@ -78,11 +78,9 @@
</template>
<script setup lang="ts">
import LayoutContent from '@/layout/layout-content.vue';
import GroupDialog from '@/components/group/index.vue';
import GroupChangeDialog from '@/views/host/terminal/host/change-group/index.vue';
import OperateDialog from '@/views/host/terminal/host/operate/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { deleteHost, searchHosts } from '@/api/modules/host';
import { GetGroupList } from '@/api/modules/group';
import { reactive, ref } from 'vue';

View file

@ -9,8 +9,6 @@
<script lang="ts" setup>
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{

View file

@ -73,10 +73,8 @@
</template>
<script setup lang="ts">
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import { dateFormat } from '@/utils/util';
import { cleanLogs, getLoginLogs } from '@/api/modules/log';
import { onMounted, reactive, ref } from '@vue/runtime-core';

View file

@ -105,11 +105,9 @@
</template>
<script setup lang="ts">
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { dateFormat } from '@/utils/util';
import LayoutContent from '@/layout/layout-content.vue';
import { cleanLogs, getOperationLogs } from '@/api/modules/log';
import { onMounted, reactive, ref } from '@vue/runtime-core';
import i18n from '@/lang';

View file

@ -39,7 +39,6 @@
<script setup lang="ts">
import { Codemirror } from 'vue-codemirror';
import LayoutContent from '@/layout/layout-content.vue';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { nextTick, onMounted, ref, shallowRef } from 'vue';

View file

@ -35,7 +35,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import { getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
import { onMounted, ref } from 'vue';
import SystemUpgrade from '@/components/system-upgrade/index.vue';

View file

@ -270,7 +270,6 @@
<script setup lang="ts">
import { dateFormat } from '@/utils/util';
import { onMounted, ref } from 'vue';
import LayoutContent from '@/layout/layout-content.vue';
import { getBackupList, deleteBackup } from '@/api/modules/setting';
import DialogOperate from '@/views/setting/backup-account/operate/index.vue';
import { Backup } from '@/api/interface/backup';

View file

@ -9,8 +9,6 @@
<script lang="ts" setup>
import i18n from '@/lang';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{

View file

@ -99,7 +99,6 @@
<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from 'vue';
import { ElForm } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue';
import { getSettingInfo, updateSetting, getSystemAvailable } from '@/api/modules/setting';
import { GlobalStore } from '@/store';
import { useI18n } from 'vue-i18n';

View file

@ -155,7 +155,6 @@
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { ElForm, ElMessageBox } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue';
import PortSetting from '@/views/setting/safe/port/index.vue';
import SSLSetting from '@/views/setting/safe/ssl/index.vue';
import MfaSetting from '@/views/setting/safe/mfa/index.vue';

View file

@ -146,7 +146,6 @@
</template>
<script setup lang="ts">
import ComplexTable from '@/components/complex-table/index.vue';
import TableSetting from '@/components/table-setting/index.vue';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { snapshotCreate, searchSnapshotPage, snapshotDelete, updateSnapshotDescription } from '@/api/modules/setting';
@ -157,7 +156,6 @@ import { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { Setting } from '@/api/interface/setting';
import LayoutContent from '@/layout/layout-content.vue';
import RecoverStatus from '@/views/setting/snapshot/status/index.vue';
import SnapshotImport from '@/views/setting/snapshot/import/index.vue';
import { getBackupList } from '@/api/modules/setting';

View file

@ -74,9 +74,6 @@ import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { Runtime } from '@/api/interface/runtime';
import { DeleteRuntime, SearchRuntimes } from '@/api/modules/runtime';
import { dateFormat, toLowerCase } from '@/utils/util';
import RouterButton from '@/components/router-button/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import CreateRuntime from '@/views/website/runtime/create/index.vue';
import Status from '@/components/status/index.vue';
import i18n from '@/lang';

View file

@ -24,7 +24,6 @@
import DrawerHeader from '@/components/drawer-header/index.vue';
import { Website } from '@/api/interface/website';
import { DeleteAcmeAccount, SearchAcmeAccount } from '@/api/modules/website';
import ComplexTable from '@/components/complex-table/index.vue';
import { useDeleteData } from '@/hooks/use-delete-data';
import i18n from '@/lang';
import { reactive, ref } from 'vue';

View file

@ -30,7 +30,6 @@
<script lang="ts" setup>
import DrawerHeader from '@/components/drawer-header/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import Create from './create/index.vue';
import { Website } from '@/api/interface/website';
import { DeleteDnsAccount, SearchDnsAccount } from '@/api/modules/website';

View file

@ -84,9 +84,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { onMounted, reactive, ref } from 'vue';
import { DeleteSSL, SearchSSL, UpdateSSL } from '@/api/modules/website';
import DnsAccount from './dns-account/index.vue';

View file

@ -16,7 +16,6 @@
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import Domain from './create/index.vue';
import { Website } from '@/api/interface/website';
import { DeleteDomain, GetWebsite, ListDomains } from '@/api/modules/website';

View file

@ -46,7 +46,6 @@
</template>
<script setup lang="ts">
import LayoutContent from '@/layout/layout-content.vue';
import { onMounted, ref, watch } from 'vue';
import Basic from './basic/index.vue';
import Safety from './safety/index.vue';

View file

@ -34,7 +34,6 @@
import { Website } from '@/api/interface/website';
import { GetWafConfig, UpdateWafEnable } from '@/api/modules/website';
import { computed, onMounted, reactive, ref } from 'vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { SaveFileContent } from '@/api/modules/files';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';

View file

@ -34,7 +34,6 @@
import { Website } from '@/api/interface/website';
import { GetWafConfig, UpdateWafEnable } from '@/api/modules/website';
import { computed, onMounted, reactive, ref } from 'vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { SaveFileContent } from '@/api/modules/files';
import i18n from '@/lang';
import { checkIp } from '@/utils/util';

View file

@ -49,7 +49,6 @@
import { Website } from '@/api/interface/website';
import { GetWafConfig, UpdateWafEnable } from '@/api/modules/website';
import { computed, onMounted, reactive, ref } from 'vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { SaveFileContent } from '@/api/modules/files';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';

View file

@ -165,12 +165,9 @@
<script lang="ts" setup>
import Tooltip from '@/components/tooltip/index.vue';
import LayoutContent from '@/layout/layout-content.vue';
import RouterButton from '@/components/router-button/index.vue';
import Backups from '@/components/backup/index.vue';
import UploadDialog from '@/components/upload/index.vue';
import DefaultServer from '@/views/website/website/default/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { onMounted, reactive, ref } from '@vue/runtime-core';
import CreateWebSite from './create/index.vue';
import DeleteWebsite from './delete/index.vue';

View file

@ -24,7 +24,6 @@
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Source from './source/index.vue';
import { nextTick, ref } from 'vue';
import ContainerLog from '@/components/container-log/index.vue';

View file

@ -39,7 +39,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
host: '0.0.0.0',
proxy: {
'/api/v1': {
target: 'http://localhost:9999/',
target: 'http://43.142.178.16:9999/',
changeOrigin: true,
ws: true,
},