feat: add option to hide other Klipper & Moonraker instances (#2029)
This commit is contained in:
parent
a0f003c9eb
commit
34f3f08bd6
@ -28,6 +28,10 @@
|
||||
min-width: auto !important;
|
||||
}
|
||||
|
||||
.minHeight30 {
|
||||
min-height: 30px !important;
|
||||
}
|
||||
|
||||
.minHeight36 {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
@ -1,9 +1,3 @@
|
||||
<style scoped>
|
||||
.minheight30 {
|
||||
min-height: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<v-menu v-model="showMenu" bottom left :offset-y="true" :close-on-content-click="false">
|
||||
@ -18,7 +12,7 @@
|
||||
{{ $t('App.TopCornerMenu.KlipperControl') }}
|
||||
</v-subheader>
|
||||
<v-list-item
|
||||
class="minheight30 pr-2"
|
||||
class="minHeight30 pr-2"
|
||||
link
|
||||
@click="checkDialog(klipperRestart, 'klipper', 'restart')">
|
||||
<v-list-item-title>{{ $t('App.TopCornerMenu.KlipperRestart') }}</v-list-item-title>
|
||||
@ -27,7 +21,7 @@
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
class="minheight30 pr-2"
|
||||
class="minHeight30 pr-2"
|
||||
link
|
||||
@click="checkDialog(klipperFirmwareRestart, 'klipper', 'firmwareRestart')">
|
||||
<v-list-item-title>{{ $t('App.TopCornerMenu.KlipperFirmwareRestart') }}</v-list-item-title>
|
||||
@ -37,42 +31,15 @@
|
||||
</v-list-item>
|
||||
</template>
|
||||
<template v-if="services.length">
|
||||
<v-divider v-if="klipperState !== 'disconnected'" class="mt-0"></v-divider>
|
||||
<v-divider v-if="klipperState !== 'disconnected'" class="mt-0" />
|
||||
<v-subheader class="pt-2" style="height: auto">
|
||||
{{ $t('App.TopCornerMenu.ServiceControl') }}
|
||||
</v-subheader>
|
||||
<v-list-item v-for="service in services" :key="service" class="minheight30 pr-2">
|
||||
<v-list-item-title>
|
||||
<v-tooltip left>
|
||||
<template #activator="{ on, attrs }">
|
||||
<span v-bind="attrs" v-on="on">
|
||||
{{ service.charAt(0).toUpperCase() + service.slice(1) }}
|
||||
</span>
|
||||
</template>
|
||||
<span>{{ getServiceState(service) }} ({{ getServiceSubState(service) }})</span>
|
||||
</v-tooltip>
|
||||
</v-list-item-title>
|
||||
<v-list-item-action class="my-0 d-flex flex-row" style="min-width: auto">
|
||||
<v-btn
|
||||
v-if="getServiceState(service) === 'inactive'"
|
||||
icon
|
||||
small
|
||||
@click="checkDialog(serviceStart, service, 'start')">
|
||||
<v-icon small>{{ mdiPlay }}</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-else icon small @click="checkDialog(serviceRestart, service, 'restart')">
|
||||
<v-icon small>{{ mdiRestart }}</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
icon
|
||||
small
|
||||
:disabled="getServiceState(service) === 'inactive' || service === 'moonraker'"
|
||||
:style="service === 'moonraker' ? 'visibility: hidden;' : ''"
|
||||
@click="checkDialog(serviceStop, service, 'stop')">
|
||||
<v-icon small>{{ mdiStop }}</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<top-corner-menu-service
|
||||
v-for="service in services"
|
||||
:key="service"
|
||||
:service="service"
|
||||
@close-menu="showMenu = false" />
|
||||
</template>
|
||||
<template v-if="powerDevices.length">
|
||||
<v-divider class="mt-0"></v-divider>
|
||||
@ -82,7 +49,7 @@
|
||||
<v-list-item
|
||||
v-for="(device, index) in powerDevices"
|
||||
:key="index"
|
||||
class="minheight30 pr-2"
|
||||
class="minHeight30 pr-2"
|
||||
:disabled="
|
||||
device.status === 'error' ||
|
||||
(device.locked_while_printing && ['printing', 'paused'].includes(printer_state))
|
||||
@ -98,13 +65,13 @@
|
||||
</template>
|
||||
<v-divider class="mt-0"></v-divider>
|
||||
<v-subheader class="pt-2" style="height: auto">{{ $t('App.TopCornerMenu.HostControl') }}</v-subheader>
|
||||
<v-list-item class="minheight30 pr-2" link @click="checkDialog(hostReboot, 'host', 'reboot')">
|
||||
<v-list-item class="minHeight30 pr-2" link @click="checkDialog(hostReboot, 'host', 'reboot')">
|
||||
<v-list-item-title>{{ $t('App.TopCornerMenu.Reboot') }}</v-list-item-title>
|
||||
<v-list-item-action class="my-0 d-flex flex-row" style="min-width: auto">
|
||||
<v-icon class="mr-2" small>{{ mdiPower }}</v-icon>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-list-item class="minheight30 pr-2" link @click="checkDialog(hostShutdown, 'host', 'shutdown')">
|
||||
<v-list-item class="minHeight30 pr-2" link @click="checkDialog(hostShutdown, 'host', 'shutdown')">
|
||||
<v-list-item-title>{{ $t('App.TopCornerMenu.Shutdown') }}</v-list-item-title>
|
||||
<v-list-item-action class="my-0 d-flex flex-row" style="min-width: auto">
|
||||
<v-icon class="mr-2" small>{{ mdiPower }}</v-icon>
|
||||
@ -133,35 +100,14 @@
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<v-dialog v-model="dialogConfirmation.show" width="400" :fullscreen="isMobile">
|
||||
<panel
|
||||
card-class="confirm-top-corner-menu-dialog"
|
||||
:icon="mdiAlert"
|
||||
:title="dialogConfirmation.title"
|
||||
:margin-bottom="false">
|
||||
<template #buttons>
|
||||
<v-btn icon tile @click="dialogConfirmation.show = false">
|
||||
<v-icon>{{ mdiCloseThick }}</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card-text class="pt-3">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<p class="body-2">{{ dialogConfirmation.description }}</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click="dialogConfirmation.show = false">
|
||||
{{ $t('App.TopCornerMenu.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn text color="error" @click="executeDialog">
|
||||
{{ dialogConfirmation.actionButtonText }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
<confirmation-dialog
|
||||
:show="dialogConfirmation.show"
|
||||
:title="dialogConfirmation.title"
|
||||
:text="dialogConfirmation.description"
|
||||
:action-button-text="dialogConfirmation.actionButtonText"
|
||||
:cancel-button-text="$t('App.TopCornerMenu.Cancel')"
|
||||
@action="executeDialog"
|
||||
@close="dialogConfirmation.show = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -171,17 +117,10 @@ import { Mixins } from 'vue-property-decorator'
|
||||
import BaseMixin from '@/components/mixins/base'
|
||||
import { ServerPowerStateDevice } from '@/store/server/power/types'
|
||||
import Panel from '@/components/ui/Panel.vue'
|
||||
import {
|
||||
mdiAlert,
|
||||
mdiCloseThick,
|
||||
mdiPowerStandby,
|
||||
mdiRestart,
|
||||
mdiPlay,
|
||||
mdiPower,
|
||||
mdiStop,
|
||||
mdiToggleSwitch,
|
||||
mdiToggleSwitchOff,
|
||||
} from '@mdi/js'
|
||||
import { mdiCloseThick, mdiPowerStandby, mdiRestart, mdiPower, mdiToggleSwitch, mdiToggleSwitchOff } from '@mdi/js'
|
||||
import TopCornerMenuService from '@/components/ui/TopCornerMenuService.vue'
|
||||
import ConfirmationDialog from '@/components/dialogs/ConfirmationDialog.vue'
|
||||
import ServiceMixins from '@/components/mixins/services'
|
||||
|
||||
interface dialogPowerDeviceChange {
|
||||
show: boolean
|
||||
@ -199,16 +138,13 @@ interface dialogConfirmation {
|
||||
}
|
||||
|
||||
@Component({
|
||||
components: { Panel },
|
||||
components: { ConfirmationDialog, TopCornerMenuService, Panel },
|
||||
})
|
||||
export default class TheTopCornerMenu extends Mixins(BaseMixin) {
|
||||
mdiAlert = mdiAlert
|
||||
export default class TheTopCornerMenu extends Mixins(BaseMixin, ServiceMixins) {
|
||||
mdiCloseThick = mdiCloseThick
|
||||
mdiPowerStandby = mdiPowerStandby
|
||||
mdiRestart = mdiRestart
|
||||
mdiPlay = mdiPlay
|
||||
mdiPower = mdiPower
|
||||
mdiStop = mdiStop
|
||||
mdiToggleSwitch = mdiToggleSwitch
|
||||
mdiToggleSwitchOff = mdiToggleSwitchOff
|
||||
|
||||
@ -229,12 +165,28 @@ export default class TheTopCornerMenu extends Mixins(BaseMixin) {
|
||||
}
|
||||
|
||||
get services() {
|
||||
const services =
|
||||
let services =
|
||||
this.$store.state.server.system_info?.available_services?.filter(
|
||||
(name: string) => name !== 'klipper_mcu'
|
||||
) ?? []
|
||||
services.sort()
|
||||
return services
|
||||
|
||||
if (this.hideOtherInstances && this.klipperInstance !== '') {
|
||||
services = services.filter(
|
||||
(name: string) =>
|
||||
(!name.toLowerCase().startsWith('klipper-') && name.toLowerCase() !== 'klipper') ||
|
||||
name === this.klipperInstance
|
||||
)
|
||||
}
|
||||
|
||||
if (this.hideOtherInstances && this.moonrakerInstance !== '') {
|
||||
services = services.filter(
|
||||
(name: string) =>
|
||||
(!name.toLowerCase().startsWith('moonraker-') && name.toLowerCase() !== 'moonraker') ||
|
||||
name === this.moonrakerInstance
|
||||
)
|
||||
}
|
||||
|
||||
return services.sort()
|
||||
}
|
||||
|
||||
get powerDevices() {
|
||||
@ -243,50 +195,37 @@ export default class TheTopCornerMenu extends Mixins(BaseMixin) {
|
||||
return devices.filter((device: ServerPowerStateDevice) => !device.device.startsWith('_'))
|
||||
}
|
||||
|
||||
get service_states() {
|
||||
return this.$store.state.server.system_info?.service_state ?? {}
|
||||
}
|
||||
|
||||
getServiceState(name: string) {
|
||||
if (name in this.service_states) return this.service_states[name].active_state
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
getServiceSubState(name: string) {
|
||||
if (name in this.service_states) return this.service_states[name].sub_state
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
checkDialog(executableFunction: any, serviceName: string, action: string) {
|
||||
if (this.printerIsPrinting) {
|
||||
this.dialogConfirmation.executableFunction = executableFunction
|
||||
this.dialogConfirmation.serviceName = serviceName
|
||||
if (!this.printerIsPrinting) {
|
||||
executableFunction(serviceName)
|
||||
return
|
||||
}
|
||||
|
||||
const actionUppercase = action.trim().charAt(0).toUpperCase() + action.trim().slice(1)
|
||||
let titleKey = 'App.TopCornerMenu.ConfirmationDialog.Title.Service' + actionUppercase
|
||||
let descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Service' + actionUppercase
|
||||
let buttonKey = 'App.TopCornerMenu.' + actionUppercase
|
||||
this.dialogConfirmation.executableFunction = executableFunction
|
||||
this.dialogConfirmation.serviceName = serviceName
|
||||
|
||||
if (serviceName === 'klipper' && ['stop', 'restart', 'firmwareRestart'].includes(action)) {
|
||||
titleKey =
|
||||
'App.TopCornerMenu.ConfirmationDialog.Title.' +
|
||||
(action !== 'stop' ? 'Klipper' : 'Service') +
|
||||
actionUppercase
|
||||
descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Klipper' + actionUppercase
|
||||
const actionUppercase = action.trim().charAt(0).toUpperCase() + action.trim().slice(1)
|
||||
let titleKey = 'App.TopCornerMenu.ConfirmationDialog.Title.Service' + actionUppercase
|
||||
let descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Service' + actionUppercase
|
||||
let buttonKey = 'App.TopCornerMenu.' + actionUppercase
|
||||
|
||||
if (action === 'firmwareRestart') buttonKey = 'App.TopCornerMenu.KlipperFirmwareRestart'
|
||||
} else if (serviceName === 'host') {
|
||||
titleKey = 'App.TopCornerMenu.ConfirmationDialog.Title.Host' + actionUppercase
|
||||
descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Host' + actionUppercase
|
||||
}
|
||||
if (serviceName === 'klipper' && ['stop', 'restart', 'firmwareRestart'].includes(action)) {
|
||||
titleKey =
|
||||
'App.TopCornerMenu.ConfirmationDialog.Title.' +
|
||||
(action !== 'stop' ? 'Klipper' : 'Service') +
|
||||
actionUppercase
|
||||
descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Klipper' + actionUppercase
|
||||
|
||||
this.dialogConfirmation.title = this.$t(titleKey).toString()
|
||||
this.dialogConfirmation.description = this.$t(descriptionKey).toString()
|
||||
this.dialogConfirmation.actionButtonText = this.$t(buttonKey).toString()
|
||||
this.dialogConfirmation.show = true
|
||||
} else executableFunction(serviceName)
|
||||
if (action === 'firmwareRestart') buttonKey = 'App.TopCornerMenu.KlipperFirmwareRestart'
|
||||
} else if (serviceName === 'host') {
|
||||
titleKey = 'App.TopCornerMenu.ConfirmationDialog.Title.Host' + actionUppercase
|
||||
descriptionKey = 'App.TopCornerMenu.ConfirmationDialog.Description.Host' + actionUppercase
|
||||
}
|
||||
|
||||
this.dialogConfirmation.title = this.$t(titleKey).toString()
|
||||
this.dialogConfirmation.description = this.$t(descriptionKey).toString()
|
||||
this.dialogConfirmation.actionButtonText = this.$t(buttonKey).toString()
|
||||
this.dialogConfirmation.show = true
|
||||
}
|
||||
|
||||
executeDialog() {
|
||||
@ -306,21 +245,6 @@ export default class TheTopCornerMenu extends Mixins(BaseMixin) {
|
||||
this.$socket.emit('printer.gcode.script', { script: 'FIRMWARE_RESTART' })
|
||||
}
|
||||
|
||||
serviceStart(service: string) {
|
||||
this.showMenu = false
|
||||
this.$socket.emit('machine.services.start', { service: service })
|
||||
}
|
||||
|
||||
serviceRestart(service: string) {
|
||||
this.showMenu = false
|
||||
this.$socket.emit('machine.services.restart', { service: service })
|
||||
}
|
||||
|
||||
serviceStop(service: string) {
|
||||
this.showMenu = false
|
||||
this.$socket.emit('machine.services.stop', { service: service })
|
||||
}
|
||||
|
||||
changeSwitch(device: ServerPowerStateDevice, value: string) {
|
||||
this.dialogPowerDeviceChange.device = device.device
|
||||
this.dialogPowerDeviceChange.value = value
|
||||
|
52
src/components/dialogs/ConfirmationDialog.vue
Normal file
52
src/components/dialogs/ConfirmationDialog.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<v-dialog :value="show" width="400" :fullscreen="isMobile">
|
||||
<panel card-class="confirm-top-corner-menu-dialog" :icon="mdiAlert" :title="title" :margin-bottom="false">
|
||||
<template #buttons>
|
||||
<v-btn icon tile @click="close">
|
||||
<v-icon>{{ mdiCloseThick }}</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card-text class="pt-3">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<p class="body-2">{{ text }}</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn text @click="close">{{ cancelButtonText }}</v-btn>
|
||||
<v-btn text color="error" @click="action">{{ actionButtonText }}</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import Component from 'vue-class-component'
|
||||
import Panel from '@/components/ui/Panel.vue'
|
||||
import { Mixins, Prop } from 'vue-property-decorator'
|
||||
import BaseMixin from '@/components/mixins/base'
|
||||
import { mdiAlert, mdiCloseThick } from '@mdi/js'
|
||||
|
||||
@Component({
|
||||
components: { Panel },
|
||||
})
|
||||
export default class ConfirmationDialog extends Mixins(BaseMixin) {
|
||||
mdiAlert = mdiAlert
|
||||
mdiCloseThick = mdiCloseThick
|
||||
|
||||
@Prop({ type: Boolean, required: true }) show!: boolean
|
||||
@Prop({ type: String, required: true }) title!: string
|
||||
@Prop({ type: String, required: true }) text!: string
|
||||
@Prop({ type: String, required: true }) actionButtonText!: string
|
||||
@Prop({ type: String, required: true }) cancelButtonText!: string
|
||||
|
||||
action() {
|
||||
this.$emit('action')
|
||||
}
|
||||
|
||||
close() {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
</script>
|
21
src/components/mixins/services.ts
Normal file
21
src/components/mixins/services.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
|
||||
@Component
|
||||
export default class ServiceMixins extends Vue {
|
||||
get hideOtherInstances() {
|
||||
return this.$store.state.gui.uiSettings.hideOtherInstances ?? false
|
||||
}
|
||||
|
||||
get instance_ids() {
|
||||
return this.$store.state.server.system_info?.instance_ids ?? {}
|
||||
}
|
||||
|
||||
get klipperInstance() {
|
||||
return this.instance_ids.klipper ?? ''
|
||||
}
|
||||
|
||||
get moonrakerInstance() {
|
||||
return this.instance_ids.moonraker ?? ''
|
||||
}
|
||||
}
|
@ -322,6 +322,13 @@
|
||||
$t('Settings.UiSettingsTab.DashboardHistoryLimitLabel', { count: dashboardHistoryLimit })
|
||||
" />
|
||||
</settings-row>
|
||||
<v-divider class="my-2" />
|
||||
<settings-row
|
||||
:title="$t('Settings.UiSettingsTab.HideOtherInstances')"
|
||||
:sub-title="$t('Settings.UiSettingsTab.HideOtherInstancesDescription')"
|
||||
:dynamic-slot-width="true">
|
||||
<v-switch v-model="hideOtherInstances" hide-details class="mt-0" />
|
||||
</settings-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
@ -696,6 +703,14 @@ export default class SettingsUiSettingsTab extends Mixins(BaseMixin, ThemeMixin)
|
||||
this.$store.dispatch('gui/saveSetting', { name: 'uiSettings.dashboardHistoryLimit', value: newVal })
|
||||
}
|
||||
|
||||
get hideOtherInstances() {
|
||||
return this.$store.state.gui.uiSettings.hideOtherInstances ?? false
|
||||
}
|
||||
|
||||
set hideOtherInstances(newVal) {
|
||||
this.$store.dispatch('gui/saveSetting', { name: 'uiSettings.hideOtherInstances', value: newVal })
|
||||
}
|
||||
|
||||
clearColorObject(color: any): string {
|
||||
if (typeof color === 'object' && 'hex' in color) color = color.hex
|
||||
if (color.length > 7) color = color.substr(0, 7)
|
||||
|
154
src/components/ui/TopCornerMenuService.vue
Normal file
154
src/components/ui/TopCornerMenuService.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<v-list-item class="minHeight30 pr-2">
|
||||
<v-list-item-title>
|
||||
<v-tooltip left>
|
||||
<template #activator="{ on, attrs }">
|
||||
<span v-bind="attrs" v-on="on">{{ name }}</span>
|
||||
</template>
|
||||
<span>{{ state }} ({{ subState }})</span>
|
||||
</v-tooltip>
|
||||
</v-list-item-title>
|
||||
<v-list-item-action class="my-0 d-flex flex-row" style="min-width: auto">
|
||||
<v-btn v-if="state === 'inactive'" icon small @click="clickStart">
|
||||
<v-icon small>{{ mdiPlay }}</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-else icon small @click="clickRestart">
|
||||
<v-icon small>{{ mdiRestart }}</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small :disabled="disableStopButton" :style="styleStopButton" @click="clickStop">
|
||||
<v-icon small>{{ mdiStop }}</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
<confirmation-dialog
|
||||
:show="showRestartDialog"
|
||||
:title="dialogRestartTitle"
|
||||
:text="dialogRestartDescription"
|
||||
:action-button-text="$t('App.TopCornerMenu.Restart')"
|
||||
:cancel-button-text="$t('App.TopCornerMenu.Cancel')"
|
||||
@action="serviceRestart"
|
||||
@close="showRestartDialog = false" />
|
||||
<confirmation-dialog
|
||||
:show="showStopDialog"
|
||||
:title="dialogStopTitle"
|
||||
:text="dialogStopDescription"
|
||||
:action-button-text="$t('App.TopCornerMenu.Stop')"
|
||||
:cancel-button-text="$t('App.TopCornerMenu.Cancel')"
|
||||
@action="serviceStop"
|
||||
@close="showStopDialog = false" />
|
||||
</v-list-item>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import Component from 'vue-class-component'
|
||||
import { Mixins, Prop } from 'vue-property-decorator'
|
||||
import BaseMixin from '@/components/mixins/base'
|
||||
import { mdiPlay, mdiRestart, mdiStop } from '@mdi/js'
|
||||
import { capitalize } from '@/plugins/helpers'
|
||||
import ServiceMixins from '@/components/mixins/services'
|
||||
|
||||
@Component({})
|
||||
export default class TopCornerMenuService extends Mixins(BaseMixin, ServiceMixins) {
|
||||
mdiPlay = mdiPlay
|
||||
mdiRestart = mdiRestart
|
||||
mdiStop = mdiStop
|
||||
|
||||
@Prop({ type: String, required: true }) service!: string
|
||||
|
||||
showRestartDialog = false
|
||||
showStopDialog = false
|
||||
|
||||
get name() {
|
||||
if (this.hideOtherInstances && this.service === this.klipperInstance) return 'Klipper'
|
||||
if (this.hideOtherInstances && this.service === this.moonrakerInstance) return 'Moonraker'
|
||||
|
||||
return capitalize(this.service)
|
||||
}
|
||||
|
||||
get service_states() {
|
||||
return this.$store.state.server.system_info?.service_state ?? {}
|
||||
}
|
||||
|
||||
get state() {
|
||||
if (this.service in this.service_states) return this.service_states[this.service].active_state
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
get subState() {
|
||||
if (this.service in this.service_states) return this.service_states[this.service].sub_state
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
get dialogRestartTitle() {
|
||||
if (this.service === this.klipperInstance)
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Title.KlipperRestart')
|
||||
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Title.ServiceRestart')
|
||||
}
|
||||
|
||||
get dialogStopTitle() {
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Title.ServiceStop')
|
||||
}
|
||||
|
||||
get dialogRestartDescription() {
|
||||
if (this.service === this.klipperInstance)
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Description.KlipperRestart')
|
||||
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Description.ServiceRestart')
|
||||
}
|
||||
|
||||
get dialogStopDescription() {
|
||||
if (this.service === this.klipperInstance)
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Description.KlipperStop')
|
||||
|
||||
return this.$t('App.TopCornerMenu.ConfirmationDialog.Description.ServiceStop')
|
||||
}
|
||||
|
||||
get disableStopButton() {
|
||||
return this.state === 'inactive' || this.service === this.moonrakerInstance
|
||||
}
|
||||
|
||||
get styleStopButton() {
|
||||
return this.service === this.moonrakerInstance ? 'visibility: hidden;' : ''
|
||||
}
|
||||
|
||||
clickStart() {
|
||||
this.$socket.emit('machine.services.start', { service: this.service })
|
||||
this.closeMenu()
|
||||
}
|
||||
|
||||
clickRestart() {
|
||||
if (this.printerIsPrinting) {
|
||||
this.showRestartDialog = true
|
||||
return
|
||||
}
|
||||
|
||||
this.serviceRestart()
|
||||
}
|
||||
|
||||
clickStop() {
|
||||
if (this.printerIsPrinting) {
|
||||
this.showStopDialog = true
|
||||
return
|
||||
}
|
||||
|
||||
this.serviceStop()
|
||||
}
|
||||
|
||||
serviceRestart() {
|
||||
this.showRestartDialog = false
|
||||
this.$socket.emit('machine.services.restart', { service: this.service })
|
||||
this.closeMenu()
|
||||
}
|
||||
|
||||
serviceStop() {
|
||||
this.showStopDialog = false
|
||||
this.$socket.emit('machine.services.stop', { service: this.service })
|
||||
this.closeMenu()
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
this.$emit('close-menu')
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1253,6 +1253,8 @@
|
||||
"GcodeThumbnails": "G-Code thumbnails",
|
||||
"GcodeThumbnailsDescription": "Click on the button to get to the instructions.",
|
||||
"Guide": "Guide",
|
||||
"HideOtherInstances": "Hide other instances",
|
||||
"HideOtherInstancesDescription": "Hide other instances of Klipper & Moonraker in the Service Menu.",
|
||||
"HideSaveConfigButtonForBedMesh": "Hide SAVE_CONFIG button for bed_mesh changes",
|
||||
"HideSaveConfigButtonForBedMeshDescription": "Hide SAVE_CONFIG, if only bed_mesh changes are pending to be saved in Klipper.",
|
||||
"HideUpdateWarnings": "Hide Update Warnings",
|
||||
|
@ -186,6 +186,7 @@ export const getDefaultState = (): GuiState => {
|
||||
dashboardFilesLimit: 5,
|
||||
dashboardFilesFilter: ['new', 'failed', 'completed'],
|
||||
dashboardHistoryLimit: 5,
|
||||
hideOtherInstances: false,
|
||||
},
|
||||
view: {
|
||||
blockFileUpload: false,
|
||||
|
@ -128,6 +128,7 @@ export interface GuiState {
|
||||
dashboardFilesLimit: number
|
||||
dashboardFilesFilter: GuiStateUiSettingsDashboardFilesFilter[]
|
||||
dashboardHistoryLimit: number
|
||||
hideOtherInstances: boolean
|
||||
}
|
||||
view: {
|
||||
blockFileUpload: boolean
|
||||
|
@ -33,6 +33,10 @@ export interface ServerState {
|
||||
[key: string]: ServerStateNetwork
|
||||
}
|
||||
system_uptime: number | null
|
||||
instance_ids: {
|
||||
moonraker: string
|
||||
klipper: string
|
||||
}
|
||||
} | null
|
||||
system_boot_at: Date | null
|
||||
moonraker_stats: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user