Add track editing support to track view model

This commit is contained in:
Bartek Fabiszewski 2019-12-29 13:54:26 +01:00
parent 069eab1f63
commit cb5405a9d5
3 changed files with 96 additions and 3 deletions

View File

@ -18,6 +18,7 @@
*/
import { lang as $, auth, config } from './initializer.js';
import TrackDialogModel from './trackdialogmodel.js';
import ViewModel from './viewmodel.js';
import uObserve from './observe.js';
import uPositionSet from './positionset.js';
@ -55,12 +56,15 @@ export default class TrackViewModel extends ViewModel {
/** @type {function} */
onExportKml: null,
/** @type {function} */
onImportGpx: null
onImportGpx: null,
/** @type {function} */
onTrackEdit: null
});
this.setClickHandlers();
/** @type HTMLSelectElement */
const listEl = document.querySelector('#track');
this.importEl = document.querySelector('#input-file');
this.editEl = this.getBoundElement('onTrackEdit');
this.select = new uSelect(listEl);
this.state = state;
this.timerId = 0;
@ -93,9 +97,11 @@ export default class TrackViewModel extends ViewModel {
this.state.onChanged('currentUser', (user) => {
if (user) {
this.loadTrackList();
TrackViewModel.setMenuVisible(this.editEl, true);
} else {
this.model.currentTrackId = '';
this.model.trackList = [];
TrackViewModel.setMenuVisible(this.editEl, false);
}
});
this.state.onChanged('currentTrack', (track) => {
@ -129,6 +135,7 @@ export default class TrackViewModel extends ViewModel {
this.model.onExportGpx = exportCb('gpx');
this.model.onExportKml = exportCb('kml');
this.model.onImportGpx = () => this.importEl.click();
this.model.onTrackEdit = () => this.showDialog();
}
/**
@ -264,6 +271,24 @@ export default class TrackViewModel extends ViewModel {
.catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
}
showDialog() {
const vm = new TrackDialogModel(this);
vm.init();
}
onTrackDeleted() {
const index = this.model.trackList.indexOf(this.state.currentTrack);
this.state.currentTrack = null;
if (index !== -1) {
this.model.trackList.splice(index, 1);
if (this.model.trackList.length) {
this.model.currentTrackId = this.model.trackList[index].listValue;
} else {
this.model.currentTrackId = '';
}
}
}
/**
* @param {boolean} start
*/
@ -285,6 +310,14 @@ export default class TrackViewModel extends ViewModel {
this.model.autoReload = false;
}
static setMenuVisible(el, visible) {
if (visible) {
el.classList.remove('menu-hidden');
} else {
el.classList.add('menu-hidden');
}
}
renderSummary() {
if (!this.state.currentTrack || !this.state.currentTrack.hasPositions) {
this.model.summary = '';

View File

@ -51,6 +51,8 @@ describe('TrackViewModel tests', () => {
let autoReloadEl;
/** @type {HTMLInputElement} */
let inputFileEl;
/** @type {HTMLAnchorElement} */
let trackEditEl;
let tracks;
let track1;
let track2;
@ -78,6 +80,7 @@ describe('TrackViewModel tests', () => {
forceReloadEl = document.querySelector('#force-reload');
inputFileEl = document.querySelector('#input-file');
autoReloadEl = document.querySelector('#auto-reload');
trackEditEl = document.querySelector('#edittrack');
const maxEl = document.querySelector('input[name="MAX_FILE_SIZE"]');
maxEl.value = MAX_FILE_SIZE;
state = new uState();
@ -257,7 +260,6 @@ describe('TrackViewModel tests', () => {
}, 100);
});
it('should load user latest position when "show latest" is checked and select respective track in list', (done) => {
// given
positions[0].trackid = track2.id;
@ -604,6 +606,64 @@ describe('TrackViewModel tests', () => {
}, 100);
});
it('should show user edit dialog on button click', (done) => {
// given
spyOn(vm, 'showDialog');
// when
vm.bindAll();
trackEditEl.click();
// then
setTimeout(() => {
expect(vm.showDialog).toHaveBeenCalledTimes(1);
done();
}, 100);
});
it('should remove current track from track list and set new current track id', () => {
// given
vm.model.trackList = [ track1, track2 ];
vm.state.currentTrack = track1;
vm.model.currentTrackId = track1.listValue;
// when
vm.onTrackDeleted();
// then
expect(vm.model.trackList.length).toBe(1);
expect(vm.model.currentTrackId).toBe(track2.listValue);
expect(vm.state.currentTrack).toBe(null);
});
it('should remove last remaining element from track list and set empty track id', () => {
// given
vm.model.trackList = [ track1 ];
vm.state.currentTrack = track1;
vm.model.currentTrackId = track1.listValue;
// when
vm.onTrackDeleted();
// then
expect(vm.model.trackList.length).toBe(0);
expect(vm.model.currentTrackId).toBe('');
expect(vm.state.currentTrack).toBe(null);
});
it('show hide element', () => {
// given
const element = document.createElement('div');
// when
TrackViewModel.setMenuVisible(element, false);
// then
expect(element.classList.contains('menu-hidden')).toBe(true);
});
it('show shown hidden element', () => {
// given
const element = document.createElement('div');
element.classList.add('menu-hidden');
// when
TrackViewModel.setMenuVisible(element, true);
// then
expect(element.classList.contains('menu-hidden')).toBe(false);
});
describe('on reload clicked', () => {
it('should reload selected track', (done) => {

View File

@ -36,7 +36,7 @@
}
$track = new uTrack($trackId);
if (!$track->isValid ||
(!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id != $track->userId))) {
(!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $track->userId))) {
uUtils::exitWithError($lang["servererror"]);
}