Add track editing support to track view model
This commit is contained in:
parent
069eab1f63
commit
cb5405a9d5
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { lang as $, auth, config } from './initializer.js';
|
import { lang as $, auth, config } from './initializer.js';
|
||||||
|
import TrackDialogModel from './trackdialogmodel.js';
|
||||||
import ViewModel from './viewmodel.js';
|
import ViewModel from './viewmodel.js';
|
||||||
import uObserve from './observe.js';
|
import uObserve from './observe.js';
|
||||||
import uPositionSet from './positionset.js';
|
import uPositionSet from './positionset.js';
|
||||||
@ -55,12 +56,15 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
/** @type {function} */
|
/** @type {function} */
|
||||||
onExportKml: null,
|
onExportKml: null,
|
||||||
/** @type {function} */
|
/** @type {function} */
|
||||||
onImportGpx: null
|
onImportGpx: null,
|
||||||
|
/** @type {function} */
|
||||||
|
onTrackEdit: null
|
||||||
});
|
});
|
||||||
this.setClickHandlers();
|
this.setClickHandlers();
|
||||||
/** @type HTMLSelectElement */
|
/** @type HTMLSelectElement */
|
||||||
const listEl = document.querySelector('#track');
|
const listEl = document.querySelector('#track');
|
||||||
this.importEl = document.querySelector('#input-file');
|
this.importEl = document.querySelector('#input-file');
|
||||||
|
this.editEl = this.getBoundElement('onTrackEdit');
|
||||||
this.select = new uSelect(listEl);
|
this.select = new uSelect(listEl);
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.timerId = 0;
|
this.timerId = 0;
|
||||||
@ -93,9 +97,11 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.state.onChanged('currentUser', (user) => {
|
this.state.onChanged('currentUser', (user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
this.loadTrackList();
|
this.loadTrackList();
|
||||||
|
TrackViewModel.setMenuVisible(this.editEl, true);
|
||||||
} else {
|
} else {
|
||||||
this.model.currentTrackId = '';
|
this.model.currentTrackId = '';
|
||||||
this.model.trackList = [];
|
this.model.trackList = [];
|
||||||
|
TrackViewModel.setMenuVisible(this.editEl, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.state.onChanged('currentTrack', (track) => {
|
this.state.onChanged('currentTrack', (track) => {
|
||||||
@ -129,6 +135,7 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.model.onExportGpx = exportCb('gpx');
|
this.model.onExportGpx = exportCb('gpx');
|
||||||
this.model.onExportKml = exportCb('kml');
|
this.model.onExportKml = exportCb('kml');
|
||||||
this.model.onImportGpx = () => this.importEl.click();
|
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}`); });
|
.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
|
* @param {boolean} start
|
||||||
*/
|
*/
|
||||||
@ -285,6 +310,14 @@ export default class TrackViewModel extends ViewModel {
|
|||||||
this.model.autoReload = false;
|
this.model.autoReload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static setMenuVisible(el, visible) {
|
||||||
|
if (visible) {
|
||||||
|
el.classList.remove('menu-hidden');
|
||||||
|
} else {
|
||||||
|
el.classList.add('menu-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderSummary() {
|
renderSummary() {
|
||||||
if (!this.state.currentTrack || !this.state.currentTrack.hasPositions) {
|
if (!this.state.currentTrack || !this.state.currentTrack.hasPositions) {
|
||||||
this.model.summary = '';
|
this.model.summary = '';
|
||||||
|
@ -51,6 +51,8 @@ describe('TrackViewModel tests', () => {
|
|||||||
let autoReloadEl;
|
let autoReloadEl;
|
||||||
/** @type {HTMLInputElement} */
|
/** @type {HTMLInputElement} */
|
||||||
let inputFileEl;
|
let inputFileEl;
|
||||||
|
/** @type {HTMLAnchorElement} */
|
||||||
|
let trackEditEl;
|
||||||
let tracks;
|
let tracks;
|
||||||
let track1;
|
let track1;
|
||||||
let track2;
|
let track2;
|
||||||
@ -78,6 +80,7 @@ describe('TrackViewModel tests', () => {
|
|||||||
forceReloadEl = document.querySelector('#force-reload');
|
forceReloadEl = document.querySelector('#force-reload');
|
||||||
inputFileEl = document.querySelector('#input-file');
|
inputFileEl = document.querySelector('#input-file');
|
||||||
autoReloadEl = document.querySelector('#auto-reload');
|
autoReloadEl = document.querySelector('#auto-reload');
|
||||||
|
trackEditEl = document.querySelector('#edittrack');
|
||||||
const maxEl = document.querySelector('input[name="MAX_FILE_SIZE"]');
|
const maxEl = document.querySelector('input[name="MAX_FILE_SIZE"]');
|
||||||
maxEl.value = MAX_FILE_SIZE;
|
maxEl.value = MAX_FILE_SIZE;
|
||||||
state = new uState();
|
state = new uState();
|
||||||
@ -257,7 +260,6 @@ describe('TrackViewModel tests', () => {
|
|||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should load user latest position when "show latest" is checked and select respective track in list', (done) => {
|
it('should load user latest position when "show latest" is checked and select respective track in list', (done) => {
|
||||||
// given
|
// given
|
||||||
positions[0].trackid = track2.id;
|
positions[0].trackid = track2.id;
|
||||||
@ -604,6 +606,64 @@ describe('TrackViewModel tests', () => {
|
|||||||
}, 100);
|
}, 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', () => {
|
describe('on reload clicked', () => {
|
||||||
|
|
||||||
it('should reload selected track', (done) => {
|
it('should reload selected track', (done) => {
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
}
|
}
|
||||||
$track = new uTrack($trackId);
|
$track = new uTrack($trackId);
|
||||||
if (!$track->isValid ||
|
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"]);
|
uUtils::exitWithError($lang["servererror"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user