This commit is contained in:
syuilo 2018-02-20 07:56:39 +09:00
parent b4a874766e
commit bc17a0b2cb
13 changed files with 618 additions and 539 deletions

View File

@ -1,6 +0,0 @@
export default (bytes, digits = 0) => {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0Byte';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, i)).toFixed(digits).replace(/\.0+$/, '') + sizes[i];
};

View File

@ -1,533 +0,0 @@
<mk-server-home-widget data-melt={ data.design == 2 }>
<template v-if="data.design == 0">
<p class="title">%fa:server%%i18n:desktop.tags.mk-server-home-widget.title%</p>
<button @click="toggle" title="%i18n:desktop.tags.mk-server-home-widget.toggle%">%fa:sort%</button>
</template>
<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<mk-server-home-widget-cpu-and-memory-usage v-if="!initializing" show={ data.view == 0 } connection={ connection }/>
<mk-server-home-widget-cpu v-if="!initializing" show={ data.view == 1 } connection={ connection } meta={ meta }/>
<mk-server-home-widget-memory v-if="!initializing" show={ data.view == 2 } connection={ connection }/>
<mk-server-home-widget-disk v-if="!initializing" show={ data.view == 3 } connection={ connection }/>
<mk-server-home-widget-uptimes v-if="!initializing" show={ data.view == 4 } connection={ connection }/>
<mk-server-home-widget-info v-if="!initializing" show={ data.view == 5 } connection={ connection } meta={ meta }/>
<style lang="stylus" scoped>
:scope
display block
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-melt]
background transparent !important
border none !important
> .title
z-index 1
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> button
position absolute
z-index 2
top 0
right 0
padding 0
width 42px
font-size 0.9em
line-height 42px
color #ccc
&:hover
color #aaa
&:active
color #999
> .initializing
margin 0
padding 16px
text-align center
color #aaa
> [data-fa]
margin-right 4px
</style>
<script lang="typescript">
this.mixin('os');
this.data = {
view: 0,
design: 0
};
this.mixin('widget');
this.mixin('server-stream');
this.connection = this.serverStream.getConnection();
this.connectionId = this.serverStream.use();
this.initializing = true;
this.on('mount', () => {
this.mios.getMeta().then(meta => {
this.update({
initializing: false,
meta
});
});
});
this.on('unmount', () => {
this.serverStream.dispose(this.connectionId);
});
this.toggle = () => {
this.data.view++;
if (this.data.view == 6) this.data.view = 0;
// Save widget state
this.save();
};
this.func = () => {
if (++this.data.design == 3) this.data.design = 0;
this.save();
};
</script>
</mk-server-home-widget>
<mk-server-home-widget-cpu-and-memory-usage>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
<defs>
<linearGradient id={ cpuGradientId } x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
<stop offset="33%" stop-color="hsl(120, 80%, 70%)"></stop>
<stop offset="66%" stop-color="hsl(60, 80%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
</linearGradient>
<mask id={ cpuMaskId } x="0" y="0" riot-width={ viewBoxX } riot-height={ viewBoxY }>
<polygon
riot-points={ cpuPolygonPoints }
fill="#fff"
fill-opacity="0.5"/>
<polyline
riot-points={ cpuPolylinePoints }
fill="none"
stroke="#fff"
stroke-width="1"/>
</mask>
</defs>
<rect
x="-1" y="-1"
riot-width={ viewBoxX + 2 } riot-height={ viewBoxY + 2 }
style="stroke: none; fill: url(#{ cpuGradientId }); mask: url(#{ cpuMaskId })"/>
<text x="1" y="5">CPU <tspan>{ cpuP }%</tspan></text>
</svg>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
<defs>
<linearGradient id={ memGradientId } x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
<stop offset="33%" stop-color="hsl(120, 80%, 70%)"></stop>
<stop offset="66%" stop-color="hsl(60, 80%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
</linearGradient>
<mask id={ memMaskId } x="0" y="0" riot-width={ viewBoxX } riot-height={ viewBoxY }>
<polygon
riot-points={ memPolygonPoints }
fill="#fff"
fill-opacity="0.5"/>
<polyline
riot-points={ memPolylinePoints }
fill="none"
stroke="#fff"
stroke-width="1"/>
</mask>
</defs>
<rect
x="-1" y="-1"
riot-width={ viewBoxX + 2 } riot-height={ viewBoxY + 2 }
style="stroke: none; fill: url(#{ memGradientId }); mask: url(#{ memMaskId })"/>
<text x="1" y="5">MEM <tspan>{ memP }%</tspan></text>
</svg>
<style lang="stylus" scoped>
:scope
display block
> svg
display block
padding 10px
width 50%
float left
&:first-child
padding-right 5px
&:last-child
padding-left 5px
> text
font-size 5px
fill rgba(0, 0, 0, 0.55)
> tspan
opacity 0.5
&:after
content ""
display block
clear both
</style>
<script lang="typescript">
import uuid from 'uuid';
this.viewBoxX = 50;
this.viewBoxY = 30;
this.stats = [];
this.connection = this.opts.connection;
this.cpuGradientId = uuid();
this.cpuMaskId = uuid();
this.memGradientId = uuid();
this.memMaskId = uuid();
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
});
this.onStats = stats => {
stats.mem.used = stats.mem.total - stats.mem.free;
this.stats.push(stats);
if (this.stats.length > 50) this.stats.shift();
const cpuPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - s.cpu_usage) * this.viewBoxY}`).join(' ');
const memPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - (s.mem.used / s.mem.total)) * this.viewBoxY}`).join(' ');
const cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ cpuPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
const memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ memPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
const cpuP = (stats.cpu_usage * 100).toFixed(0);
const memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
this.update({
cpuPolylinePoints,
memPolylinePoints,
cpuPolygonPoints,
memPolygonPoints,
cpuP,
memP
});
};
</script>
</mk-server-home-widget-cpu-and-memory-usage>
<mk-server-home-widget-cpu>
<mk-server-home-widget-pie ref="pie"/>
<div>
<p>%fa:microchip%CPU</p>
<p>{ cores } Cores</p>
<p>{ model }</p>
</div>
<style lang="stylus" scoped>
:scope
display block
> mk-server-home-widget-pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>
<script lang="typescript">
this.cores = this.opts.meta.cpu.cores;
this.model = this.opts.meta.cpu.model;
this.connection = this.opts.connection;
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
});
this.onStats = stats => {
this.$refs.pie.render(stats.cpu_usage);
};
</script>
</mk-server-home-widget-cpu>
<mk-server-home-widget-memory>
<mk-server-home-widget-pie ref="pie"/>
<div>
<p>%fa:flask%Memory</p>
<p>Total: { bytesToSize(total, 1) }</p>
<p>Used: { bytesToSize(used, 1) }</p>
<p>Free: { bytesToSize(free, 1) }</p>
</div>
<style lang="stylus" scoped>
:scope
display block
> mk-server-home-widget-pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>
<script lang="typescript">
import bytesToSize from '../../../common/scripts/bytes-to-size';
this.connection = this.opts.connection;
this.bytesToSize = bytesToSize;
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
});
this.onStats = stats => {
stats.mem.used = stats.mem.total - stats.mem.free;
this.$refs.pie.render(stats.mem.used / stats.mem.total);
this.update({
total: stats.mem.total,
used: stats.mem.used,
free: stats.mem.free
});
};
</script>
</mk-server-home-widget-memory>
<mk-server-home-widget-disk>
<mk-server-home-widget-pie ref="pie"/>
<div>
<p>%fa:R hdd%Storage</p>
<p>Total: { bytesToSize(total, 1) }</p>
<p>Available: { bytesToSize(available, 1) }</p>
<p>Used: { bytesToSize(used, 1) }</p>
</div>
<style lang="stylus" scoped>
:scope
display block
> mk-server-home-widget-pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>
<script lang="typescript">
import bytesToSize from '../../../common/scripts/bytes-to-size';
this.connection = this.opts.connection;
this.bytesToSize = bytesToSize;
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
});
this.onStats = stats => {
stats.disk.used = stats.disk.total - stats.disk.free;
this.$refs.pie.render(stats.disk.used / stats.disk.total);
this.update({
total: stats.disk.total,
used: stats.disk.used,
available: stats.disk.available
});
};
</script>
</mk-server-home-widget-disk>
<mk-server-home-widget-uptimes>
<p>Uptimes</p>
<p>Process: { process ? process.toFixed(0) : '---' }s</p>
<p>OS: { os ? os.toFixed(0) : '---' }s</p>
<style lang="stylus" scoped>
:scope
display block
padding 10px 14px
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
</style>
<script lang="typescript">
this.connection = this.opts.connection;
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
});
this.onStats = stats => {
this.update({
process: stats.process_uptime,
os: stats.os_uptime
});
};
</script>
</mk-server-home-widget-uptimes>
<mk-server-home-widget-info>
<p>Maintainer: <b>{ meta.maintainer }</b></p>
<p>Machine: { meta.machine }</p>
<p>Node: { meta.node }</p>
<style lang="stylus" scoped>
:scope
display block
padding 10px 14px
> p
margin 0
font-size 12px
color #505050
</style>
<script lang="typescript">
this.meta = this.opts.meta;
</script>
</mk-server-home-widget-info>
<mk-server-home-widget-pie>
<svg viewBox="0 0 1 1" preserveAspectRatio="none">
<circle
riot-r={ r }
cx="50%" cy="50%"
fill="none"
stroke-width="0.1"
stroke="rgba(0, 0, 0, 0.05)"/>
<circle
riot-r={ r }
cx="50%" cy="50%"
riot-stroke-dasharray={ Math.PI * (r * 2) }
riot-stroke-dashoffset={ strokeDashoffset }
fill="none"
stroke-width="0.1"
riot-stroke={ color }/>
<text x="50%" y="50%" dy="0.05" text-anchor="middle">{ (p * 100).toFixed(0) }%</text>
</svg>
<style lang="stylus" scoped>
:scope
display block
> svg
display block
height 100%
> circle
transform-origin center
transform rotate(-90deg)
transition stroke-dashoffset 0.5s ease
> text
font-size 0.15px
fill rgba(0, 0, 0, 0.6)
</style>
<script lang="typescript">
this.r = 0.4;
this.render = p => {
const color = `hsl(${180 - (p * 180)}, 80%, 70%)`;
const strokeDashoffset = (1 - p) * (Math.PI * (this.r * 2));
this.update({
p,
color,
strokeDashoffset
});
};
</script>
</mk-server-home-widget-pie>

