Refactor app configure view selector to cover mobile better
This commit is contained in:
@@ -5,7 +5,7 @@ const i18n = useI18n();
|
||||
const t = i18n.t;
|
||||
|
||||
import { ref, onMounted, onBeforeUnmount, useTemplateRef } from 'vue';
|
||||
import { Button, ButtonGroup, SingleSelect, InputDialog, ProgressBar } from '@cloudron/pankow';
|
||||
import { Button, ButtonGroup, ProgressBar } from '@cloudron/pankow';
|
||||
import PostInstallDialog from '../components/PostInstallDialog.vue';
|
||||
import SftpInfoDialog from '../components/SftpInfoDialog.vue';
|
||||
import Access from '../components/app/Access.vue';
|
||||
@@ -45,21 +45,6 @@ const hasEmail = ref(false);
|
||||
const busyStopTask = ref(false);
|
||||
const postInstallDialog = useTemplateRef('postInstallDialog');
|
||||
const sftpInfoDialog = useTemplateRef('sftpInfoDialog');
|
||||
const inputDialog = useTemplateRef('inputDialog');
|
||||
|
||||
function onSetView(newView) {
|
||||
if (!isViewEnabled(newView, app.value.error?.details.installationState)) {
|
||||
if (!currentView.value) {
|
||||
currentView.value = 'info';
|
||||
window.location.hash = `/app/${id.value}/info`;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
currentView.value = newView;
|
||||
window.location.hash = `/app/${id.value}/${newView}`;
|
||||
}
|
||||
|
||||
let refreshTimer = null;
|
||||
async function refresh() {
|
||||
@@ -186,7 +171,18 @@ function hashChange() {
|
||||
const parts = tmp.split('/');
|
||||
if (parts.length !== 2) return;
|
||||
|
||||
onSetView(parts[1] || 'info');
|
||||
const newView = parts[1] || 'info';
|
||||
if (!isViewEnabled(newView, app.value.error?.details.installationState)) {
|
||||
if (!currentView.value) {
|
||||
currentView.value = 'info';
|
||||
window.location.hash = `/app/${id.value}/info`;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
currentView.value = newView;
|
||||
window.location.hash = `/app/${id.value}/${newView}`;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -205,23 +201,32 @@ onMounted(async () => {
|
||||
if (app.value.manifest.addons.turn && app.value.manifest.addons.turn.optional) hasServices = true;
|
||||
if (app.value.manifest.addons.redis && app.value.manifest.addons.redis.optional) hasServices = true;
|
||||
|
||||
views.value.push({ enabled: true, id: 'info', display: t('app.infoTabTitle'), });
|
||||
views.value.push({ enabled: true, id: 'display', display: t('app.displayTabTitle'), });
|
||||
if (app.value.accessLevel === 'admin') views.value.push({ enabled: true, id: 'location', display: t('app.locationTabTitle'), });
|
||||
if (app.value.type === APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'proxy', display: 'Proxy', });
|
||||
if (app.value.accessLevel === 'admin') views.value.push({ enabled: true, id: 'access', display: t('app.accessControlTabTitle'), });
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'resources', display: t('app.resourcesTabTitle'), });
|
||||
if (app.value.type !== APP_TYPES.PROXIED && hasServices) views.value.push({ enabled: true, id: 'services', display: t('app.servicesTabTitle'), });
|
||||
if (app.value.accessLevel === 'admin' && app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'storage', display: t('app.storageTabTitle'), });
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'graphs', display: t('app.graphsTabTitle'), });
|
||||
views.value.push({ enabled: true, id: 'security', display: t('app.securityTabTitle'), });
|
||||
if (app.value.accessLevel === 'admin' && hasEmail.value && app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'email', display: t('app.emailTabTitle'), });
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'cron', display: t('app.cronTabTitle'), });
|
||||
views.value.push({ enabled: true, id: 'updates', display: t('app.updatesTabTitle'), });
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push({ enabled: true, id: 'backups', display: t('app.backupsTabTitle'), });
|
||||
views.value.push({ enabled: true, id: 'repair', display: t('app.repairTabTitle'), });
|
||||
views.value.push({ enabled: true, id: 'eventlog', display: t('app.eventlogTabTitle'), });
|
||||
if (app.value.accessLevel === 'admin') views.value.push({ enabled: true, id: 'uninstall', display: t('app.uninstallTabTitle'), });
|
||||
function buildMenuItem(id, label) {
|
||||
return {
|
||||
id: id,
|
||||
disabled: () => !isViewEnabled(id, app.value.error?.details.installationState),
|
||||
label: label,
|
||||
href: `/#/app/${id.value}/${id}`,
|
||||
};
|
||||
}
|
||||
|
||||
views.value.push(buildMenuItem('info', t('app.infoTabTitle')));
|
||||
views.value.push(buildMenuItem('display', t('app.displayTabTitle')));
|
||||
if (app.value.accessLevel === 'admin') views.value.push(buildMenuItem('location', t('app.locationTabTitle')));
|
||||
if (app.value.type === APP_TYPES.PROXIED) views.value.push(buildMenuItem('proxy', 'Proxy'));
|
||||
if (app.value.accessLevel === 'admin') views.value.push(buildMenuItem('access', t('app.accessControlTabTitle')));
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('resources', t('app.resourcesTabTitle')));
|
||||
if (app.value.type !== APP_TYPES.PROXIED && hasServices) views.value.push(buildMenuItem('services', t('app.servicesTabTitle')));
|
||||
if (app.value.accessLevel === 'admin' && app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('storage', t('app.storageTabTitle')));
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('graphs', t('app.graphsTabTitle')));
|
||||
views.value.push(buildMenuItem('security', t('app.securityTabTitle')));
|
||||
if (app.value.accessLevel === 'admin' && hasEmail.value && app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('email', t('app.emailTabTitle')));
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('cron', t('app.cronTabTitle')));
|
||||
views.value.push(buildMenuItem('updates', t('app.updatesTabTitle')));
|
||||
if (app.value.type !== APP_TYPES.PROXIED) views.value.push(buildMenuItem('backups', t('app.backupsTabTitle')));
|
||||
views.value.push(buildMenuItem('repair', t('app.repairTabTitle')));
|
||||
views.value.push(buildMenuItem('eventlog', t('app.eventlogTabTitle')));
|
||||
if (app.value.accessLevel === 'admin') views.value.push(buildMenuItem('uninstall', t('app.uninstallTabTitle')));
|
||||
|
||||
hashChange();
|
||||
window.addEventListener('hashchange', hashChange);
|
||||
@@ -240,7 +245,6 @@ onBeforeUnmount(() => {
|
||||
<div class="configure-outer">
|
||||
<PostInstallDialog ref="postInstallDialog"/>
|
||||
<SftpInfoDialog ref="sftpInfoDialog"/>
|
||||
<InputDialog ref="inputDialog"/>
|
||||
|
||||
<div class="configure-inner" v-if="!busy">
|
||||
<div class="titlebar">
|
||||
@@ -255,9 +259,9 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="titlebar-toolbar">
|
||||
<SingleSelect class="pankow-no-desktop" v-model="currentView" :options="views" optionKey="id" optionLabel="display" @select="onSetView"/>
|
||||
<div style="display: flex; gap: 10px">
|
||||
<Button v-if="app.taskId" danger tool plain icon="fa-solid fa-xmark" v-tooltip="'Cancel Task'" :loading="busyStopTask" :disabled="busyStopTask" @click="onStopAppTask()"/>
|
||||
<Button :menu="views" class="pankow-no-desktop" tool>{{ views.find(v => v.id === currentView).label }}</Button>
|
||||
<ButtonGroup>
|
||||
<Button secondary tool :href="`/logs.html?appId=${app.id}`" target="_blank" v-tooltip="$t('app.logsActionTooltip')" icon="fa-solid fa-align-left" />
|
||||
<Button secondary tool v-if="app.type !== APP_TYPES.PROXIED" :href="`/terminal.html?id=${app.id}`" target="_blank" v-tooltip="$t('app.terminalActionTooltip')" icon="fa fa-terminal" />
|
||||
@@ -273,8 +277,8 @@ onBeforeUnmount(() => {
|
||||
<div class="configure-body">
|
||||
<div class="configure-menu pankow-no-mobile">
|
||||
<div v-for="view in views" :key="view.id" class="configure-menu-item" :active="currentView === view.id ? true : null" :disabled="isViewEnabled(view.id, app.error?.details.installationState) ? null : true">
|
||||
<a v-if="isViewEnabled(view.id, app.error?.details.installationState)" :href="`/#/app/${app.id}/${view.id}`">{{ view.display }}</a>
|
||||
<span v-else>{{ view.display }}</span>
|
||||
<a v-if="isViewEnabled(view.id, app.error?.details.installationState)" :href="`/#/app/${app.id}/${view.id}`">{{ view.label }}</a>
|
||||
<span v-else>{{ view.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="configure-content">
|
||||
|
||||
Reference in New Issue
Block a user