mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: rework async ServiceInfo
This commit is contained in:
parent
fe380005a5
commit
e8b0e3b87c
2 changed files with 51 additions and 49 deletions
|
@ -198,6 +198,17 @@ export type BackupList = {
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SERVICES
|
||||||
|
|
||||||
|
export type ServiceInfo = {
|
||||||
|
status: 'running' | 'stopped' | 'failed' | 'unknown'
|
||||||
|
start_on_boot: 'enabled' | 'disabled' | 'unknown'
|
||||||
|
last_state_change: string | 'unknown'
|
||||||
|
description: string
|
||||||
|
configuration: 'valid' | 'broken' | 'unknown'
|
||||||
|
}
|
||||||
|
export type ServiceLogs = Obj<string[]>
|
||||||
|
|
||||||
// DIAGNOSIS
|
// DIAGNOSIS
|
||||||
|
|
||||||
export type Diagnosis = {
|
export type Diagnosis = {
|
||||||
|
|
|
@ -1,70 +1,61 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { useAutoModal } from '@/composables/useAutoModal'
|
import { useAutoModal } from '@/composables/useAutoModal'
|
||||||
import { useInitialQueries } from '@/composables/useInitialQueries'
|
|
||||||
import { distanceToNow } from '@/helpers/filters/date'
|
import { distanceToNow } from '@/helpers/filters/date'
|
||||||
|
import type { ServiceInfo, ServiceLogs } from '@/types/core/api'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{ name: string }>()
|
||||||
name: string
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const modalConfirm = useAutoModal()
|
const modalConfirm = useAutoModal()
|
||||||
const { loading, refetch } = useInitialQueries(
|
|
||||||
[
|
|
||||||
{ uri: 'services/' + props.name },
|
|
||||||
{ uri: `services/${props.name}/log?number=50` },
|
|
||||||
],
|
|
||||||
{ onQueriesResponse },
|
|
||||||
)
|
|
||||||
|
|
||||||
const infos = ref()
|
const { infos, upOrDownTime, isCritical, logs } = await api
|
||||||
const uptime = ref()
|
.fetchAll<
|
||||||
const isCritical = ref()
|
[ServiceInfo, ServiceLogs]
|
||||||
const logs = ref()
|
>([{ uri: 'services/' + props.name }, { uri: `services/${props.name}/log?number=50` }])
|
||||||
const action = ref()
|
.then(([service, logs]) => {
|
||||||
|
const { last_state_change, ...infos } = service
|
||||||
|
const criticalServices = ['nginx', 'ssh', 'slapd', 'yunohost-api']
|
||||||
|
|
||||||
function onQueriesResponse(
|
return {
|
||||||
// eslint-disable-next-line
|
infos,
|
||||||
{ status, description, start_on_boot, last_state_change, configuration }: any,
|
upOrDownTime:
|
||||||
logs_: any,
|
last_state_change === 'unknown'
|
||||||
) {
|
? t('unknown')
|
||||||
isCritical.value = ['nginx', 'ssh', 'slapd', 'yunohost-api'].includes(
|
: distanceToNow(last_state_change, false),
|
||||||
props.name,
|
isCritical: criticalServices.includes(props.name),
|
||||||
)
|
logs: Object.keys(logs)
|
||||||
// eslint-disable-next-line
|
|
||||||
uptime.value = last_state_change === 'unknown' ? 0 : last_state_change
|
|
||||||
infos.value = { description, status, start_on_boot, configuration }
|
|
||||||
|
|
||||||
logs.value = Object.keys(logs_)
|
|
||||||
.sort((prev, curr) => {
|
.sort((prev, curr) => {
|
||||||
if (prev === 'journalctl') return -1
|
if (prev === 'journalctl') return -1
|
||||||
else if (curr === 'journalctl') return 1
|
else if (curr === 'journalctl') return 1
|
||||||
else if (prev < curr) return -1
|
else if (prev < curr) return -1
|
||||||
else return 1
|
else return 1
|
||||||
})
|
})
|
||||||
.map((filename) => ({ content: logs_[filename].join('\n'), filename }))
|
.map((filename) => ({
|
||||||
|
content: logs[filename].join('\n'),
|
||||||
|
filename,
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
async function updateService(action) {
|
async function updateService(action: 'start' | 'stop' | 'restart') {
|
||||||
const confirmed = await modalConfirm(
|
const confirmed = await modalConfirm(
|
||||||
t('confirm_service_' + action, { name: props.name }),
|
t(`confirm_service_${action}`, { name: props.name }),
|
||||||
)
|
)
|
||||||
if (!confirmed) return
|
if (!confirmed) return
|
||||||
|
|
||||||
api
|
api
|
||||||
.put({
|
.put({
|
||||||
uri: `services/${props.name}/${action}`,
|
uri: `services/${props.name}/${action}`,
|
||||||
humanKey: { key: 'services.' + action, name: props.name },
|
humanKey: { key: `services.${action}`, name: props.name },
|
||||||
})
|
})
|
||||||
.then(() => refetch(false))
|
.then(() => api.refetch())
|
||||||
}
|
}
|
||||||
|
|
||||||
function shareLogs() {
|
function shareLogs() {
|
||||||
const logs = logs.value
|
const logsContent = logs
|
||||||
.map(({ filename, content }) => {
|
.map(({ filename, content }) => {
|
||||||
return `LOGFILE: ${filename}\n${content}`
|
return `LOGFILE: ${filename}\n${content}`
|
||||||
})
|
})
|
||||||
|
@ -72,21 +63,21 @@ function shareLogs() {
|
||||||
|
|
||||||
fetch('https://paste.yunohost.org/documents', {
|
fetch('https://paste.yunohost.org/documents', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: logs,
|
body: logsContent,
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.ok) return response.json()
|
if (response.ok) return response.json()
|
||||||
|
else console.error('error', response)
|
||||||
// FIXME flash error
|
// FIXME flash error
|
||||||
/* eslint-disable-next-line */ else console.log('error', response)
|
|
||||||
})
|
})
|
||||||
.then(({ key }) => {
|
.then(({ key }) => {
|
||||||
window.open('https://paste.yunohost.org/' + key, '_blank')
|
window.open(`https://paste.yunohost.org/${key}`, '_blank')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ViewBase :loading="loading" skeleton="CardInfoSkeleton">
|
<div>
|
||||||
<!-- INFO CARD -->
|
<!-- INFO CARD -->
|
||||||
<YCard :title="name" icon="info-circle" button-unbreak="sm">
|
<YCard :title="name" icon="info-circle" button-unbreak="sm">
|
||||||
<template #header-buttons>
|
<template #header-buttons>
|
||||||
|
@ -129,7 +120,7 @@ function shareLogs() {
|
||||||
<YIcon :iname="value === 'running' ? 'check-circle' : 'times'" />
|
<YIcon :iname="value === 'running' ? 'check-circle' : 'times'" />
|
||||||
{{ $t(value) }}
|
{{ $t(value) }}
|
||||||
</span>
|
</span>
|
||||||
{{ $t('since') }} {{ distanceToNow(uptime) }}
|
{{ $t('since') }} {{ upOrDownTime }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
|
@ -160,7 +151,7 @@ function shareLogs() {
|
||||||
<pre class="log"><code>{{ content }}</code></pre>
|
<pre class="log"><code>{{ content }}</code></pre>
|
||||||
</template>
|
</template>
|
||||||
</YCard>
|
</YCard>
|
||||||
</ViewBase>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in a new issue