View File

@ -0,0 +1,127 @@
<template>
<div class="cpu-memory">
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none">
<defs>
<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="-1" y="-1"
:width="viewBoxX + 2" :height="viewBoxY + 2"
:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"/>
<text x="1" y="5">CPU <tspan>{{ cpuP }}%</tspan></text>
</svg>
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none">
<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="-1" y="-1"
:width="viewBoxX + 2" :height="viewBoxY + 2"
:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"/>
<text x="1" y="5">MEM <tspan>{{ memP }}%</tspan></text>
</svg>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import uuid from 'uuid';
export default Vue.extend({
props: ['connection'],
data() {
return {
viewBoxX: 50,
viewBoxY: 30,
stats: [],
cpuGradientId: uuid(),
cpuMaskId: uuid(),
memGradientId: uuid(),
memMaskId: uuid(),
cpuPolylinePoints: '',
memPolylinePoints: '',
cpuPolygonPoints: '',
memPolygonPoints: '',
cpuP: '',
memP: ''
};
},
mounted() {
this.connection.on('stats', this.onStats);
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
},
methods: {
onStats(stats) {
stats.mem.used = stats.mem.total - stats.mem.free;
this.stats.push(stats);
if (this.stats.length > 50) this.stats.shift();
this.cpuPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - s.cpu_usage) * this.viewBoxY}`).join(' ');
this.memPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - (s.mem.used / s.mem.total)) * this.viewBoxY}`).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.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
}
}
});
</script>
<style lang="stylus" scoped>
.cpu-memory
> svg
display block
padding 10px
width 50%
float left
&:first-child
padding-right 5px
&:last-child
padding-left 5px
> text
font-size 5px
fill rgba(0, 0, 0, 0.55)
> tspan
opacity 0.5
&:after
content ""
display block
clear both
</style>

