misc_pterodactyl-panel/resources/assets/scripts/components/dashboard/Dashboard.vue
Dane Everitt be5a9108f9
Dont refresh server statuses unless the page is active
Reduces the number of polling requests happening on the server by only sending those requests if the user is actively viewing the dashboard.

There was no point in updating the resource usage if no one is viewing it. After 30 seconds away from the window when a user comes back it will update instantenously, otherwise it'll just update after 5 seconds.
2018-06-02 22:23:54 -07:00

166 lines
6 KiB
Vue

<template>
<div>
<flash container="mt-4"/>
<div class="server-search animate fadein">
<input type="text"
:placeholder="$t('dashboard.index.search')"
@input="onChange"
v-model="search"
ref="search"
/>
</div>
<div v-if="this.loading" class="my-4 animate fadein">
<div class="text-center h-16">
<span class="spinner spinner-xl"></span>
</div>
</div>
<transition-group class="w-full m-auto mt-4 animate fadein sm:flex flex-wrap content-start" v-else>
<server-box
v-for="(server, index) in servers.models"
v-bind:key="index"
v-bind:server="server"
/>
</transition-group>
</div>
</template>
<script>
import { DateTime } from 'luxon';
import { ServerCollection } from '../../models/server';
import _ from 'lodash';
import Flash from '../Flash';
import ServerBox from './ServerBox';
export default {
name: 'dashboard',
components: { ServerBox, Flash },
data: function () {
return {
backgroundedAt: DateTime.local(),
documentVisible: true,
loading: true,
search: '',
servers: new ServerCollection,
}
},
/**
* Start loading the servers before the DOM $.el is created.
*/
created: function () {
this.loadServers();
document.addEventListener('visibilitychange', () => {
this.documentVisible = document.visibilityState === 'visible';
this._handleDocumentVisibilityChange(this.documentVisible);
});
},
/**
* Once the page is mounted set a function to run every 5 seconds that will
* iterate through the visible servers and fetch their resource usage.
*/
mounted: function () {
this._iterateServerResourceUse();
},
methods: {
/**
* Load the user's servers and render them onto the dashboard.
*
* @param {string} query
*/
loadServers: function (query = '') {
this.loading = true;
window.axios.get(this.route('api.client.index'), {
params: { query },
})
.finally(() => {
this.clearFlashes();
})
.then(response => {
this.servers = new ServerCollection;
response.data.data.forEach(obj => {
this.getResourceUse(
this.servers.add(obj.attributes)
);
});
if (this.servers.models.length === 0) {
this.info(this.$t('dashboard.index.no_matches'));
}
})
.catch(err => {
console.error(err);
const response = err.response;
if (response.data && _.isObject(response.data.errors)) {
response.data.errors.forEach(function (error) {
this.error(error.detail);
});
}
})
.finally(() => {
this.loading = false;
});
},
/**
* Handle a search for servers but only call the search function every 500ms
* at the fastest.
*/
onChange: _.debounce(function () {
this.loadServers(this.$data.search);
}, 500),
/**
* Get resource usage for an individual server for rendering purposes.
*
* @param {Server} server
*/
getResourceUse: function (server) {
window.axios.get(this.route('api.client.servers.resources', { server: server.identifier }))
.then(response => {
if (!(response.data instanceof Object)) {
throw new Error('Received an invalid response object back from status endpoint.');
}
window.events.$emit(`server:${server.uuid}::resources`, response.data.attributes);
})
.catch(err => {
console.error(err);
});
},
/**
* Iterates over all of the active servers and gets their resource usage.
*
* @private
*/
_iterateServerResourceUse: function (initialTimeout = 5000) {
window.setTimeout(() => {
if (this.documentVisible) {
return window.setTimeout(this._iterateServerResourceUse(), 5000);
}
}, initialTimeout);
},
/**
* Handle changes to document visibilty to keep server statuses updated properly.
*
* @param {Boolean} isVisible
* @private
*/
_handleDocumentVisibilityChange: function (isVisible) {
if (!isVisible) {
this.backgroundedAt = DateTime.local();
return;
}
// If it has been more than 30 seconds since this window was put into the background
// lets go ahead and refresh all of the listed servers so that they have fresh stats.
const diff = DateTime.local().diff(this.backgroundedAt, 'seconds');
this._iterateServerResourceUse(diff.seconds > 30 ? 1 : 5000);
},
}
};
</script>