summaryrefslogtreecommitdiff
path: root/packages/frontend/src/pages/admin/queue.chart.vue
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-12-27 14:36:33 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-12-27 14:36:33 +0900
commit9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch)
treece5959571a981b9c4047da3c7b3fd080aa44222c /packages/frontend/src/pages/admin/queue.chart.vue
parentwip: retention for dashboard (diff)
downloadsharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.gz
sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.bz2
sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.zip
rename: client -> frontend
Diffstat (limited to 'packages/frontend/src/pages/admin/queue.chart.vue')
-rw-r--r--packages/frontend/src/pages/admin/queue.chart.vue149
1 files changed, 149 insertions, 0 deletions
diff --git a/packages/frontend/src/pages/admin/queue.chart.vue b/packages/frontend/src/pages/admin/queue.chart.vue
new file mode 100644
index 0000000000..186a22c43e
--- /dev/null
+++ b/packages/frontend/src/pages/admin/queue.chart.vue
@@ -0,0 +1,149 @@
+<template>
+<div class="pumxzjhg">
+ <div class="_table status">
+ <div class="_row">
+ <div class="_cell"><div class="_label">Process</div>{{ number(activeSincePrevTick) }}</div>
+ <div class="_cell"><div class="_label">Active</div>{{ number(active) }}</div>
+ <div class="_cell"><div class="_label">Waiting</div>{{ number(waiting) }}</div>
+ <div class="_cell"><div class="_label">Delayed</div>{{ number(delayed) }}</div>
+ </div>
+ </div>
+ <div class="charts">
+ <div class="chart">
+ <div class="title">Process</div>
+ <XChart ref="chartProcess" type="process"/>
+ </div>
+ <div class="chart">
+ <div class="title">Active</div>
+ <XChart ref="chartActive" type="active"/>
+ </div>
+ <div class="chart">
+ <div class="title">Delayed</div>
+ <XChart ref="chartDelayed" type="delayed"/>
+ </div>
+ <div class="chart">
+ <div class="title">Waiting</div>
+ <XChart ref="chartWaiting" type="waiting"/>
+ </div>
+ </div>
+ <div class="jobs">
+ <div v-if="jobs.length > 0">
+ <div v-for="job in jobs" :key="job[0]">
+ <span>{{ job[0] }}</span>
+ <span style="margin-left: 8px; opacity: 0.7;">({{ number(job[1]) }} jobs)</span>
+ </div>
+ </div>
+ <span v-else style="opacity: 0.5;">{{ i18n.ts.noJobs }}</span>
+ </div>
+</div>
+</template>
+
+<script lang="ts" setup>
+import { markRaw, onMounted, onUnmounted, ref } from 'vue';
+import XChart from './queue.chart.chart.vue';
+import number from '@/filters/number';
+import * as os from '@/os';
+import { stream } from '@/stream';
+import { i18n } from '@/i18n';
+
+const connection = markRaw(stream.useChannel('queueStats'));
+
+const activeSincePrevTick = ref(0);
+const active = ref(0);
+const delayed = ref(0);
+const waiting = ref(0);
+const jobs = ref([]);
+let chartProcess = $ref<InstanceType<typeof XChart>>();
+let chartActive = $ref<InstanceType<typeof XChart>>();
+let chartDelayed = $ref<InstanceType<typeof XChart>>();
+let chartWaiting = $ref<InstanceType<typeof XChart>>();
+
+const props = defineProps<{
+ domain: string;
+}>();
+
+const onStats = (stats) => {
+ activeSincePrevTick.value = stats[props.domain].activeSincePrevTick;
+ active.value = stats[props.domain].active;
+ delayed.value = stats[props.domain].delayed;
+ waiting.value = stats[props.domain].waiting;
+
+ chartProcess.pushData(stats[props.domain].activeSincePrevTick);
+ chartActive.pushData(stats[props.domain].active);
+ chartDelayed.pushData(stats[props.domain].delayed);
+ chartWaiting.pushData(stats[props.domain].waiting);
+};
+
+const onStatsLog = (statsLog) => {
+ const dataProcess = [];
+ const dataActive = [];
+ const dataDelayed = [];
+ const dataWaiting = [];
+
+ for (const stats of [...statsLog].reverse()) {
+ dataProcess.push(stats[props.domain].activeSincePrevTick);
+ dataActive.push(stats[props.domain].active);
+ dataDelayed.push(stats[props.domain].delayed);
+ dataWaiting.push(stats[props.domain].waiting);
+ }
+
+ chartProcess.setData(dataProcess);
+ chartActive.setData(dataActive);
+ chartDelayed.setData(dataDelayed);
+ chartWaiting.setData(dataWaiting);
+};
+
+onMounted(() => {
+ os.api(props.domain === 'inbox' ? 'admin/queue/inbox-delayed' : props.domain === 'deliver' ? 'admin/queue/deliver-delayed' : null, {}).then(result => {
+ jobs.value = result;
+ });
+
+ connection.on('stats', onStats);
+ connection.on('statsLog', onStatsLog);
+ connection.send('requestLog', {
+ id: Math.random().toString().substr(2, 8),
+ length: 200,
+ });
+});
+
+onUnmounted(() => {
+ connection.off('stats', onStats);
+ connection.off('statsLog', onStatsLog);
+ connection.dispose();
+});
+</script>
+
+<style lang="scss" scoped>
+.pumxzjhg {
+ > .status {
+ padding: 16px;
+ }
+
+ > .charts {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 16px;
+
+ > .chart {
+ min-width: 0;
+ padding: 16px;
+ background: var(--panel);
+ border-radius: var(--radius);
+
+ > .title {
+ margin-bottom: 8px;
+ }
+ }
+ }
+
+ > .jobs {
+ margin-top: 16px;
+ padding: 16px;
+ max-height: 180px;
+ overflow: auto;
+ background: var(--panel);
+ border-radius: var(--radius);
+ }
+
+}
+</style>