View File

@ -0,0 +1,68 @@
<template>
<div class="cpu">
<x-pie class="pie" :value="usage"/>
<div>
<p>%fa:microchip%CPU</p>
<p>{{ cores }} Cores</p>
<p>{{ model }}</p>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XPie from './server.pie.vue';
export default Vue.extend({
components: {
'x-pie': XPie
},
props: ['connection', 'meta'],
data() {
return {
usage: 0
};
},
mounted() {
this.connection.on('stats', this.onStats);
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
},
methods: {
onStats(stats) {
this.usage = stats.cpu_usage;
}
}
});
</script>
<style lang="stylus" scoped>
.cpu
> .pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>

View File

@ -0,0 +1,76 @@
<template>
<div class="disk">
<x-pie class="pie" :value="usage"/>
<div>
<p>%fa:R hdd%Storage</p>
<p>Total: {{ total | bytes(1) }}</p>
<p>Available: {{ available | bytes(1) }}</p>
<p>Used: {{ used | bytes(1) }}</p>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XPie from './server.pie.vue';
export default Vue.extend({
components: {
'x-pie': XPie
},
props: ['connection'],
data() {
return {
usage: 0,
total: 0,
used: 0,
available: 0
};
},
mounted() {
this.connection.on('stats', this.onStats);
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
},
methods: {
onStats(stats) {
stats.disk.used = stats.disk.total - stats.disk.free;
this.usage = stats.disk.used / stats.disk.total;
this.total = stats.disk.total;
this.used = stats.disk.used;
this.available = stats.disk.available;
}
}
});
</script>
<style lang="stylus" scoped>
.disk
> .pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>

