Move status indicator code into a shared component

This commit is contained in:
Johannes Zellner
2025-03-24 16:58:29 +01:00
parent b9d9797734
commit 3a323551eb
7 changed files with 67 additions and 34 deletions
+2 -1
View File
@@ -4,6 +4,7 @@ import { ref, onMounted, useTemplateRef } from 'vue';
import { marked } from 'marked';
import { Button } from 'pankow';
import Section from '../components/Section.vue';
import StateLED from '../components/StateLED.vue';
import BackupDialog from '../components/BackupDialog.vue';
import BackupSchedule from '../components/BackupSchedule.vue';
import BackupList from '../components/BackupList.vue';
@@ -87,7 +88,7 @@ onMounted(async () => {
<div class="info-value">
<span v-show="config.provider === 'filesystem'">{{ config.backupFolder }}</span>
<span v-show="mountlike(config.provider)">
<i class="fa fa-circle" :style="{ color: mountStatus.state === 'active' ? '#27CE65' : '#d9534f' }" v-show="mountStatus" v-tooltip="mountStatus.message"></i>
<StateLED v-if="mountStatus" :state="mountStatus.state === 'active' ? 'success' : 'danger'" v-tooltip="mountStatus.message"/>
<span v-show="config.provider === 'disk' || config.provider === 'filesystem' || config.provider === 'ext4' || config.provider === 'xfs' || config.provider === 'mountpoint'">{{ mountOptions.diskPath || config.mountPoint }}{{ (config.prefix ? '/' : '') + config.prefix }}</span>
<span v-show="config.provider === 'cifs' || config.provider === 'nfs' || config.provider === 'sshfs'">{{ mountOptions.host }}:{{ mountOptions.remoteDir }}{{ (config.prefix ? '/' : '') + config.prefix }}</span>
</span>
+2 -2
View File
@@ -8,6 +8,7 @@ import { ref, onMounted, useTemplateRef } from 'vue';
import { Button, TableView, ProgressBar, InputDialog, Dialog, FormGroup, TextInput, InputGroup, Switch, ButtonGroup, SingleSelect } from 'pankow';
import { prettyDecimalSize } from 'pankow/utils';
import Section from '../components/Section.vue';
import StateLED from '../components/StateLED.vue';
import SettingsItem from '../components/SettingsItem.vue';
import DomainsModel from '../models/DomainsModel.js';
import MailModel from '../models/MailModel.js';
@@ -385,8 +386,7 @@ onMounted(async () => {
<Section>
<TableView :columns="columns" :model="domains" :busy="busy">
<template #status="domain">
<i class="fa fa-circle" :class="{ 'status-active': domain.status, 'status-error': !domain.status }" v-if="domain.statusCheckDone"></i>
<i class="fa fa-circle-notch fa-spin" v-if="!domain.statusCheckDone"></i>
<StateLED :busy="!domain.statusCheckDone" :state="domain.status ? 'success' : 'danger'"/>
</template>
<template #domain="domain">
<a :href="`/#/email/${domain.domain}`">{{ domain.domain }}</a>
+21 -16
View File
@@ -9,6 +9,7 @@ import { Button, TableView, ProgressBar, ButtonGroup, FormGroup, Checkbox, Dialo
import { prettyBinarySize } from 'pankow/utils';
import { each } from 'async';
import Section from '../components/Section.vue';
import StateLED from '../components/StateLED.vue';
import ServicesModel from '../models/ServicesModel.js';
import SystemModel from '../models/SystemModel.js';
import AppsModel from '../models/AppsModel.js';
@@ -122,7 +123,7 @@ function onResetToDefaults() {
editMemoryLimit.value = editService.value.defaultMemoryLimit;
}
async function onEditConfirm() {
async function onEditSubmit() {
editBusy.value = true;
const [error] = await servicesModel.update(editService.value.id, parseInt(editMemoryLimit.value), editRecoveryMode.value);
@@ -133,11 +134,27 @@ async function onEditConfirm() {
return;
}
setTimeout(() => refresh(editService.value.id), 2000);
await refresh(editService.value.id);
editBusy.value = false;
dialog.value.close();
}
function state(service) {
if (service.status === 'active') return 'success';
else if (service.status === 'starting' && service.config.recoveryMode) return '';
else if (service.status === 'starting') return 'warning';
else return 'danger';
}
function stateTooltip(service) {
if (!service.status) return '';
if (service.status === 'active') return 'Active';
else if (service.status === 'starting' && service.config.recoveryMode) return 'Recovery mode';
else if (service.status === 'starting') return 'Starting';
else return service.status;
}
onMounted(async () => {
await refreshAll();
@@ -156,7 +173,7 @@ onMounted(async () => {
:confirm-label="$t('main.dialog.save')"
:reject-label="$t('main.dialog.cancel')"
reject-style="secondary"
@confirm="onEditConfirm()"
@confirm="onEditSubmit()"
>
<p class="has-error text-center" v-show="editError">{{ editError }}</p>
@@ -183,19 +200,7 @@ onMounted(async () => {
<TableView :columns="columns" :model="servicesArray">
<template #status="service">
<span v-show="service.status">
<span v-if="service.status === 'active'">
<i class="fa fa-circle status-active" v-tooltip="'active'"></i>
</span>
<span v-else-if="service.status === 'starting'">
<i class="fa fa-circle status-starting" v-tooltip="'starting'" v-show="!service.config.recoveryMode"></i>
<i class="fa fa-circle status-inactive" v-tooltip="'recovery mode'" v-show="service.config.recoveryMode"></i>
</span>
<span v-else>
<i class="fa fa-circle status-error" uib-tooltip="{{ service.status }}"></i>
</span>
</span>
<i class="fa fa-circle-notch fa-spin" v-show="!service.status"></i>
<StateLED :busy="!service.status" :state="state(service)" :title="stateTooltip(service)"/>
</template>
<template #memoryPercent="service">
<ProgressBar :value="service.memoryPercent" v-show="service.memoryPercent" />
-1
View File
@@ -49,7 +49,6 @@ onMounted(async () => {
</Section>
<Section :title="$t('support.remoteSupport.title')">
<h2 class="text-center" v-show="!ready"><i class="fa fa-circle-notch fa-spin"></i></h2>
<div v-show="ready">
<p>{{ $t('support.remoteSupport.description') }}</p>
<b>{{ $t('support.remoteSupport.warning') }}</b>
+6 -3
View File
@@ -7,6 +7,7 @@ const t = i18n.t;
import { computed, ref, useTemplateRef, onMounted } from 'vue';
import { Button, ButtonGroup, Checkbox, Dialog, Dropdown, FormGroup, InputDialog, NumberInput, PasswordInput, TableView, TextInput } from 'pankow';
import Section from '../components/Section.vue';
import StateLED from '../components/StateLED.vue';
import VolumesModel from '../models/VolumesModel.js';
const volumesModel = VolumesModel.create();
@@ -86,14 +87,16 @@ async function refresh() {
const [error, result] = await volumesModel.list();
if (error) return console.error(error);
result.forEach(v => { v.busy = true; });
volumes.value = result;
busy.value = false;
for (const v of volumes.value) {
const status = await volumesModel.getStatus(v.id);
v.state = status.state;
v.state = status.state === 'inactive' ? 'danger' : (status.state === 'active' ? 'success' : '');
v.message = status.message;
v.busy = false;
}
};
@@ -285,8 +288,8 @@ onMounted(async () =>{
{{ (volume.mountType === 'mountpoint' || volume.mountType === 'filesystem') ? volume.hostPath : (volume.mountOptions.host || volume.mountOptions.diskPath || volume.hostPath) + (volume.mountOptions.remoteDir || '') }}
</template>
<template #status="volume">
<div style="text-align: center;" v-tooltip="volume.message">
<i class="fa fa-circle" :style="{ color: volume.state === 'active' ? '#27CE65' : '#d9534f' }"></i>
<div style="text-align: center;" :title="volume.message">
<StateLED :busy="volume.busy" :state="volume.state"/>
</div>
</template>
<template #actions="volume">