mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 16:29:17 +08:00
feat: 应用商店兼容移动端 (#1119)
#### 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:
parent
13abe8cb66
commit
f7c76c012f
@ -1,82 +0,0 @@
|
||||
<template>
|
||||
<Layout v-loading="loading" :element-loading-text="loadinText" fullscreen>
|
||||
<template #menu v-if="!globalStore.isFullScreen">
|
||||
<Menu></Menu>
|
||||
</template>
|
||||
<template #footer v-if="!globalStore.isFullScreen">
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Layout from '@/layout/index.vue';
|
||||
import Footer from './footer/index.vue';
|
||||
import Menu from './menu/index.vue';
|
||||
import { onMounted, computed, ref, watch, onBeforeUnmount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { useTheme } from '@/hooks/use-theme';
|
||||
import { getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
|
||||
|
||||
const i18n = useI18n();
|
||||
const loading = ref(false);
|
||||
const loadinText = ref();
|
||||
const globalStore = GlobalStore();
|
||||
const themeConfig = computed(() => globalStore.themeConfig);
|
||||
const { switchDark } = useTheme();
|
||||
|
||||
let timer: NodeJS.Timer | null = null;
|
||||
|
||||
watch(
|
||||
() => globalStore.isLoading,
|
||||
() => {
|
||||
if (globalStore.isLoading) {
|
||||
loadStatus();
|
||||
} else {
|
||||
loading.value = globalStore.isLoading;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const loadDataFromDB = async () => {
|
||||
const res = await getSettingInfo();
|
||||
document.title = res.data.panelName;
|
||||
i18n.locale.value = res.data.language;
|
||||
i18n.warnHtmlMessage = false;
|
||||
globalStore.updateLanguage(res.data.language);
|
||||
globalStore.setThemeConfig({ ...themeConfig.value, theme: res.data.theme });
|
||||
globalStore.setThemeConfig({ ...themeConfig.value, panelName: res.data.panelName });
|
||||
switchDark();
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
loading.value = globalStore.isLoading;
|
||||
loadinText.value = globalStore.loadingText;
|
||||
if (loading.value) {
|
||||
timer = setInterval(async () => {
|
||||
await getSystemAvailable()
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
location.reload();
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
location.reload();
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
}, 1000 * 10);
|
||||
}
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
loadDataFromDB();
|
||||
});
|
||||
</script>
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper">
|
||||
<div :class="classObj" class="app-wrapper" v-loading="loading" :element-loading-text="loadinText" fullscreen>
|
||||
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
|
||||
<div class="app-sidebar">
|
||||
<div class="app-sidebar" v-if="!globalStore.isFullScreen">
|
||||
<Sidebar />
|
||||
</div>
|
||||
|
||||
@ -9,23 +9,34 @@
|
||||
<mobile-header v-if="classObj.mobile" />
|
||||
<app-main class="app-main" />
|
||||
|
||||
<Footer class="app-footer" />
|
||||
<Footer class="app-footer" v-if="!globalStore.isFullScreen" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { onMounted, computed, ref, watch, onBeforeUnmount } 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';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useTheme } from '@/hooks/use-theme';
|
||||
import { getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
|
||||
useResize();
|
||||
|
||||
const menuStore = MenuStore();
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
const loading = ref(false);
|
||||
const loadinText = ref();
|
||||
const themeConfig = computed(() => globalStore.themeConfig);
|
||||
const { switchDark } = useTheme();
|
||||
|
||||
let timer: NodeJS.Timer | null = null;
|
||||
|
||||
const classObj = computed(() => {
|
||||
return {
|
||||
hideSidebar: menuStore.isCollapse,
|
||||
@ -37,6 +48,58 @@ const classObj = computed(() => {
|
||||
const handleClickOutside = () => {
|
||||
menuStore.closeSidebar(false);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => globalStore.isLoading,
|
||||
() => {
|
||||
if (globalStore.isLoading) {
|
||||
loadStatus();
|
||||
} else {
|
||||
loading.value = globalStore.isLoading;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const loadDataFromDB = async () => {
|
||||
const res = await getSettingInfo();
|
||||
document.title = res.data.panelName;
|
||||
i18n.locale.value = res.data.language;
|
||||
i18n.warnHtmlMessage = false;
|
||||
globalStore.updateLanguage(res.data.language);
|
||||
globalStore.setThemeConfig({ ...themeConfig.value, theme: res.data.theme });
|
||||
globalStore.setThemeConfig({ ...themeConfig.value, panelName: res.data.panelName });
|
||||
switchDark();
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
loading.value = globalStore.isLoading;
|
||||
loadinText.value = globalStore.loadingText;
|
||||
if (loading.value) {
|
||||
timer = setInterval(async () => {
|
||||
await getSystemAvailable()
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
location.reload();
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
location.reload();
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
}, 1000 * 10);
|
||||
}
|
||||
};
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
loadDataFromDB();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -6,4 +6,32 @@
|
||||
.mobile-monitor-chart {
|
||||
margin-top: 20px !important;
|
||||
}
|
||||
.search-button {
|
||||
float: none !important;
|
||||
.table-button {
|
||||
display: inline-flex !important;
|
||||
}
|
||||
}
|
||||
|
||||
.app-card {
|
||||
.app-button {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
.install-card .a-detail {
|
||||
.d-name {
|
||||
height: auto !important;
|
||||
.h-button {
|
||||
float: none !important;
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
.d-button {
|
||||
min-width: auto !important;
|
||||
}
|
||||
.d-description {
|
||||
display: block !important;
|
||||
overflow: inherit !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<LayoutContent v-loading="loading" v-if="!showDetail" :title="$t('app.app')">
|
||||
<template #toolbar>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="20">
|
||||
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
|
||||
<el-button
|
||||
class="tag-button"
|
||||
:class="activeTag === 'all' ? '' : 'no-active'"
|
||||
@ -24,7 +24,7 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
v-model="req.name"
|
||||
@ -45,11 +45,11 @@
|
||||
</template>
|
||||
<template #main>
|
||||
<el-row :gutter="5">
|
||||
<el-col v-for="(app, index) in apps" :key="index" :xs="12" :sm="12" :md="8" :lg="8" :xl="8">
|
||||
<el-col v-for="(app, index) in apps" :key="index" :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
||||
<div class="app-card">
|
||||
<el-card class="e-card">
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="5" :sm="5" :md="6" :lg="6" :xl="5">
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="8" :sm="5" :md="6" :lg="6" :xl="5">
|
||||
<div class="app-icon">
|
||||
<el-avatar
|
||||
shape="square"
|
||||
@ -58,7 +58,7 @@
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="19" :sm="19" :md="18" :lg="18" :xl="19">
|
||||
<el-col :xs="16" :sm="19" :md="18" :lg="18" :xl="19">
|
||||
<div class="app-content">
|
||||
<div class="app-header">
|
||||
<span class="app-title">{{ app.name }}</span>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<LayoutContent v-loading="loading || syncLoading" :title="activeName">
|
||||
<template #toolbar>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="20">
|
||||
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
|
||||
<div>
|
||||
<el-button
|
||||
class="tag-button"
|
||||
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
class="table-button"
|
||||
@ -68,7 +68,7 @@
|
||||
>
|
||||
<div class="install-card">
|
||||
<el-card class="e-card">
|
||||
<el-row :gutter="24">
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="3" :sm="3" :md="3" :lg="4" :xl="4">
|
||||
<div class="icon">
|
||||
<el-avatar
|
||||
@ -78,7 +78,7 @@
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="21" :sm="21" :md="21" :lg="20" :xl="20">
|
||||
<el-col :xs="24" :sm="21" :md="21" :lg="20" :xl="20">
|
||||
<div class="a-detail">
|
||||
<div class="d-name">
|
||||
<el-button link type="info">
|
||||
|
@ -20,7 +20,7 @@
|
||||
</template>
|
||||
<template v-if="nginxIsExist && !openNginxConfig" #toolbar>
|
||||
<el-row :class="{ mask: nginxStatus != 'Running' }">
|
||||
<el-col :span="20">
|
||||
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
|
||||
<el-button type="primary" @click="openCreate">
|
||||
{{ $t('website.create') }}
|
||||
</el-button>
|
||||
@ -31,7 +31,7 @@
|
||||
{{ $t('website.defaultServer') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
v-model="req.name"
|
||||
|
Loading…
x
Reference in New Issue
Block a user