View File

@ -0,0 +1,25 @@
<template>
<div class="info">
<p>Maintainer: <b>{{ meta.maintainer }}</b></p>
<p>Machine: {{ meta.machine }}</p>
<p>Node: {{ meta.node }}</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['meta']
});
</script>
<style lang="info" scoped>
.uptimes
padding 10px 14px
> p
margin 0
font-size 12px
color #505050
</style>

View File

@ -0,0 +1,76 @@
<template>
<div class="memory">
<x-pie class="pie" :value="usage"/>
<div>
<p>%fa:flask%Memory</p>
<p>Total: {{ total | bytes(1) }}</p>
<p>Used: {{ used | bytes(1) }}</p>
<p>Free: {{ free | bytes(1) }}</p>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XPie from './server.pie.vue';
export default Vue.extend({
components: {
'x-pie': XPie
},
props: ['connection'],
data() {
return {
usage: 0,
total: 0,
used: 0,
free: 0
};
},
mounted() {
this.connection.on('stats', this.onStats);
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
},
methods: {
onStats(stats) {
stats.mem.used = stats.mem.total - stats.mem.free;
this.usage = stats.mem.used / stats.mem.total;
this.total = stats.mem.total;
this.used = stats.mem.used;
this.free = stats.mem.free;
}
}
});
</script>
<style lang="stylus" scoped>
.memory
> .pie
padding 10px
height 100px
float left
> div
float left
width calc(100% - 100px)
padding 10px 10px 10px 0
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
> [data-fa]
margin-right 4px
&:after
content ""
display block
clear both
</style>

View File

@ -0,0 +1,61 @@
<template>
<svg viewBox="0 0 1 1" preserveAspectRatio="none">
<circle
:r="r"
cx="50%" cy="50%"
fill="none"
stroke-width="0.1"
stroke="rgba(0, 0, 0, 0.05)"/>
<circle
:r="r"
cx="50%" cy="50%"
:stroke-dasharray="Math.PI * (r * 2)"
:stroke-dashoffset="strokeDashoffset"
fill="none"
stroke-width="0.1"
:stroke="color"/>
<text x="50%" y="50%" dy="0.05" text-anchor="middle">{{ (p * 100).toFixed(0) }}%</text>
</svg>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: {
value: {
type: Number,
required: true
}
},
data() {
return {
r: 0.4
};
},
computed: {
color(): string {
return `hsl(${180 - (this.value * 180)}, 80%, 70%)`;
},
strokeDashoffset(): number {
return (1 - this.value) * (Math.PI * (this.r * 2));
}
}
});
</script>
<style lang="stylus" scoped>
svg
display block
height 100%
> circle
transform-origin center
transform rotate(-90deg)
transition stroke-dashoffset 0.5s ease
> text
font-size 0.15px
fill rgba(0, 0, 0, 0.6)
</style>

