Improve control panel
This commit is contained in:
		
							parent
							
								
									e922d8904c
								
							
						
					
					
						commit
						6d53e64798
					
				
					 3 changed files with 167 additions and 6 deletions
				
			
		
							
								
								
									
										143
									
								
								src/client/app/desktop/views/pages/admin/admin.cpu-memory.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/client/app/desktop/views/pages/admin/admin.cpu-memory.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,143 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
 | 
				
			||||||
 | 
						<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
 | 
				
			||||||
 | 
							<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="0.3"/>
 | 
				
			||||||
 | 
								</mask>
 | 
				
			||||||
 | 
							</defs>
 | 
				
			||||||
 | 
							<rect
 | 
				
			||||||
 | 
								x="0" y="0"
 | 
				
			||||||
 | 
								:width="viewBoxX" :height="viewBoxY"
 | 
				
			||||||
 | 
								: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 }`">
 | 
				
			||||||
 | 
							<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="0.3"/>
 | 
				
			||||||
 | 
								</mask>
 | 
				
			||||||
 | 
							</defs>
 | 
				
			||||||
 | 
							<rect
 | 
				
			||||||
 | 
								x="0" y="0"
 | 
				
			||||||
 | 
								:width="viewBoxX" :height="viewBoxY"
 | 
				
			||||||
 | 
								: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 * as uuid from 'uuid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: ['connection'],
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								viewBoxX: 50,
 | 
				
			||||||
 | 
								viewBoxY: 20,
 | 
				
			||||||
 | 
								stats: [],
 | 
				
			||||||
 | 
								cpuGradientId: uuid(),
 | 
				
			||||||
 | 
								cpuMaskId: uuid(),
 | 
				
			||||||
 | 
								memGradientId: uuid(),
 | 
				
			||||||
 | 
								memMaskId: uuid(),
 | 
				
			||||||
 | 
								cpuPolylinePoints: '',
 | 
				
			||||||
 | 
								memPolylinePoints: '',
 | 
				
			||||||
 | 
								cpuPolygonPoints: '',
 | 
				
			||||||
 | 
								memPolygonPoints: '',
 | 
				
			||||||
 | 
								cpuP: '',
 | 
				
			||||||
 | 
								memP: ''
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							this.connection.on('stats', this.onStats);
 | 
				
			||||||
 | 
							this.connection.on('statsLog', this.onStatsLog);
 | 
				
			||||||
 | 
							this.connection.send({
 | 
				
			||||||
 | 
								type: 'requestLog',
 | 
				
			||||||
 | 
								id: Math.random().toString()
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						beforeDestroy() {
 | 
				
			||||||
 | 
							this.connection.off('stats', this.onStats);
 | 
				
			||||||
 | 
							this.connection.off('statsLog', this.onStatsLog);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							onStats(stats) {
 | 
				
			||||||
 | 
								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]);
 | 
				
			||||||
 | 
								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.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							onStatsLog(statsLog) {
 | 
				
			||||||
 | 
								statsLog.forEach(stats => this.onStats(stats));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					root(isDark)
 | 
				
			||||||
 | 
						> svg
 | 
				
			||||||
 | 
							display block
 | 
				
			||||||
 | 
							width 50%
 | 
				
			||||||
 | 
							float left
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:first-child
 | 
				
			||||||
 | 
								padding-right 5px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:last-child
 | 
				
			||||||
 | 
								padding-left 5px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> text
 | 
				
			||||||
 | 
								font-size 2px
 | 
				
			||||||
 | 
								fill isDark ? rgba(#fff, 0.55) : rgba(#000, 0.55)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> tspan
 | 
				
			||||||
 | 
									opacity 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						&:after
 | 
				
			||||||
 | 
							content ""
 | 
				
			||||||
 | 
							display block
 | 
				
			||||||
 | 
							clear both
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.zyknedwtlthezamcjlolyusmipqmjgxz[data-darkmode]
 | 
				
			||||||
 | 
						root(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.zyknedwtlthezamcjlolyusmipqmjgxz:not([data-darkmode])
 | 
				
			||||||
 | 
						root(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,12 @@
 | 
				
			||||||
	<header>%i18n:@dashboard%</header>
 | 
						<header>%i18n:@dashboard%</header>
 | 
				
			||||||
	<div v-if="stats" class="stats">
 | 
						<div v-if="stats" class="stats">
 | 
				
			||||||
		<div><b>%fa:user% {{ stats.originalUsersCount | number }}</b><span>%i18n:@original-users%</span></div>
 | 
							<div><b>%fa:user% {{ stats.originalUsersCount | number }}</b><span>%i18n:@original-users%</span></div>
 | 
				
			||||||
		<div><b>%fa:user% {{ stats.usersCount | number }}</b><span>%i18n:@all-users%</span></div>
 | 
							<div><span>%fa:user% {{ stats.usersCount | number }}</span><span>%i18n:@all-users%</span></div>
 | 
				
			||||||
		<div><b>%fa:pen% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div>
 | 
							<div><b>%fa:pen% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div>
 | 
				
			||||||
		<div><b>%fa:pen% {{ stats.notesCount | number }}</b><span>%i18n:@all-notes%</span></div>
 | 
							<div><span>%fa:pen% {{ stats.notesCount | number }}</span><span>%i18n:@all-notes%</span></div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="cpu-memory">
 | 
				
			||||||
 | 
							<x-cpu-memory :connection="connection"/>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		<button class="ui" @click="invite">%i18n:@invite%</button>
 | 
							<button class="ui" @click="invite">%i18n:@invite%</button>
 | 
				
			||||||
| 
						 | 
					@ -16,19 +19,31 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from "vue";
 | 
					import Vue from "vue";
 | 
				
			||||||
 | 
					import XCpuMemory from "./admin.cpu-memory.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
							XCpuMemory
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			stats: null,
 | 
								stats: null,
 | 
				
			||||||
			inviteCode: null
 | 
								inviteCode: null,
 | 
				
			||||||
 | 
								connection: null,
 | 
				
			||||||
 | 
								connectionId: null
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	created() {
 | 
						created() {
 | 
				
			||||||
 | 
							this.connection = (this as any).os.streams.serverStatsStream.getConnection();
 | 
				
			||||||
 | 
							this.connectionId = (this as any).os.streams.serverStatsStream.use();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		(this as any).api('stats').then(stats => {
 | 
							(this as any).api('stats').then(stats => {
 | 
				
			||||||
			this.stats = stats;
 | 
								this.stats = stats;
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						beforeDestroy() {
 | 
				
			||||||
 | 
							(this as any).os.streams.serverStatsStream.dispose(this.connectionId);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		invite() {
 | 
							invite() {
 | 
				
			||||||
			(this as any).api('admin/invite').then(x => {
 | 
								(this as any).api('admin/invite').then(x => {
 | 
				
			||||||
| 
						 | 
					@ -47,16 +62,19 @@ export default Vue.extend({
 | 
				
			||||||
		display flex
 | 
							display flex
 | 
				
			||||||
		justify-content center
 | 
							justify-content center
 | 
				
			||||||
		margin-bottom 16px
 | 
							margin-bottom 16px
 | 
				
			||||||
 | 
							padding 16px
 | 
				
			||||||
 | 
							border solid 1px #eee
 | 
				
			||||||
 | 
							border-radius 8px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> div
 | 
							> div
 | 
				
			||||||
			flex 1
 | 
								flex 1
 | 
				
			||||||
			text-align center
 | 
								text-align center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			> b
 | 
								> *:first-child
 | 
				
			||||||
				display block
 | 
									display block
 | 
				
			||||||
				color $theme-color
 | 
									color $theme-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			> span
 | 
								> *:last-child
 | 
				
			||||||
				font-size 70%
 | 
									font-size 70%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
		</ul>
 | 
							</ul>
 | 
				
			||||||
	</nav>
 | 
						</nav>
 | 
				
			||||||
	<main>
 | 
						<main>
 | 
				
			||||||
		<div v-if="page == 'dashboard'">
 | 
							<div v-show="page == 'dashboard'">
 | 
				
			||||||
			<x-dashboard/>
 | 
								<x-dashboard/>
 | 
				
			||||||
			<x-users-chart/>
 | 
								<x-users-chart/>
 | 
				
			||||||
			<x-notes-chart/>
 | 
								<x-notes-chart/>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue