Massive frontend overhaul
This commit is contained in:
		@ -1,5 +1,5 @@
 | 
				
			|||||||
before_script:
 | 
					before_script:
 | 
				
			||||||
 - export VERSION=1.0.1
 | 
					 - export VERSION=1.1.0
 | 
				
			||||||
 - chmod +x packaging/build-package.sh packaging/package-upload.sh
 | 
					 - chmod +x packaging/build-package.sh packaging/package-upload.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stages:
 | 
					stages:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								package.json
									
									
									
									
									
								
							@ -10,10 +10,15 @@
 | 
				
			|||||||
    "build": "node build/build.js"
 | 
					    "build": "node build/build.js"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "bootstrap": "^4.0.0-beta.2",
 | 
					    "@fortawesome/fontawesome": "^1.1.5",
 | 
				
			||||||
    "bootstrap-vue": "^1.3.0",
 | 
					    "@fortawesome/fontawesome-free-regular": "^5.0.9",
 | 
				
			||||||
 | 
					    "@fortawesome/fontawesome-free-solid": "^5.0.9",
 | 
				
			||||||
 | 
					    "@fortawesome/vue-fontawesome": "0.0.22",
 | 
				
			||||||
 | 
					    "bootstrap": "^4.0.0",
 | 
				
			||||||
 | 
					    "bootstrap-vue": "^1.5.1",
 | 
				
			||||||
    "event-emitter": "^0.3.5",
 | 
					    "event-emitter": "^0.3.5",
 | 
				
			||||||
    "jquery": "^3.2.1",
 | 
					    "jquery": "^3.2.1",
 | 
				
			||||||
 | 
					    "moment": "^2.22.0",
 | 
				
			||||||
    "tiny-emitter": "^2.0.2",
 | 
					    "tiny-emitter": "^2.0.2",
 | 
				
			||||||
    "util.inherits": "^1.0.3",
 | 
					    "util.inherits": "^1.0.3",
 | 
				
			||||||
    "vue": "^2.4.2",
 | 
					    "vue": "^2.4.2",
 | 
				
			||||||
@ -39,18 +44,20 @@
 | 
				
			|||||||
    "friendly-errors-webpack-plugin": "^1.1.3",
 | 
					    "friendly-errors-webpack-plugin": "^1.1.3",
 | 
				
			||||||
    "html-webpack-plugin": "^2.28.0",
 | 
					    "html-webpack-plugin": "^2.28.0",
 | 
				
			||||||
    "http-proxy-middleware": "^0.17.3",
 | 
					    "http-proxy-middleware": "^0.17.3",
 | 
				
			||||||
    "webpack-bundle-analyzer": "^2.2.1",
 | 
					    "node-sass": "^4.8.3",
 | 
				
			||||||
    "semver": "^5.3.0",
 | 
					 | 
				
			||||||
    "shelljs": "^0.7.6",
 | 
					 | 
				
			||||||
    "opn": "^5.1.0",
 | 
					    "opn": "^5.1.0",
 | 
				
			||||||
    "optimize-css-assets-webpack-plugin": "^2.0.0",
 | 
					    "optimize-css-assets-webpack-plugin": "^2.0.0",
 | 
				
			||||||
    "ora": "^1.2.0",
 | 
					    "ora": "^1.2.0",
 | 
				
			||||||
    "rimraf": "^2.6.0",
 | 
					    "rimraf": "^2.6.0",
 | 
				
			||||||
 | 
					    "sass-loader": "^6.0.7",
 | 
				
			||||||
 | 
					    "semver": "^5.3.0",
 | 
				
			||||||
 | 
					    "shelljs": "^0.7.6",
 | 
				
			||||||
    "url-loader": "^0.5.8",
 | 
					    "url-loader": "^0.5.8",
 | 
				
			||||||
    "vue-loader": "^13.0.4",
 | 
					    "vue-loader": "^13.0.4",
 | 
				
			||||||
    "vue-style-loader": "^3.0.1",
 | 
					    "vue-style-loader": "^3.0.1",
 | 
				
			||||||
    "vue-template-compiler": "^2.4.2",
 | 
					    "vue-template-compiler": "^2.4.2",
 | 
				
			||||||
    "webpack": "^2.6.1",
 | 
					    "webpack": "^2.7.0",
 | 
				
			||||||
 | 
					    "webpack-bundle-analyzer": "^2.2.1",
 | 
				
			||||||
    "webpack-dev-middleware": "^1.10.0",
 | 
					    "webpack-dev-middleware": "^1.10.0",
 | 
				
			||||||
    "webpack-hot-middleware": "^2.18.0",
 | 
					    "webpack-hot-middleware": "^2.18.0",
 | 
				
			||||||
    "webpack-merge": "^4.1.0"
 | 
					    "webpack-merge": "^4.1.0"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/App.vue
									
									
									
									
									
								
							@ -1,21 +1,23 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div id="app" class="container">
 | 
					  <div id="app">
 | 
				
			||||||
    <div class="row" style="padding-bottom: 10px;">
 | 
					    <n :sensors="sensors" />
 | 
				
			||||||
      <div class="col-sm">
 | 
					    <div class="container">
 | 
				
			||||||
        <h1>Ripper</h1>
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <main role="main" class="col-md-12 ml-sm-auto col-lg-12 pt-3 px-4">
 | 
				
			||||||
 | 
					        <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
 | 
				
			||||||
 | 
					          <h1 class="h2">Jobs</h1>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <status :sensors="sensors"></status>
 | 
					 | 
				
			||||||
    <temperatures :temperatures="sensors.temperatures"></temperatures>
 | 
					 | 
				
			||||||
        <job v-for="(job, id) in jobs" :job="job" :key="job.id"></job>
 | 
					        <job v-for="(job, id) in jobs" :job="job" :key="job.id"></job>
 | 
				
			||||||
 | 
					        </main>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import Vue from 'vue'
 | 
					import Vue from 'vue'
 | 
				
			||||||