View File

@ -0,0 +1,46 @@
<template>
<div class="uptimes">
<p>Uptimes</p>
<p>Process: {{ process ? process.toFixed(0) : '---' }}s</p>
<p>OS: {{ os ? os.toFixed(0) : '---' }}s</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['connection'],
data() {
return {
process: 0,
os: 0
};
},
mounted() {
this.connection.on('stats', this.onStats);
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
},
methods: {
onStats(stats) {
this.process = stats.process_uptime;
this.os = stats.os_uptime;
}
}
});
</script>
<style lang="stylus" scoped>
.uptimes
padding 10px 14px
> p
margin 0
font-size 12px
color #505050
&:first-child
font-weight bold
</style>

View File

@ -0,0 +1,127 @@
<template>
<div class="mkw-server" :data-melt="props.design == 2">
<template v-if="props.design == 0">
<p class="title">%fa:server%%i18n:desktop.tags.mk-server-home-widget.title%</p>
<button @click="toggle" title="%i18n:desktop.tags.mk-server-home-widget.toggle%">%fa:sort%</button>
</template>
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<template v-if="!fetching">
<x-cpu-memory v-show="props.view == 0" :connection="connection"/>
<x-cpu v-show="props.view == 1" :connection="connection" :meta="meta"/>
<x-memory v-show="props.view == 2" :connection="connection"/>
<x-disk v-show="props.view == 3" :connection="connection"/>
<x-uptimes v-show="props.view == 4" :connection="connection"/>
<x-info v-show="props.view == 5" :connection="connection" :meta="meta"/>
</template>
</div>
</template>
<script lang="ts">
import define from '../../../../common/define-widget';
import XCpuMemory from './server.cpu-memory.vue';
import XCpu from './server.cpu.vue';
import XMemory from './server.memory.vue';
import XDisk from './server.disk.vue';
import XUptimes from './server.uptimes.vue';
import XInfo from './server.info.vue';
export default define({
name: 'server',
props: {
design: 0,
view: 0
}
}).extend({
components: {
'x-cpu-and-memory': XCpuMemory,
'x-cpu': XCpu,
'x-memory': XMemory,
'x-disk': XDisk,
'x-uptimes': XUptimes,
'x-info': XInfo
},
data() {
return {
fetching: true,
meta: null,
connection: null,
connectionId: null
};
},
mounted() {
(this as any).os.getMeta().then(meta => {
this.meta = meta;
this.fetching = false;
});
this.connection = (this as any).os.streams.serverStream.getConnection();
this.connectionId = (this as any).os.streams.serverStream.use();
},
beforeDestroy() {
(this as any).os.streams.serverStream.dispose(this.connectionId);
},
methods: {
toggle() {
if (this.props.design == 5) {
this.props.design = 0;
} else {
this.props.design++;
}
},
func() {
this.toggle();
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-server
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-melt]
background transparent !important
border none !important
> .title
z-index 1
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> button
position absolute
z-index 2
top 0
right 0
padding 0
width 42px
font-size 0.9em
line-height 42px
color #ccc
&:hover
color #aaa
&:active
color #999
> .fetching
margin 0
padding 16px
text-align center
color #aaa
> [data-fa]
margin-right 4px
</style>

View File

@ -0,0 +1,8 @@
import Vue from 'vue';
Vue.filter('bytes', (v, digits = 0) => {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (v == 0) return '0Byte';
const i = Math.floor(Math.log(v) / Math.log(1024));
return (v / Math.pow(1024, i)).toFixed(digits).replace(/\.0+$/, '') + sizes[i];
});

View File

@ -0,0 +1 @@
require('./bytes');

View File

@ -20,6 +20,9 @@ require('./common/views/directives');
// Register global components // Register global components
require('./common/views/components'); require('./common/views/components');
// Register global filters
require('./filters');
Vue.mixin({ Vue.mixin({
destroyed(this: any) { destroyed(this: any) {
if (this.$el.parentNode) { if (this.$el.parentNode) {