Add spinner
This commit is contained in:
parent
e3e524f406
commit
b8d5a92fc6
@ -472,16 +472,6 @@ button > * {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loader {
|
|
||||||
animation: blink 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink {
|
|
||||||
50% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#configForm label {
|
#configForm label {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -502,8 +492,6 @@ button > * {
|
|||||||
width: 150px;
|
width: 150px;
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,6 +514,8 @@ button > * {
|
|||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* alert */
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -545,6 +535,8 @@ button > * {
|
|||||||
border-top: 1px solid #555;
|
border-top: 1px solid #555;
|
||||||
box-shadow: 10px 10px 10px -8px rgba(0, 0, 0, 0.3);
|
box-shadow: 10px 10px 10px -8px rgba(0, 0, 0, 0.3);
|
||||||
z-index: 100000;
|
z-index: 100000;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert.error {
|
.alert.error {
|
||||||
@ -552,6 +544,14 @@ button > * {
|
|||||||
border-top: 1px solid #d05858;
|
border-top: 1px solid #d05858;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert.in {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.out {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.alert button {
|
.alert button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
@ -564,6 +564,67 @@ button > * {
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert.spinner {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.spinner > span {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #9880ff;
|
||||||
|
color: #9880ff;
|
||||||
|
animation: spinner-dot 1s infinite linear alternate;
|
||||||
|
animation-delay: 0.5s;
|
||||||
|
transform: translateZ(0);
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
-ms-transform: translateZ(0);
|
||||||
|
will-change: transform, opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.spinner > span::after {
|
||||||
|
left: 15px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #9880ff;
|
||||||
|
color: #9880ff;
|
||||||
|
animation: spinner-dot 1s infinite alternate;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.spinner > span::before, .alert.spinner > span::after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.spinner > span::before {
|
||||||
|
left: -15px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #9880ff;
|
||||||
|
color: #9880ff;
|
||||||
|
animation: spinner-dot 1s infinite alternate;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinner-dot {
|
||||||
|
0% {
|
||||||
|
background-color: #9880ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
50%, 100% {
|
||||||
|
background-color: #ebe6ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* chart */
|
/* chart */
|
||||||
.ct-point {
|
.ct-point {
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
@ -592,7 +653,7 @@ button > * {
|
|||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* openlayers 3 popup */
|
/* openlayers popup */
|
||||||
.ol-popup {
|
.ol-popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 12px;
|
bottom: 12px;
|
||||||
|
@ -24,8 +24,10 @@ export default class uAlert {
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} AlertOptions
|
* @typedef {Object} AlertOptions
|
||||||
* @property {number} [autoClose=0] Optional autoclose delay time in ms, default 0 – no autoclose
|
* @property {number} [autoClose=0] Optional autoclose delay time in ms, default 0 – no autoclose
|
||||||
|
* @property {boolean} [hasButton] Optional can be closed by button click, default true when autoClose not set
|
||||||
* @property {string} [id] Optional box id
|
* @property {string} [id] Optional box id
|
||||||
* @property {string} [class] Optional box class
|
* @property {string} [class] Optional box class
|
||||||
|
* @property {boolean} [fixed=false] Optional set fixed position, default false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +37,8 @@ export default class uAlert {
|
|||||||
*/
|
*/
|
||||||
constructor(message, options = {}) {
|
constructor(message, options = {}) {
|
||||||
this.autoClose = options.autoClose || 0;
|
this.autoClose = options.autoClose || 0;
|
||||||
|
this.hasButton = typeof options.hasButton !== 'undefined' ? options.hasButton : this.autoClose === 0
|
||||||
|
this.fixedPosition = options.fixed || false;
|
||||||
const html = `<div class="alert"><span>${message}</span></div>`;
|
const html = `<div class="alert"><span>${message}</span></div>`;
|
||||||
this.box = uUtils.nodeFromHtml(html);
|
this.box = uUtils.nodeFromHtml(html);
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
@ -43,7 +47,7 @@ export default class uAlert {
|
|||||||
if (options.class) {
|
if (options.class) {
|
||||||
this.box.classList.add(options.class);
|
this.box.classList.add(options.class);
|
||||||
}
|
}
|
||||||
if (this.autoClose === 0) {
|
if (this.hasButton) {
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button');
|
||||||
button.setAttribute('type', 'button');
|
button.setAttribute('type', 'button');
|
||||||
button.textContent = '×';
|
button.textContent = '×';
|
||||||
@ -72,11 +76,18 @@ export default class uAlert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (!this.fixedPosition) {
|
||||||
const top = uAlert.getPosition();
|
const top = uAlert.getPosition();
|
||||||
if (top) {
|
if (top) {
|
||||||
this.box.style.top = `${top}px`;
|
this.box.style.top = `${top}px`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
document.body.appendChild(this.box);
|
document.body.appendChild(this.box);
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.box) {
|
||||||
|
this.box.classList.add('in');
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@ -84,10 +95,14 @@ export default class uAlert {
|
|||||||
clearTimeout(this.closeHandle);
|
clearTimeout(this.closeHandle);
|
||||||
this.closeHandle = null;
|
this.closeHandle = null;
|
||||||
}
|
}
|
||||||
if (this.box) {
|
if (this.box && document.body.contains(this.box)) {
|
||||||
if (document.body.contains(this.box)) {
|
const element = this.box;
|
||||||
document.body.removeChild(this.box);
|
requestAnimationFrame(() => {
|
||||||
}
|
element.classList.add('out');
|
||||||
|
setTimeout(() => {
|
||||||
|
element.remove();
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
this.box = null;
|
this.box = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,4 +144,8 @@ export default class uAlert {
|
|||||||
return this.show(message, { class: 'toast', autoClose: 10000 });
|
return this.show(message, { class: 'toast', autoClose: 10000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static spinner() {
|
||||||
|
return this.show('', { class: 'spinner', hasButton: false, fixed: true });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -129,11 +129,18 @@ export default class GoogleMapsApi {
|
|||||||
* Display track
|
* Display track
|
||||||
* @param {uPositionSet} track
|
* @param {uPositionSet} track
|
||||||
* @param {boolean} update Should fit bounds if true
|
* @param {boolean} update Should fit bounds if true
|
||||||
|
* @return {Promise.<void>}
|
||||||
*/
|
*/
|
||||||
displayTrack(track, update) {
|
displayTrack(track, update) {
|
||||||
if (!track || !track.hasPositions) {
|
if (!track || !track.hasPositions) {
|
||||||
return;
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
const promise = new Promise((resolve) => {
|
||||||
|
google.maps.event.addListenerOnce(this.map, 'tilesloaded', () => {
|
||||||
|
console.log('tilesloaded');
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
});
|
||||||
// init polyline
|
// init polyline
|
||||||
const polyOptions = {
|
const polyOptions = {
|
||||||
strokeColor: config.strokeColor,
|
strokeColor: config.strokeColor,
|
||||||
@ -184,6 +191,7 @@ export default class GoogleMapsApi {
|
|||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -424,11 +424,18 @@ export default class OpenLayersApi {
|
|||||||
* Display track
|
* Display track
|
||||||
* @param {uPositionSet} track Track
|
* @param {uPositionSet} track Track
|
||||||
* @param {boolean} update Should fit bounds if true
|
* @param {boolean} update Should fit bounds if true
|
||||||
|
* @return {Promise.<void>}
|
||||||
*/
|
*/
|
||||||
displayTrack(track, update) {
|
displayTrack(track, update) {
|
||||||
if (!track || !track.hasPositions) {
|
if (!track || !track.hasPositions) {
|
||||||
return;
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
const promise = new Promise((resolve) => {
|
||||||
|
this.map.once('rendercomplete', () => {
|
||||||
|
console.log('rendercomplete');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
let start = this.layerMarkers ? this.layerMarkers.getSource().getFeatures().length : 0;
|
let start = this.layerMarkers ? this.layerMarkers.getSource().getFeatures().length : 0;
|
||||||
if (start > 0) {
|
if (start > 0) {
|
||||||
this.removePoint(--start);
|
this.removePoint(--start);
|
||||||
@ -457,6 +464,7 @@ export default class OpenLayersApi {
|
|||||||
extent = this.fitToExtent(extent);
|
extent = this.fitToExtent(extent);
|
||||||
}
|
}
|
||||||
this.setZoomToExtent(extent);
|
this.setZoomToExtent(extent);
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,7 +120,7 @@ export default class MapViewModel extends ViewModel {
|
|||||||
this.api.zoomToBounds(this.savedBounds);
|
this.api.zoomToBounds(this.savedBounds);
|
||||||
}
|
}
|
||||||
if (this.state.currentTrack) {
|
if (this.state.currentTrack) {
|
||||||
this.api.displayTrack(this.state.currentTrack, this.savedBounds === null);
|
this.displayTrack(this.state.currentTrack, this.savedBounds === null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,14 +135,20 @@ export default class MapViewModel extends ViewModel {
|
|||||||
this.api.clearMap();
|
this.api.clearMap();
|
||||||
if (track) {
|
if (track) {
|
||||||
uObserve.observe(track, 'positions', () => {
|
uObserve.observe(track, 'positions', () => {
|
||||||
this.api.displayTrack(track, false);
|
this.displayTrack(track, false);
|
||||||
this.api.zoomToExtent();
|
this.api.zoomToExtent();
|
||||||
});
|
});
|
||||||
this.api.displayTrack(track, true);
|
this.displayTrack(track, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
displayTrack(track, update) {
|
||||||
|
this.state.jobStart();
|
||||||
|
this.api.displayTrack(track, update)
|
||||||
|
.finally(() => this.state.jobStop());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get popup html
|
* Get popup html
|
||||||
* @param {number} id Position index
|
* @param {number} id Position index
|
||||||
|
42
js/src/spinner.js
Normal file
42
js/src/spinner.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* μlogger
|
||||||
|
*
|
||||||
|
* Copyright(C) 2020 Bartek Fabiszewski (www.fabiszewski.net)
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import uAlert from './alert.js';
|
||||||
|
|
||||||
|
export default class uSpinner {
|
||||||
|
|
||||||
|
constructor(state) {
|
||||||
|
this.spinner = null;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.state.onChanged('activeJobs', (jobs) => {
|
||||||
|
if (jobs > 0) {
|
||||||
|
if (!this.spinner) {
|
||||||
|
this.spinner = uAlert.spinner();
|
||||||
|
}
|
||||||
|
} else if (this.spinner) {
|
||||||
|
this.spinner.destroy();
|
||||||
|
this.spinner = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ import uObserve from './observe.js';
|
|||||||
* @property {?uUser} currentUser
|
* @property {?uUser} currentUser
|
||||||
* @property {boolean} showLatest
|
* @property {boolean} showLatest
|
||||||
* @property {boolean} showAllUsers
|
* @property {boolean} showAllUsers
|
||||||
|
* @property {number} activeJobs
|
||||||
*/
|
*/
|
||||||
export default class uState {
|
export default class uState {
|
||||||
|
|
||||||
@ -33,6 +34,15 @@ export default class uState {
|
|||||||
this.currentUser = null;
|
this.currentUser = null;
|
||||||
this.showLatest = false;
|
this.showLatest = false;
|
||||||
this.showAllUsers = false;
|
this.showAllUsers = false;
|
||||||
|
this.activeJobs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobStart() {
|
||||||
|
this.activeJobs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobStop() {
|
||||||
|
this.activeJobs--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,6 +173,7 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
uAlert.error($._('notauthorized'));
|
uAlert.error($._('notauthorized'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.state.jobStart();
|
||||||
uTrack.import(form, auth.user)
|
uTrack.import(form, auth.user)
|
||||||
.then((trackList) => {
|
.then((trackList) => {
|
||||||
if (trackList.length) {
|
if (trackList.length) {
|
||||||
@ -186,6 +187,7 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
.catch((e) => uAlert.error(`${$._('actionfailure')}\n${e.message}`, e))
|
.catch((e) => uAlert.error(`${$._('actionfailure')}\n${e.message}`, e))
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.model.inputFile = '';
|
this.model.inputFile = '';
|
||||||
|
this.state.jobStop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +201,7 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
if (!track) {
|
if (!track) {
|
||||||
this.state.currentTrack = null;
|
this.state.currentTrack = null;
|
||||||
} else if (!track.isEqualTo(this.state.currentTrack)) {
|
} else if (!track.isEqualTo(this.state.currentTrack)) {
|
||||||
|
this.state.jobStart();
|
||||||
track.fetchPositions().then(() => {
|
track.fetchPositions().then(() => {
|
||||||
console.log(`currentTrack id: ${track.id}, loaded ${track.length} positions`);
|
console.log(`currentTrack id: ${track.id}, loaded ${track.length} positions`);
|
||||||
this.state.currentTrack = track;
|
this.state.currentTrack = track;
|
||||||
@ -206,7 +209,8 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.model.showLatest = false;
|
this.model.showLatest = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); });
|
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); })
|
||||||
|
.finally(() => this.state.jobStop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +247,7 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
* Handle last position of all users request
|
* Handle last position of all users request
|
||||||
*/
|
*/
|
||||||
loadAllUsersPosition() {
|
loadAllUsersPosition() {
|
||||||
|
this.state.jobStart();
|
||||||
uPositionSet.fetchLatest()
|
uPositionSet.fetchLatest()
|
||||||
.then((_track) => {
|
.then((_track) => {
|
||||||
if (_track) {
|
if (_track) {
|
||||||
@ -251,10 +256,12 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.state.currentTrack = _track;
|
this.state.currentTrack = _track;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); });
|
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); })
|
||||||
|
.finally(() => this.state.jobStop());
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTrackList() {
|
loadTrackList() {
|
||||||
|
this.state.jobStart();
|
||||||
uTrack.fetchList(this.state.currentUser)
|
uTrack.fetchList(this.state.currentUser)
|
||||||
.then((_tracks) => {
|
.then((_tracks) => {
|
||||||
this.model.trackList = _tracks;
|
this.model.trackList = _tracks;
|
||||||
@ -269,7 +276,8 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.model.currentTrackId = '';
|
this.model.currentTrackId = '';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); });
|
.catch((e) => { uAlert.error(`${$._('actionfailure')}\n${e.message}`, e); })
|
||||||
|
.finally(() => this.state.jobStop());
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialog() {
|
showDialog() {
|
||||||
|
@ -25,6 +25,7 @@ import MapViewModel from './mapviewmodel.js';
|
|||||||
import TrackViewModel from './trackviewmodel.js';
|
import TrackViewModel from './trackviewmodel.js';
|
||||||
import UserViewModel from './userviewmodel.js';
|
import UserViewModel from './userviewmodel.js';
|
||||||
import uAlert from './alert.js';
|
import uAlert from './alert.js';
|
||||||
|
import uSpinner from './spinner.js';
|
||||||
import uState from './state.js';
|
import uState from './state.js';
|
||||||
|
|
||||||
const domReady = uInitializer.waitForDom();
|
const domReady = uInitializer.waitForDom();
|
||||||
@ -39,13 +40,14 @@ Promise.all([ domReady, initReady ])
|
|||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
const state = new uState();
|
const state = new uState();
|
||||||
|
const spinner = new uSpinner(state);
|
||||||
const mainVM = new MainViewModel(state);
|
const mainVM = new MainViewModel(state);
|
||||||
const userVM = new UserViewModel(state);
|
const userVM = new UserViewModel(state);
|
||||||
const trackVM = new TrackViewModel(state);
|
const trackVM = new TrackViewModel(state);
|
||||||
const mapVM = new MapViewModel(state);
|
const mapVM = new MapViewModel(state);
|
||||||
const chartVM = new ChartViewModel(state);
|
const chartVM = new ChartViewModel(state);
|
||||||
const configVM = new ConfigViewModel(state);
|
const configVM = new ConfigViewModel(state);
|
||||||
|
spinner.init();
|
||||||
mainVM.init();
|
mainVM.init();
|
||||||
userVM.init();
|
userVM.init();
|
||||||
trackVM.init();
|
trackVM.init();
|
||||||
|
@ -24,6 +24,10 @@ describe('Alert tests', () => {
|
|||||||
const message = 'test message';
|
const message = 'test message';
|
||||||
let alert;
|
let alert;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(window, 'requestAnimationFrame').and.callFake((callback) => callback());
|
||||||
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
if (alert) {
|
if (alert) {
|
||||||
alert.destroy();
|
alert.destroy();
|
||||||
@ -79,6 +83,7 @@ describe('Alert tests', () => {
|
|||||||
|
|
||||||
it('should render and destroy alert box', () => {
|
it('should render and destroy alert box', () => {
|
||||||
// given
|
// given
|
||||||
|
spyOn(window, 'setTimeout').and.callFake((callback) => callback());
|
||||||
const id = 'testId';
|
const id = 'testId';
|
||||||
const options = { id }
|
const options = { id }
|
||||||
alert = new uAlert(message, options);
|
alert = new uAlert(message, options);
|
||||||
@ -96,6 +101,7 @@ describe('Alert tests', () => {
|
|||||||
|
|
||||||
it('should show and autoclose alert box', (done) => {
|
it('should show and autoclose alert box', (done) => {
|
||||||
// given
|
// given
|
||||||
|
jasmine.clock().install();
|
||||||
const id = 'testId';
|
const id = 'testId';
|
||||||
const options = { id: id, autoClose: 50 }
|
const options = { id: id, autoClose: 50 }
|
||||||
|
|
||||||
@ -103,7 +109,8 @@ describe('Alert tests', () => {
|
|||||||
alert = uAlert.show(message, options);
|
alert = uAlert.show(message, options);
|
||||||
// then
|
// then
|
||||||
expect(document.querySelector(`#${id}`)).not.toBeNull();
|
expect(document.querySelector(`#${id}`)).not.toBeNull();
|
||||||
|
jasmine.clock().tick(5000);
|
||||||
|
jasmine.clock().uninstall();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(document.querySelector(`#${id}`)).toBeNull();
|
expect(document.querySelector(`#${id}`)).toBeNull();
|
||||||
done();
|
done();
|
||||||
@ -112,12 +119,15 @@ describe('Alert tests', () => {
|
|||||||
|
|
||||||
it('should close alert box on close button click', (done) => {
|
it('should close alert box on close button click', (done) => {
|
||||||
// given
|
// given
|
||||||
|
jasmine.clock().install();
|
||||||
const id = 'testId';
|
const id = 'testId';
|
||||||
const options = { id }
|
const options = { id }
|
||||||
alert = uAlert.show(message, options);
|
alert = uAlert.show(message, options);
|
||||||
const closeButton = alert.box.querySelector('button');
|
const closeButton = alert.box.querySelector('button');
|
||||||
// when
|
// when
|
||||||
closeButton.click();
|
closeButton.click();
|
||||||
|
jasmine.clock().tick(5000);
|
||||||
|
jasmine.clock().uninstall();
|
||||||
// then
|
// then
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(document.querySelector(`#${id}`)).toBeNull();
|
expect(document.querySelector(`#${id}`)).toBeNull();
|
||||||
|
@ -281,7 +281,7 @@ describe('Google Maps map API tests', () => {
|
|||||||
expect(api.polies[0].path.length).toBe(track.length);
|
expect(api.polies[0].path.length).toBe(track.length);
|
||||||
expect(api.setMarker).toHaveBeenCalledTimes(track.length);
|
expect(api.setMarker).toHaveBeenCalledTimes(track.length);
|
||||||
expect(google.maps.Map.prototype.fitBounds).toHaveBeenCalledTimes(1);
|
expect(google.maps.Map.prototype.fitBounds).toHaveBeenCalledTimes(1);
|
||||||
expect(google.maps.event.addListenerOnce).not.toHaveBeenCalled();
|
expect(google.maps.event.addListenerOnce).toHaveBeenCalledTimes(1);
|
||||||
expect(setTimeout).not.toHaveBeenCalled();
|
expect(setTimeout).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ describe('MapViewModel tests', () => {
|
|||||||
'cleanup': { /* ignored */ },
|
'cleanup': { /* ignored */ },
|
||||||
'zoomToBounds': { /* ignored */ },
|
'zoomToBounds': { /* ignored */ },
|
||||||
'zoomToExtent': { /* ignored */ },
|
'zoomToExtent': { /* ignored */ },
|
||||||
'displayTrack': { /* ignored */ },
|
'displayTrack': Promise.resolve(),
|
||||||
'clearMap': { /* ignored */ },
|
'clearMap': { /* ignored */ },
|
||||||
'updateSize': { /* ignored */ }
|
'updateSize': { /* ignored */ }
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user