mirror of
https://github.com/hotomoe/hotomoe
synced 2024-11-25 15:46:17 +09:00
Improve admin page
This commit is contained in:
parent
8ae94c034d
commit
6f1e2f6636
@ -1080,10 +1080,10 @@ admin/views/index.vue:
|
|||||||
|
|
||||||
admin/views/dashboard.vue:
|
admin/views/dashboard.vue:
|
||||||
dashboard: "ダッシュボード"
|
dashboard: "ダッシュボード"
|
||||||
all-users: "全てのユーザー"
|
accounts: "アカウント"
|
||||||
original-users: "このインスタンスのユーザー"
|
notes: "投稿"
|
||||||
all-notes: "全ての投稿"
|
this-instance: "このインスタンス"
|
||||||
original-notes: "このインスタンスの投稿"
|
federated: "連合"
|
||||||
invite: "招待"
|
invite: "招待"
|
||||||
banner-url: "Banner URL"
|
banner-url: "Banner URL"
|
||||||
disableRegistration: "Disable new user registration"
|
disableRegistration: "Disable new user registration"
|
||||||
|
@ -1,79 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
|
<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
|
||||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
|
<div ref="cpu"></div>
|
||||||
<defs>
|
<div ref="mem"></div>
|
||||||
<linearGradient :id="cpuGradientId" x1="0" x2="0" y1="1" y2="0">
|
|
||||||
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
|
||||||
<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
|
|
||||||
</linearGradient>
|
|
||||||
<mask :id="cpuMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
|
|
||||||
<polygon
|
|
||||||
:points="cpuPolygonPoints"
|
|
||||||
fill="#fff"
|
|
||||||
fill-opacity="0.5"/>
|
|
||||||
<polyline
|
|
||||||
:points="cpuPolylinePoints"
|
|
||||||
fill="none"
|
|
||||||
stroke="#fff"
|
|
||||||
stroke-width="1"/>
|
|
||||||
</mask>
|
|
||||||
</defs>
|
|
||||||
<rect
|
|
||||||
x="0" y="0"
|
|
||||||
:width="viewBoxX" :height="viewBoxY"
|
|
||||||
:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"/>
|
|
||||||
<text x="1" y="12">CPU <tspan>{{ cpuP }}%</tspan></text>
|
|
||||||
</svg>
|
|
||||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
|
|
||||||
<defs>
|
|
||||||
<linearGradient :id="memGradientId" x1="0" x2="0" y1="1" y2="0">
|
|
||||||
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
|
||||||
<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
|
|
||||||
</linearGradient>
|
|
||||||
<mask :id="memMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
|
|
||||||
<polygon
|
|
||||||
:points="memPolygonPoints"
|
|
||||||
fill="#fff"
|
|
||||||
fill-opacity="0.5"/>
|
|
||||||
<polyline
|
|
||||||
:points="memPolylinePoints"
|
|
||||||
fill="none"
|
|
||||||
stroke="#fff"
|
|
||||||
stroke-width="1"/>
|
|
||||||
</mask>
|
|
||||||
</defs>
|
|
||||||
<rect
|
|
||||||
x="0" y="0"
|
|
||||||
:width="viewBoxX" :height="viewBoxY"
|
|
||||||
:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"/>
|
|
||||||
<text x="1" y="12">MEM <tspan>{{ memP }}%</tspan></text>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as uuid from 'uuid';
|
import * as ApexCharts from 'apexcharts';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['connection'],
|
props: ['connection'],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
viewBoxX: 200,
|
|
||||||
viewBoxY: 70,
|
|
||||||
stats: [],
|
stats: [],
|
||||||
cpuGradientId: uuid(),
|
cpuChart: null,
|
||||||
cpuMaskId: uuid(),
|
memChart: null,
|
||||||
memGradientId: uuid(),
|
|
||||||
memMaskId: uuid(),
|
|
||||||
cpuPolylinePoints: '',
|
|
||||||
memPolylinePoints: '',
|
|
||||||
cpuPolygonPoints: '',
|
|
||||||
memPolygonPoints: '',
|
|
||||||
cpuP: '',
|
cpuP: '',
|
||||||
memP: ''
|
memP: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
stats(stats) {
|
||||||
|
this.cpuChart.updateSeries([{
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.cpu_usage }))
|
||||||
|
}]);
|
||||||
|
this.memChart.updateSeries([{
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: (x.mem.used / x.mem.total) }))
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.connection.on('stats', this.onStats);
|
this.connection.on('stats', this.onStats);
|
||||||
this.connection.on('statsLog', this.onStatsLog);
|
this.connection.on('statsLog', this.onStatsLog);
|
||||||
@ -81,27 +40,75 @@ export default Vue.extend({
|
|||||||
id: Math.random().toString().substr(2, 8),
|
id: Math.random().toString().substr(2, 8),
|
||||||
length: 200
|
length: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const chartOpts = {
|
||||||
|
chart: {
|
||||||
|
type: 'area',
|
||||||
|
height: 300,
|
||||||
|
animations: {
|
||||||
|
dynamicAnimation: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
clipMarkers: false,
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'straight',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
data: []
|
||||||
|
}],
|
||||||
|
xaxis: {
|
||||||
|
type: 'numeric',
|
||||||
|
labels: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
show: false,
|
||||||
|
min: 0,
|
||||||
|
max: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.cpuChart = new ApexCharts(this.$refs.cpu, Object.assign({}, chartOpts, {
|
||||||
|
title: {
|
||||||
|
text: 'CPU'
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
this.memChart = new ApexCharts(this.$refs.mem, Object.assign({}, chartOpts, {
|
||||||
|
title: {
|
||||||
|
text: 'MEM'
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.cpuChart.render();
|
||||||
|
this.memChart.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.connection.off('stats', this.onStats);
|
this.connection.off('stats', this.onStats);
|
||||||
this.connection.off('statsLog', this.onStatsLog);
|
this.connection.off('statsLog', this.onStatsLog);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onStats(stats) {
|
onStats(stats) {
|
||||||
this.stats.push(stats);
|
this.stats.push(stats);
|
||||||
if (this.stats.length > 200) this.stats.shift();
|
if (this.stats.length > 200) this.stats.shift();
|
||||||
|
|
||||||
const cpuPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - s.cpu_usage) * this.viewBoxY]);
|
|
||||||
const memPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.mem.used / s.mem.total)) * this.viewBoxY]);
|
|
||||||
this.cpuPolylinePoints = cpuPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
|
||||||
this.memPolylinePoints = memPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
|
||||||
|
|
||||||
this.cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.cpuPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
|
|
||||||
this.memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.memPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
|
|
||||||
|
|
||||||
this.cpuP = (stats.cpu_usage * 100).toFixed(0);
|
this.cpuP = (stats.cpu_usage * 100).toFixed(0);
|
||||||
this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
|
this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStatsLog(statsLog) {
|
onStatsLog(statsLog) {
|
||||||
statsLog.reverse().forEach(stats => this.onStats(stats));
|
statsLog.reverse().forEach(stats => this.onStats(stats));
|
||||||
}
|
}
|
||||||
@ -111,27 +118,17 @@ export default Vue.extend({
|
|||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.zyknedwtlthezamcjlolyusmipqmjgxz
|
.zyknedwtlthezamcjlolyusmipqmjgxz
|
||||||
> svg
|
display flex
|
||||||
|
|
||||||
|
> div
|
||||||
display block
|
display block
|
||||||
width 50%
|
flex 1
|
||||||
float left
|
padding 32px
|
||||||
|
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
|
background var(--face)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&:first-child
|
&:first-child
|
||||||
padding-right 5px
|
margin-right 16px
|
||||||
|
|
||||||
&:last-child
|
|
||||||
padding-left 5px
|
|
||||||
|
|
||||||
> text
|
|
||||||
font-size 10px
|
|
||||||
fill var(--chartCaption)
|
|
||||||
|
|
||||||
> tspan
|
|
||||||
opacity 0.5
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,31 +2,51 @@
|
|||||||
<div class="obdskegsannmntldydackcpzezagxqfy">
|
<div class="obdskegsannmntldydackcpzezagxqfy">
|
||||||
<div v-if="stats" class="stats">
|
<div v-if="stats" class="stats">
|
||||||
<div>
|
<div>
|
||||||
<div>%fa:user%</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span>%i18n:@original-users%</span>
|
<div>%fa:user%</div>
|
||||||
<b>{{ stats.originalUsersCount | number }}</b>
|
<div>
|
||||||
|
<span>%i18n:@accounts%</span>
|
||||||
|
<b class="primary">{{ stats.originalUsersCount | number }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>%fa:home% %i18n:@this-instance%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>%fa:pencil-alt%</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span>%i18n:@original-notes%</span>
|
<div>%fa:pencil-alt%</div>
|
||||||
<b>{{ stats.originalNotesCount | number }}</b>
|
<div>
|
||||||
|
<span>%i18n:@notes%</span>
|
||||||
|
<b class="primary">{{ stats.originalNotesCount | number }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>%fa:home% %i18n:@this-instance%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>%fa:user%</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span>%i18n:@all-users%</span>
|
<div>%fa:user%</div>
|
||||||
<b>{{ stats.usersCount | number }}</b>
|
<div>
|
||||||
|
<span>%i18n:@accounts%</span>
|
||||||
|
<b>{{ stats.usersCount | number }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>%fa:globe% %i18n:@federated%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>%fa:pencil-alt%</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span>%i18n:@all-notes%</span>
|
<div>%fa:pencil-alt%</div>
|
||||||
<b>{{ stats.notesCount | number }}</b>
|
<div>
|
||||||
|
<span>%i18n:@notes%</span>
|
||||||
|
<b>{{ stats.notesCount | number }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>%fa:globe% %i18n:@federated%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -78,40 +98,53 @@ export default Vue.extend({
|
|||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
|
|
||||||
> div
|
> div
|
||||||
display flex
|
|
||||||
align-items center
|
|
||||||
flex 1
|
flex 1
|
||||||
max-width 300px
|
max-width 300px
|
||||||
margin-right 16px
|
margin-right 16px
|
||||||
text-align center
|
|
||||||
color var(--text)
|
color var(--text)
|
||||||
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
||||||
&:last-child
|
&:last-child
|
||||||
margin-right 0
|
margin-right 0
|
||||||
|
|
||||||
> div:first-child
|
> div:first-child
|
||||||
padding 16px 24px
|
display flex
|
||||||
font-size 28px
|
align-items center
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
margin-right 0
|
||||||
|
|
||||||
|
> div:first-child
|
||||||
|
padding 16px 24px
|
||||||
|
font-size 28px
|
||||||
|
|
||||||
|
> div:last-child
|
||||||
|
flex 1
|
||||||
|
padding 16px 32px 16px 0
|
||||||
|
text-align right
|
||||||
|
|
||||||
|
> span
|
||||||
|
font-size 70%
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
> b
|
||||||
|
display block
|
||||||
|
|
||||||
|
&.primary
|
||||||
|
color var(--primary)
|
||||||
|
|
||||||
> div:last-child
|
> div:last-child
|
||||||
flex 1
|
padding 6px 16px
|
||||||
padding 16px 32px 16px 0
|
border-top solid 1px #eee
|
||||||
text-align right
|
|
||||||
|
|
||||||
> span
|
> span
|
||||||
|
font-size 70%
|
||||||
opacity 0.7
|
opacity 0.7
|
||||||
|
|
||||||
> b
|
|
||||||
display block
|
|
||||||
|
|
||||||
> .cpu-memory
|
> .cpu-memory
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
padding 32px
|
|
||||||
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
|
||||||
background var(--face)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user