import job from './components/Job';
 | 
					import job from './components/Job';
 | 
				
			||||||
import status from './components/Status';
 | 
					import navbar from './components/Nav';
 | 
				
			||||||
import temperatures from './components/TempStatus';
 | 
					 | 
				
			||||||
import EventWebSocket from './websocket';
 | 
					import EventWebSocket from './websocket';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let d = {
 | 
					let d = {
 | 
				
			||||||
@ -70,8 +72,7 @@ export default {
 | 
				
			|||||||
  name: 'app',
 | 
					  name: 'app',
 | 
				
			||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
    job: job,
 | 
					    job: job,
 | 
				
			||||||
    status: status,
 | 
					    n: navbar,
 | 
				
			||||||
    temperatures: temperatures,
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return d;
 | 
					    return d;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										93
									
								
								src/assets/scss/_sidebar.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/assets/scss/_sidebar.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					body {
 | 
				
			||||||
 | 
					  font-size: .875rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.feather {
 | 
				
			||||||
 | 
					  width: 16px;
 | 
				
			||||||
 | 
					  height: 16px;
 | 
				
			||||||
 | 
					  vertical-align: text-bottom;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Sidebar
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar {
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  bottom: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  z-index: 100; /* Behind the navbar */
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar-sticky {
 | 
				
			||||||
 | 
					  position: -webkit-sticky;
 | 
				
			||||||
 | 
					  position: sticky;
 | 
				
			||||||
 | 
					  top: 48px; /* Height of navbar */
 | 
				
			||||||
 | 
					  height: calc(100vh - 48px);
 | 
				
			||||||
 | 
					  padding-top: .5rem;
 | 
				
			||||||
 | 
					  overflow-x: hidden;
 | 
				
			||||||
 | 
					  overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar .nav-link {
 | 
				
			||||||
 | 
					  font-weight: 500;
 | 
				
			||||||
 | 
					  color: #333;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar .nav-link .feather {
 | 
				
			||||||
 | 
					  margin-right: 4px;
 | 
				
			||||||
 | 
					  color: #999;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar .nav-link.active {
 | 
				
			||||||
 | 
					  color: #007bff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar .nav-link:hover .feather,
 | 
				
			||||||
 | 
					.sidebar .nav-link.active .feather {
 | 
				
			||||||
 | 
					  color: inherit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sidebar-heading {
 | 
				
			||||||
 | 
					  font-size: .75rem;
 | 
				
			||||||
 | 
					  text-transform: uppercase;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Navbar
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar-brand {
 | 
				
			||||||
 | 
					  padding-top: .75rem;
 | 
				
			||||||
 | 
					  padding-bottom: .75rem;
 | 
				
			||||||
 | 
					  font-size: 1rem;
 | 
				
			||||||
 | 
					  background-color: rgba(0, 0, 0, .25);
 | 
				
			||||||
 | 
					  box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar .form-control {
 | 
				
			||||||
 | 
					  padding: .75rem 1rem;
 | 
				
			||||||
 | 
					  border-width: 0;
 | 
				
			||||||
 | 
					  border-radius: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-control-dark {
 | 
				
			||||||
 | 
					  color: #fff;
 | 
				
			||||||
 | 
					  background-color: rgba(255, 255, 255, .1);
 | 
				
			||||||
 | 
					  border-color: rgba(255, 255, 255, .1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-control-dark:focus {
 | 
				
			||||||
 | 
					  border-color: transparent;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Utilities
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.border-top { border-top: 1px solid #e5e5e5; }
 | 
				
			||||||
 | 
					.border-bottom { border-bottom: 1px solid #e5e5e5; }
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/assets/scss/_variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/assets/scss/_variables.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					$cold: #6CA6CD;
 | 
				
			||||||
 | 
					$cool: #79CDCD;
 | 
				
			||||||
 | 
					$info: #4F94CD;
 | 
				
			||||||
 | 
					$acceptable: #66CDAA;
 | 
				
			||||||
 | 
					$success: #A2CD5A;
 | 
				
			||||||
 | 
					$high: #EEE685;
 | 
				
			||||||
 | 
					$warning: #E3A869;
 | 
				
			||||||
 | 
					$danger: #EE8262;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$badge-color: #545454;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$theme-colors: (
 | 
				
			||||||
 | 
					  "cold": $cold,
 | 
				
			||||||
 | 
					  "cool": $cool,
 | 
				
			||||||
 | 
					  "acceptable": $acceptable,
 | 
				
			||||||
 | 
					  "high": $high
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@each $color, $value in $theme-colors {
 | 
				
			||||||
 | 
					  .badge-#{$color} {
 | 
				
			||||||
 | 
					    color: $badge-color !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/assets/scss/app.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/assets/scss/app.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					@import '_variables.scss';
 | 
				
			||||||
 | 
					@import '~bootstrap/scss/bootstrap';
 | 
				
			||||||
 | 
					@import '~bootstrap-vue/dist/bootstrap-vue.css';
 | 
				
			||||||
 | 
					@import '_sidebar.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.margin-top-10 {
 | 
				
			||||||
 | 
					  margin-top: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.margin-bottom-10 {
 | 
				
			||||||
 | 
					  margin-bottom: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.margin-bottom-20 {
 | 
				
			||||||
 | 
					  margin-bottom: 20px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.badge-success {
 | 
				
			||||||
 | 
					  color: #454545;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.nav-item .progress {
 | 
				
			||||||
 | 
					  width: 70px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <div class="row">
 | 
					 | 
				
			||||||
    <job v-for="(job, index) in jobs" :job="job" :key="job_id"></job>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
import job from '@/components/Job';
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  name: 'hello',
 | 
					 | 
				
			||||||
  components: {
 | 
					 | 
				
			||||||
    job: job
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  data () {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      msg: 'Welcome to Your Vue.js App'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
@ -1,11 +1,19 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col-sm">
 | 
					    <div class="col-sm">
 | 
				
			||||||
      <h3>{{ job.title }} - {{ stageValue }}</h3>
 | 
					      <div class="card">
 | 
				
			||||||
 | 
					        <div class="card-header">
 | 
				
			||||||
 | 
					          <div class="row">
 | 
				
			||||||
 | 
					            <div class="col-md">{{ job.title }}</div>
 | 
				
			||||||
 | 
					            <div class="col-md text-center badge">{{ stageValue }}</div>
 | 
				
			||||||
 | 
					            <div class="col-md text-right">Remaining: {{ eta }}</div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="card-body">
 | 
				
			||||||
          <template v-if="job.progress">
 | 
					          <template v-if="job.progress">
 | 
				
			||||||
            <span class="text-center">{{ job.progress.name }} ({{ job.progress.percentage }}%)</span>
 | 
					            <span class="text-center">{{ job.progress.name }} ({{ job.progress.percentage }}%)</span>
 | 
				
			||||||
            <div class="progress">
 | 
					            <div class="progress">
 | 
				
			||||||
          <div class="progress-bar bg-success" role="progressbar" :style="'width: ' + job.progress.percentage + '%'" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">{{ job.progress.percentage }}%</div>
 | 
					              <div class="progress-bar bg-success" role="progressbar" :style="'width: ' + job.progress.percentage + '%'" :aria-valuenow=job.progress.percentage aria-valuemin="0" aria-valuemax="100">{{ job.progress.percentage }}%</div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <template v-if="job.progress.totalPercentage">
 | 
					            <template v-if="job.progress.totalPercentage">
 | 
				
			||||||
              <span class="text-center">Total Progress ({{ job.progress.totalPercentage }}%)</span>
 | 
					              <span class="text-center">Total Progress ({{ job.progress.totalPercentage }}%)</span>
 | 
				
			||||||
@ -16,6 +24,8 @@
 | 
				
			|||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@ -28,8 +38,20 @@
 | 
				
			|||||||
          return 'Ripping';
 | 
					          return 'Ripping';
 | 
				
			||||||
        } else if (this.job.stage === 'transcode') {
 | 
					        } else if (this.job.stage === 'transcode') {
 | 
				
			||||||
          return 'Transcoding';
 | 
					          return 'Transcoding';
 | 
				
			||||||
 | 
					        } else if (this.job.stage === 'copy') {
 | 
				
			||||||
 | 
					          return 'Copying';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return 'Unknown: ' + this.job.stage;
 | 
					        return 'Unknown: ' + this.job.stage;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      eta: function() {
 | 
				
			||||||
 | 
					        if (this.job.eta == 0) {
 | 
				
			||||||
 | 
					          return 'Unknown';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Job is in nanoseconds because of Go's time.Duration
 | 
				
			||||||
 | 
					        let eta = moment.duration(this.job.eta / 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return eta.humanize();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/components/Nav.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/components/Nav.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top p-0">
 | 
				
			||||||
 | 
					    <div class="container d-flex flex-column flex-md-row">
 | 
				
			||||||
 | 
					      <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">ARM</a>
 | 
				
			||||||
 | 
					      <div class="collapse navbar-collapse">
 | 
				
			||||||
 | 
					        <status :sensors="sensors" v-if="sensors"></status>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import status from './Status';
 | 
				
			||||||
 | 
					  export default {
 | 
				
			||||||
 | 
					    name: 'navbar',
 | 
				
			||||||
 | 
					    props: [ 'sensors' ],
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					      status: status,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="row" v-if="sensors.cpu || sensors.memory || sensors.storage">
 | 
					  <ul class="navbar-nav ml-auto" v-if="sensors.cpu || sensors.memory || sensors.disks">
 | 
				
			||||||
    <cpu_status :status="sensors.cpu"></cpu_status>
 | 
					    <cpu_status :status="sensors.cpu" :cpuName="sensors.cpuName" :temperatures="sensors.temperatures"></cpu_status>
 | 
				
			||||||
    <memory_status :status="sensors.memory"></memory_status>
 | 
					    <memory_status :status="sensors.memory"></memory_status>
 | 
				
			||||||
    <disk_status :status="sensors.disk"></disk_status>
 | 
					    <disk_status :status="sensors.disks"></disk_status>
 | 
				
			||||||
  </div>
 | 
					  </ul>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div style="padding-top: 10px;">
 | 
					  <div class="margin-top-10 margin-bottom-20 text-center">
 | 
				
			||||||
    <template v-for="(temp, id) in temperatures">
 | 
					 | 
				
			||||||
      <span class="badge badge-info">{{ temp.name }}: {{ temp.temperature }}C</span> 
 | 
					 | 
				
			||||||
    </template>
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -10,6 +7,7 @@
 | 
				
			|||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
    name: 'temp_status',
 | 
					    name: 'temp_status',
 | 
				
			||||||
    props: [ 'temperatures' ],
 | 
					    props: [ 'temperatures' ],
 | 
				
			||||||
    components: {},
 | 
					    methods: {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,21 +1,38 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="col">
 | 
					  <b-nav-item-dropdown no-caret right>
 | 
				
			||||||
    <h4>CPU <span :class="'badge badge-' + percentageClass">{{ formattedPercentage }}%</span></h4>
 | 
					    <template slot="button-content">
 | 
				
			||||||
    <div class="progress">
 | 
					      <font-awesome-icon icon="tachometer-alt" /> CPU
 | 
				
			||||||
      <div :class="'progress-bar bg-' + percentageClass" role="progressbar" :style="{ width : status.UserPct + '%' }" :aria-valuenow="status.UserPct" aria-valuemin="0" aria-valuemax="100"></div>
 | 
					      <b-progress :value="status.UserPct" height=".5rem" :variant="percentageClass"></b-progress>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <b-dropdown-header class="text-center">CPU</b-dropdown-header>
 | 
				
			||||||
 | 
					    <div class="text-center">
 | 
				
			||||||
 | 
					      <small>{{ cpuName }}</small>
 | 
				
			||||||
 | 
					      <br />
 | 
				
			||||||
 | 
					      <span :class="'badge badge-' + percentageClass">{{ formattedPercentage }}%</span>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="text-center">
 | 
				
			||||||
 | 
					      <template v-for="(temp, id) in temperatures">
 | 
				
			||||||
 | 
					        <span :class="'badge badge-' + badgeClass(temp.temperature)" :title="temp.name">{{ temp.temperature }}C</span> 
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					  </b-nav-item-dropdown>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
    name: 'cpu_status',
 | 
					    name: 'cpu_status',
 | 
				
			||||||
    props: [ 'status' ],
 | 
					    props: [ 'status', 'cpuName', 'temperatures' ],
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
      formattedPercentage: function() {
 | 
					      formattedPercentage: function() {
 | 
				
			||||||
 | 
					        if (!this.status) {
 | 
				
			||||||
 | 
					          return '0.00';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return parseFloat(this.status.UserPct).toFixed(2);
 | 
					        return parseFloat(this.status.UserPct).toFixed(2);
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      percentageClass: function() {
 | 
					      percentageClass: function() {
 | 
				
			||||||
 | 
					        if (!this.status) {
 | 
				
			||||||
 | 
					          return 'info';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (this.status.UserPct >= 90) {
 | 
					        if (this.status.UserPct >= 90) {
 | 
				
			||||||
          return 'danger';
 | 
					          return 'danger';
 | 
				
			||||||
        } else if (this.status.UserPct >= 80) {
 | 
					        } else if (this.status.UserPct >= 80) {
 | 
				
			||||||
@ -23,6 +40,24 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return 'success'
 | 
					        return 'success'
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					      badgeClass: function(temp) {
 | 
				
			||||||
 | 
					        if (temp >= 90) {
 | 
				
			||||||
 | 
					          return 'danger';
 | 
				
			||||||
 | 
					        } else if (temp >= 70) {
 | 
				
			||||||
 | 
					          return 'warning';
 | 
				
			||||||
 | 
					        } else if (temp >= 60) {
 | 
				
			||||||
 | 
					          return 'high';
 | 
				
			||||||
 | 
					        } else if (temp >= 50) {
 | 
				
			||||||
 | 
					          return 'success';
 | 
				
			||||||
 | 
					        } else if (temp >= 40) {
 | 
				
			||||||
 | 
					          return 'acceptable';
 | 
				
			||||||
 | 
					        } else if (temp >= 30) {
 | 
				
			||||||
 | 
					          return 'cool';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return 'cold';
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="col">
 | 
					  <b-nav-item-dropdown no-caret right>
 | 
				
			||||||
    <h4>Disk Space <span :class="'badge badge-' + percentageClass"><formatBytes :bytes="status.used"></formatBytes> of <formatBytes :bytes="status.total"></formatBytes></span></h4>
 | 
					    <template slot="button-content">
 | 
				
			||||||
    <div class="progress">
 | 
					      <font-awesome-icon icon="hdd" /> Disks
 | 
				
			||||||
      <div :class="'progress-bar bg-' + percentageClass" role="progressbar" :style="{ width : usedPercentage + '%' }" :aria-valuenow="usedPercentage" aria-valuemin="0" aria-valuemax="100"></div>
 | 
					      <b-progress :value="totalUsedPercentage" height=".5rem" :variant="totalPercentageClass"></b-progress>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <b-dropdown-header class="text-center">Disks</b-dropdown-header>
 | 
				
			||||||
 | 
					    <div class="text-center">
 | 
				
			||||||
 | 
					      Total
 | 
				
			||||||
 | 
					      <br />
 | 
				
			||||||
 | 
					      <span :class="'badge badge-' + totalPercentageClass"><formatBytes :bytes="totalUsed" /> / <formatBytes :bytes="total" /></span>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div v-for="(disk, index) in status" class="text-center">
 | 
				
			||||||
 | 
					      {{ disk.path }}
 | 
				
			||||||
 | 
					      <br />
 | 
				
			||||||
 | 
					      <span :class="'badge badge-' + individualPercentages[index]"><formatBytes :bytes="disk.used" /> / <formatBytes :bytes="disk.total" /></span>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					  </b-nav-item-dropdown>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@ -12,14 +24,40 @@
 | 
				
			|||||||
    name: 'disk_status',
 | 
					    name: 'disk_status',
 | 
				
			||||||
    props: [ 'status' ],
 | 
					    props: [ 'status' ],
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
      usedPercentage: function() {
 | 
					      totalUsed: function() {
 | 
				
			||||||
        if (!this.status) {
 | 
					        let used = 0;
 | 
				
			||||||
          return 0;
 | 
					
 | 
				
			||||||
 | 
					        let i;
 | 
				
			||||||
 | 
					        for (i = 0; i < this.status.length; i++) {
 | 
				
			||||||
 | 
					          used += this.status[i].used;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return parseFloat((this.status.used / this.status.total) * 100).toFixed(1).toString();
 | 
					
 | 
				
			||||||
 | 
					        return used;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      percentageClass: function() {
 | 
					      total: function() {
 | 
				
			||||||
        let usedPercent = (this.status.used / this.status.total) * 100;
 | 
					        let total = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let i;
 | 
				
			||||||
 | 
					        for (i = 0; i < this.status.length; i++) {
 | 
				
			||||||
 | 
					          total += this.status[i].total;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return total;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      totalUsedPercentage: function() {
 | 
				
			||||||
 | 
					        let used = 0;
 | 
				
			||||||
 | 
					        let total = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let i;
 | 
				
			||||||
 | 
					        for (i = 0; i < this.status.length; i++) {
 | 
				
			||||||
 | 
					          used += this.status[i].used;
 | 
				
			||||||
 | 
					          total += this.status[i].total;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (used / total) * 100;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      totalPercentageClass: function() {
 | 
				
			||||||
 | 
					        let usedPercent = this.totalUsedPercentage;
 | 
				
			||||||
        if (usedPercent >= 90) {
 | 
					        if (usedPercent >= 90) {
 | 
				
			||||||
          return 'danger';
 | 
					          return 'danger';
 | 
				
			||||||
        } else if (usedPercent >= 75) {
 | 
					        } else if (usedPercent >= 75) {
 | 
				
			||||||
@ -27,6 +65,24 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return 'success'
 | 
					        return 'success'
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      individualPercentages: function() {
 | 
				
			||||||
 | 
					        let percentages = [];
 | 
				
			||||||
 | 
					        let i, usedPercent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < this.status.length; i++) {
 | 
				
			||||||
 | 
					          usedPercent = (this.status[i].used / this.status[i].total) * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (usedPercent >= 90) {
 | 
				
			||||||
 | 
					            percentages[i] = 'danger';
 | 
				
			||||||
 | 
					          } else if (usedPercent >= 75) {
 | 
				
			||||||
 | 
					            percentages[i] = 'warning';
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            percentages[i] = 'success';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return percentages;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,15 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="col">
 | 
					  <b-nav-item-dropdown no-caret right>
 | 
				
			||||||
    <h4>Memory <span :class="'badge badge-' + percentageClass"><formatBytes :bytes="(status.MemUsed + status.Buffers + status.Cached) * 1024" /> / <formatBytes :bytes="status.MemTotal * 1024" /></span></h4>
 | 
					    <template slot="button-content">
 | 
				
			||||||
    <div class="progress">
 | 
					      <font-awesome-icon icon="microchip" /> Memory
 | 
				
			||||||
      <div class="progress-bar bg-success" role="progressbar" :style="{ width: memoryPercentage + '%' }" :aria-valuenow="memoryPercentage" aria-valuemin="0" aria-valuemax="100"></div>
 | 
					      <b-progress :value="memoryPercentage" height=".5rem" :variant="percentageClass"></b-progress>
 | 
				
			||||||
      <div class="progress-bar bg-warning" role="progressbar" :style="{ width: memoryBufCachePercentage + '%' }" :aria-valuenow="memoryBufCachePercentage" aria-valuemin="0" aria-valuemax="100"></div>
 | 
					    </template>
 | 
				
			||||||
    </div>
 | 
					    <b-dropdown-header class="text-center">Memory</b-dropdown-header>
 | 
				
			||||||
 | 
					    <div class="text-center">
 | 
				
			||||||
 | 
					      <span :class="'badge badge-' + percentageClass"><formatBytes :bytes="status.MemUsed * 1024" /> / <formatBytes :bytes="status.MemTotal * 1024" /></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					  </b-nav-item-dropdown>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@ -14,16 +18,10 @@
 | 
				
			|||||||
    props: [ 'status' ],
 | 
					    props: [ 'status' ],
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
      memoryPercentage: function() {
 | 
					      memoryPercentage: function() {
 | 
				
			||||||
        if (!this.status) {
 | 
					        return (this.status.MemUsed / this.status.MemTotal) * 100;
 | 
				
			||||||
          return 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return parseFloat((this.status.MemUsed / this.status.MemTotal) * 100).toFixed(1).toString();
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      memoryBufCachePercentage: function() {
 | 
					      memoryBufCachePercentage: function() {
 | 
				
			||||||
        if (!this.status) {
 | 
					        return ((this.status.Buffers + this.status.Cached) / this.status.MemTotal) * 100;
 | 
				
			||||||
          return 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return parseFloat(((this.status.Buffers + this.status.Cached) / this.status.MemTotal) * 100).toFixed(1).toString();
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      percentageClass: function() {
 | 
					      percentageClass: function() {
 | 
				
			||||||
        let usedPercent = (this.status.MemUsed / this.status.MemTotal) * 100;
 | 
					        let usedPercent = (this.status.MemUsed / this.status.MemTotal) * 100;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.js
									
									
									
									
									
								
							@ -1,14 +1,20 @@
 | 
				
			|||||||
// The Vue build version to load with the `import` command
 | 
					// The Vue build version to load with the `import` command
 | 
				
			||||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 | 
					// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 | 
				
			||||||
import Vue from 'vue'
 | 
					import Vue from 'vue'
 | 
				
			||||||
import 'bootstrap/dist/css/bootstrap.css'
 | 
					import './assets/scss/app.scss'
 | 
				
			||||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
 | 
					 | 
				
			||||||
import App from './App'
 | 
					import App from './App'
 | 
				
			||||||
 | 
					import fontawesome from '@fortawesome/fontawesome'
 | 
				
			||||||
 | 
					import FontAwesomeIcon from '@fortawesome/vue-fontawesome'
 | 
				
			||||||
 | 
					import solid from '@fortawesome/fontawesome-free-solid'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import BootstrapVue from 'bootstrap-vue'
 | 
					import BootstrapVue from 'bootstrap-vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.use(BootstrapVue);
 | 
					Vue.use(BootstrapVue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fontawesome.library.add(solid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Vue.component('font-awesome-icon', FontAwesomeIcon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.component('formatBytes', {
 | 
					Vue.component('formatBytes', {
 | 
				
			||||||
  render: function (createElement) {
 | 
					  render: function (createElement) {
 | 
				
			||||||
    return createElement(
 | 
					    return createElement(
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,3 @@
 | 
				
			|||||||
window.arm_config = {
 | 
					window.arm_config = {
 | 
				
			||||||
  url: 'ws://127.0.0.1:8080/ws'
 | 
					  url: 'ws://192.168.2.85:8080/ws'
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user