Refactors all Glances widgets to inherit from parent mixin

This commit is contained in:
Alicia Sykes 2022-01-19 11:43:04 +00:00
parent ea3ffa5d36
commit dfea4e317c
14 changed files with 75 additions and 107 deletions

View File

@ -1187,11 +1187,13 @@ All Glance's based widgets require a `hostname`
**Field** | **Type** | **Required** | **Description** **Field** | **Type** | **Required** | **Description**
--- | --- | --- | --- --- | --- | --- | ---
**`hostname`** | `string` | Required | The URL to your Glances instance (without a trailing slash) **`hostname`** | `string` | Required | The URL to your Glances instance (without a trailing slash)
**`username`** | `string` | _Optional_ | If you have setup basic auth on Glances, specify username here (defaults to `glances`)
**`password`** | `string` | _Optional_ | If you have setup basic auth on Glances, specify password here. **Note**: since this password is in plaintext, it is important not to reuse it anywhere else
##### Info ##### Info
- **CORS**: 🟢 Enabled - **CORS**: 🟢 Enabled
- **Auth**: 🟢 Not Required - **Auth**: 🟠 Optional
- **Price**: 🟢 Free - **Price**: 🟢 Free
- **Host**: Self-Hosted (see [GitHub - Nicolargo/Glances](https://github.com/nicolargo/glances)) - **Host**: Self-Hosted (see [GitHub - Nicolargo/Glances](https://github.com/nicolargo/glances))
- **Privacy**: ⚫ No Policy Available - **Privacy**: ⚫ No Policy Available

View File

@ -20,10 +20,11 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import { timestampToDateTime, getTimeAgo, getTimeDifference } from '@/utils/MiscHelpers'; import { timestampToDateTime, getTimeAgo, getTimeDifference } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
data() { data() {
return { return {
alerts: null, alerts: null,
@ -31,19 +32,12 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/alert`; return this.makeGlancesUrl('alert');
}, },
}, },
filters: {}, filters: {},
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(alertData) { processData(alertData) {
if (!alertData || alertData.length === 0) { if (!alertData || alertData.length === 0) {
this.noResults = true; this.noResults = true;

View File

@ -8,11 +8,12 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import { capitalize } from '@/utils/MiscHelpers'; import { capitalize } from '@/utils/MiscHelpers';
import PercentageChart from '@/components/Charts/PercentageChart'; import PercentageChart from '@/components/Charts/PercentageChart';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
components: { components: {
PercentageChart, PercentageChart,
}, },
@ -22,12 +23,8 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/quicklook`; return this.makeGlancesUrl('quicklook');
}, },
}, },
created() { created() {
@ -35,9 +32,6 @@ export default {
this.overrideUpdateInterval = 2; this.overrideUpdateInterval = 2;
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
/* Converts returned data into format for the percentage charts */ /* Converts returned data into format for the percentage charts */
processData(cpuData) { processData(cpuData) {
const cpuSections = []; const cpuSections = [];

View File

@ -17,11 +17,12 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import GaugeChart from '@/components/Charts/Gauge'; import GaugeChart from '@/components/Charts/Gauge';
import { getValueFromCss, capitalize } from '@/utils/MiscHelpers'; import { getValueFromCss, capitalize } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
components: { components: {
GaugeChart, GaugeChart,
}, },
@ -35,18 +36,11 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/cpu`; return this.makeGlancesUrl('cpu');
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(cpuData) { processData(cpuData) {
this.gaugeValue = cpuData.total; this.gaugeValue = cpuData.total;
this.gaugeColor = this.getColor(cpuData.total); this.gaugeColor = this.getColor(cpuData.total);

View File

@ -6,31 +6,25 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import ChartingMixin from '@/mixins/ChartingMixin'; import ChartingMixin from '@/mixins/ChartingMixin';
import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers'; import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin, ChartingMixin], mixins: [WidgetMixin, GlancesMixin, ChartingMixin],
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
limit() { limit() {
return this.options.limit || 100; return this.options.limit || 100;
}, },
endpoint() { endpoint() {
return `${this.hostname}/api/3/cpu/history/${this.limit}`; return this.makeGlancesUrl(`cpu/history/${this.limit}`);
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(cpuData) { processData(cpuData) {
const { system, user } = cpuData; const { system, user } = cpuData;
const labels = []; const labels = [];

View File

@ -20,10 +20,11 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import { convertBytes } from '@/utils/MiscHelpers'; import { convertBytes } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
data() { data() {
return { return {
disks: null, disks: null,
@ -31,12 +32,8 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/diskio`; return this.makeGlancesUrl('diskio');
}, },
}, },
filters: { filters: {
@ -51,9 +48,6 @@ export default {
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(diskData) { processData(diskData) {
this.previous = this.disks; this.previous = this.disks;
const disks = []; const disks = [];

View File

@ -18,11 +18,12 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import PercentageChart from '@/components/Charts/PercentageChart'; import PercentageChart from '@/components/Charts/PercentageChart';
import { getValueFromCss, convertBytes } from '@/utils/MiscHelpers'; import { getValueFromCss, convertBytes } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
components: { components: {
PercentageChart, PercentageChart,
}, },
@ -32,12 +33,8 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/fs`; return this.makeGlancesUrl('fs');
}, },
}, },
filters: { filters: {

View File

@ -6,31 +6,25 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import ChartingMixin from '@/mixins/ChartingMixin'; import ChartingMixin from '@/mixins/ChartingMixin';
import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers'; import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin, ChartingMixin], mixins: [WidgetMixin, GlancesMixin, ChartingMixin],
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
limit() { limit() {
return this.options.limit || 500; return this.options.limit || 500;
}, },
endpoint() { endpoint() {
return `${this.hostname}/api/3/load/history/${this.limit}`; return this.makeGlancesUrl(`load/history/${this.limit}`);
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(loadData) { processData(loadData) {
const labels = []; const labels = [];
const min1 = []; const min1 = [];

View File

@ -17,11 +17,12 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import GaugeChart from '@/components/Charts/Gauge'; import GaugeChart from '@/components/Charts/Gauge';
import { getValueFromCss, capitalize, convertBytes } from '@/utils/MiscHelpers'; import { getValueFromCss, capitalize, convertBytes } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
components: { components: {
GaugeChart, GaugeChart,
}, },
@ -35,18 +36,11 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/mem`; return this.makeGlancesUrl('mem');
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(memData) { processData(memData) {
this.gaugeValue = memData.percent; this.gaugeValue = memData.percent;
this.gaugeColor = this.getColor(memData.percent); this.gaugeColor = this.getColor(memData.percent);

View File

@ -6,31 +6,25 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import ChartingMixin from '@/mixins/ChartingMixin'; import ChartingMixin from '@/mixins/ChartingMixin';
import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers'; import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin, ChartingMixin], mixins: [WidgetMixin, GlancesMixin, ChartingMixin],
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
limit() { limit() {
return this.options.limit || 100; return this.options.limit || 100;
}, },
endpoint() { endpoint() {
return `${this.hostname}/api/3/mem/history/${this.limit}`; return this.makeGlancesUrl(`mem/history/${this.limit}`);
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(memData) { processData(memData) {
const readings = memData.percent; const readings = memData.percent;
const labels = []; const labels = [];
@ -67,7 +61,6 @@ export default {
}, },
tooltipOptions: { tooltipOptions: {
formatTooltipY: d => `${Math.round(d)}%`, formatTooltipY: d => `${Math.round(d)}%`,
// formatTooltipX: d => timestampToTime(d),
}, },
}); });
}, },

View File

@ -30,10 +30,11 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import { convertBytes } from '@/utils/MiscHelpers'; import { convertBytes } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin], mixins: [WidgetMixin, GlancesMixin],
data() { data() {
return { return {
networks: null, networks: null,
@ -41,12 +42,8 @@ export default {
}; };
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/network`; return this.makeGlancesUrl('network');
}, },
}, },
filters: { filters: {
@ -64,9 +61,6 @@ export default {
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(networkData) { processData(networkData) {
this.previous = this.disks; this.previous = this.disks;
const networks = []; const networks = [];

View File

@ -6,31 +6,25 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import ChartingMixin from '@/mixins/ChartingMixin'; import ChartingMixin from '@/mixins/ChartingMixin';
import { convertBytes, getTimeAgo, timestampToTime } from '@/utils/MiscHelpers'; import { convertBytes, getTimeAgo, timestampToTime } from '@/utils/MiscHelpers';
export default { export default {
mixins: [WidgetMixin, ChartingMixin], mixins: [WidgetMixin, GlancesMixin, ChartingMixin],
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
limit() { limit() {
return this.options.limit || 100; return this.options.limit || 100;
}, },
endpoint() { endpoint() {
return `${this.hostname}/api/3/network/history/${this.limit}`; return this.makeGlancesUrl(`network/history/${this.limit}`);
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(trafficData) { processData(trafficData) {
const preliminary = { const preliminary = {
upload: [], upload: [],

View File

@ -8,23 +8,17 @@
<script> <script>
import WidgetMixin from '@/mixins/WidgetMixin'; import WidgetMixin from '@/mixins/WidgetMixin';
import GlancesMixin from '@/mixins/GlancesMixin';
import ChartingMixin from '@/mixins/ChartingMixin'; import ChartingMixin from '@/mixins/ChartingMixin';
export default { export default {
mixins: [WidgetMixin, ChartingMixin], mixins: [WidgetMixin, GlancesMixin, ChartingMixin],
computed: { computed: {
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
endpoint() { endpoint() {
return `${this.hostname}/api/3/load`; return this.makeGlancesUrl('load');
}, },
}, },
methods: { methods: {
fetchData() {
this.makeRequest(this.endpoint).then(this.processData);
},
processData(loadData) { processData(loadData) {
const chartData = { const chartData = {
labels: ['1 Min', '5 Mins', '15 Mins'], labels: ['1 Min', '5 Mins', '15 Mins'],

View File

@ -0,0 +1,36 @@
/** Reusable mixin for all Glances widgets */
const WidgetMixin = {
computed: {
/* Required, hostname (e.g. IP + port) for Glances instance */
hostname() {
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
return this.options.hostname;
},
/* Optionally specify the API version, defaults to V 3 */
apiVersion() {
return this.options.apiVersion || 3;
},
/* Optionally specify basic auth credentials for Glances instance */
credentials() {
if (this.options.username && this.options.password) {
const stringifiedUser = `${this.options.username}:${this.options.password}`;
const headers = { Authorization: `Basic ${window.btoa(stringifiedUser)}` };
return { headers };
}
return null;
},
},
methods: {
/* Make the request to Glances API, and calls handler function with results
* Requires endpoint attribute and processData method to be implemented by child */
fetchData() {
this.makeRequest(this.endpoint, this.credentials).then(this.processData);
},
/* Returns URL to Glances API endpoint */
makeGlancesUrl(apiPath) {
return `${this.hostname}/api/${this.apiVersion}/${apiPath}`;
},
},
};
export default WidgetMixin;