mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Msp dashboard: Add syncing overlay. (#23311)
Related to: https://github.com/fleetdm/confidential/issues/8602 Changes: - Added a syncing overlay when the dashboard gathers an updated list of software, profiles, and scripts from a Fleet instance.
This commit is contained in:
parent
6e9955d7c7
commit
48578a0a32
10 changed files with 131 additions and 7 deletions
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* <ajax-overlay>
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* @type {Component}
|
||||
*
|
||||
* --- SLOTS: ---
|
||||
* N/A
|
||||
*
|
||||
* --- EVENTS EMITTED: ---
|
||||
* N/A
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
parasails.registerComponent('ajaxOverlay', {
|
||||
|
||||
// ╔═╗╦ ╦╔╗ ╦ ╦╔═╗ ╔═╗╦═╗╔═╗╔═╗╔═╗
|
||||
// ╠═╝║ ║╠╩╗║ ║║ ╠═╝╠╦╝║ ║╠═╝╚═╗
|
||||
// ╩ ╚═╝╚═╝╩═╝╩╚═╝ ╩ ╩╚═╚═╝╩ ╚═╝
|
||||
props: [
|
||||
'syncing',
|
||||
'syncingMessage'
|
||||
],
|
||||
|
||||
// ╦╔╗╔╦╔╦╗╦╔═╗╦ ╦╔╗╔╔╦╗╔═╗╦═╗╔╗╔╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗
|
||||
// ║║║║║ ║ ║╠═╣║ ║║║║ ║ ║╣ ╠╦╝║║║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣
|
||||
// ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╩╝╚╝ ╩ ╚═╝╩╚═╝╚╝╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
|
||||
data: function () {
|
||||
return {
|
||||
//…
|
||||
};
|
||||
},
|
||||
|
||||
beforeMount: function() {
|
||||
//…
|
||||
},
|
||||
|
||||
// ╦ ╦╔╦╗╔╦╗╦
|
||||
// ╠═╣ ║ ║║║║
|
||||
// ╩ ╩ ╩ ╩ ╩╩═╝
|
||||
template: `
|
||||
<div style="top: 0; left: 0; background-color: rgba(255,255,255,0.75); z-index: 1000;" class="position-fixed w-100 h-100" :class="syncing? '' : 'd-none'">
|
||||
<div class="row h-100">
|
||||
<div class="col h-100"></div>
|
||||
<div class="col-6 col-md-4 h-100">
|
||||
<div class="d-flex flex-column h-100 justify-content-center">
|
||||
<div class="py-5 text-center">
|
||||
<h2 purpose="syncing-message" class="text-dark" v-if="syncingMessage">{{syncingMessage}}</h2>
|
||||
<span purpose="loading-indicator">
|
||||
<span class="loading-dot dot1"></span>
|
||||
<span class="loading-dot dot2"></span>
|
||||
<span class="loading-dot dot3"></span>
|
||||
<span class="loading-dot dot4"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col h-100"></div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
|
||||
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
|
||||
mounted: async function () {
|
||||
//…
|
||||
},
|
||||
|
||||
beforeDestroy: function() {
|
||||
//…
|
||||
},
|
||||
|
||||
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
|
||||
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
|
||||
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
|
||||
methods: {
|
||||
|
||||
// ╦╔╗╔╔╦╗╔═╗╦═╗╔╗╔╔═╗╦ ╔═╗╦ ╦╔═╗╔╗╔╔╦╗ ╦ ╦╔═╗╔╗╔╔╦╗╦ ╔═╗╦═╗╔═╗
|
||||
// ║║║║ ║ ║╣ ╠╦╝║║║╠═╣║ ║╣ ╚╗╔╝║╣ ║║║ ║ ╠═╣╠═╣║║║ ║║║ ║╣ ╠╦╝╚═╗
|
||||
// ╩╝╚╝ ╩ ╚═╝╩╚═╝╚╝╩ ╩╩═╝ ╚═╝ ╚╝ ╚═╝╝╚╝ ╩ ╩ ╩╩ ╩╝╚╝═╩╝╩═╝╚═╝╩╚═╚═╝
|
||||
|
||||
//…
|
||||
|
||||
// ╔═╗╦ ╦╔╗ ╦ ╦╔═╗ ╔╦╗╔═╗╔╦╗╦ ╦╔═╗╔╦╗╔═╗
|
||||
// ╠═╝║ ║╠╩╗║ ║║ ║║║║╣ ║ ╠═╣║ ║ ║║╚═╗
|
||||
// ╩ ╚═╝╚═╝╩═╝╩╚═╝ ╩ ╩╚═╝ ╩ ╩ ╩╚═╝═╩╝╚═╝
|
||||
// > Public methods are rarely exposed by Vue components, but sometimes they
|
||||
// > are an important escape hatch. They are callable via something like
|
||||
// > `this.$refs.ajaxOverlay.doSomething())`, and, by convention, are always
|
||||
// > prefixed with "do".
|
||||
// N/A
|
||||
|
||||
// ╔═╗╦═╗╦╦ ╦╔═╗╔╦╗╔═╗ ╔╦╗╔═╗╔╦╗╦ ╦╔═╗╔╦╗╔═╗
|
||||
// ╠═╝╠╦╝║╚╗╔╝╠═╣ ║ ║╣ ║║║║╣ ║ ╠═╣║ ║ ║║╚═╗
|
||||
// ╩ ╩╚═╩ ╚╝ ╩ ╩ ╩ ╚═╝ ╩ ╩╚═╝ ╩ ╩ ╩╚═╝═╩╝╚═╝
|
||||
|
||||
//…
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -23,6 +23,8 @@ parasails.registerPage('profiles', {
|
|||
profileToEdit: {},
|
||||
cloudError: '',
|
||||
newProfile: undefined,
|
||||
syncingMessage: '',
|
||||
overlaySyncing: false,
|
||||
},
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
|
|
@ -118,10 +120,11 @@ parasails.registerPage('profiles', {
|
|||
await this._getProfiles();
|
||||
},
|
||||
_getProfiles: async function() {
|
||||
this.syncing = true;
|
||||
this.overlaySyncing = true;
|
||||
this.syncingMessage = 'Gathering profiles';
|
||||
let newProfilesInformation = await Cloud.getProfiles();
|
||||
this.profiles = newProfilesInformation;
|
||||
this.syncing = false;
|
||||
this.overlaySyncing = false;
|
||||
await this.changeTeamFilter();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ parasails.registerPage('scripts', {
|
|||
profileToEdit: {},
|
||||
cloudError: '',
|
||||
newScript: undefined,
|
||||
syncingMessage: '',
|
||||
overlaySyncing: '',
|
||||
},
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
|
|
@ -110,10 +112,11 @@ parasails.registerPage('scripts', {
|
|||
await this._getScripts();
|
||||
},
|
||||
_getScripts: async function() {
|
||||
this.syncing = true;
|
||||
this.overlaySyncing = true;
|
||||
this.syncingMessage = 'Gathering scripts';
|
||||
let newScriptsInformation = await Cloud.getScripts();
|
||||
this.scripts = newScriptsInformation;
|
||||
this.syncing = false;
|
||||
this.overlaySyncing = false;
|
||||
await this.changeTeamFilter();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ parasails.registerPage('software', {
|
|||
newSoftware: undefined,
|
||||
showAdvancedOptions: false,
|
||||
newSoftwareFilename: undefined,
|
||||
|
||||
syncingMessage: '',
|
||||
overlaySyncing: false,
|
||||
},
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
|
|
@ -136,10 +137,11 @@ parasails.registerPage('software', {
|
|||
}
|
||||
},
|
||||
_getSoftware: async function() {
|
||||
this.syncing = true;
|
||||
this.overlaySyncing = true;
|
||||
this.syncingMessage = 'Gathering software';
|
||||
let newSoftwareInformation = await Cloud.getSoftware();
|
||||
this.software = newSoftwareInformation;
|
||||
this.syncing = false;
|
||||
this.overlaySyncing = false;
|
||||
await this.changeTeamFilter();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* <ajax-overlay>
|
||||
*/
|
||||
[parasails-component='ajax-overlay'] {
|
||||
[purpose='loading-indicator'] {
|
||||
.loader(@brand);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
// Per-component styles
|
||||
@import 'components/stripe-card-element.component.less';
|
||||
@import 'components/ajax-button.component.less';
|
||||
@import 'components/ajax-overlay.component.less';
|
||||
@import 'components/modal.component.less';
|
||||
@import 'components/cloud-error.component.less';
|
||||
@import 'components/multifield.component.less';
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@
|
|||
<script src="/js/components/ace-editor.component.js"></script>
|
||||
<script src="/js/components/ajax-button.component.js"></script>
|
||||
<script src="/js/components/ajax-form.component.js"></script>
|
||||
<script src="/js/components/ajax-overlay.component.js"></script>
|
||||
<script src="/js/components/cloud-error.component.js"></script>
|
||||
<script src="/js/components/file-upload.component.js"></script>
|
||||
<script src="/js/components/js-timestamp.component.js"></script>
|
||||
|
|
|
|||
|
|
@ -150,5 +150,6 @@
|
|||
</ajax-form>
|
||||
</div>
|
||||
</modal>
|
||||
<ajax-overlay :syncing-message="syncingMessage" :syncing="overlaySyncing"></ajax-overlay>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
|
|
|||
|
|
@ -160,5 +160,6 @@
|
|||
</ajax-form>
|
||||
</div>
|
||||
</modal>
|
||||
<ajax-overlay :syncing-message="syncingMessage" :syncing="overlaySyncing"></ajax-overlay>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
|
|
|||
|
|
@ -196,5 +196,6 @@
|
|||
</ajax-form>
|
||||
</div>
|
||||
</modal>
|
||||
<ajax-overlay :syncing-message="syncingMessage" :syncing="overlaySyncing"></ajax-overlay>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
|
|
|||
Loading…
Reference in a new issue