diff --git a/js/src/trackviewmodel.js b/js/src/trackviewmodel.js index 5c57dbd..07645b0 100644 --- a/js/src/trackviewmodel.js +++ b/js/src/trackviewmodel.js @@ -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 = ''; diff --git a/js/test/trackviewmodel.test.js b/js/test/trackviewmodel.test.js index 7ff932a..f8994cb 100644 --- a/js/test/trackviewmodel.test.js +++ b/js/test/trackviewmodel.test.js @@ -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) => { diff --git a/utils/handletrack.php b/utils/handletrack.php index 894ba3c..908529b 100644 --- a/utils/handletrack.php +++ b/utils/handletrack.php @@ -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"]); }