parent
282828df0b
commit
6b7e984817
3 changed files with 84 additions and 60 deletions
frontend/src/components
|
@ -44,13 +44,8 @@
|
||||||
<FilterForm :value="locationQuery"
|
<FilterForm :value="locationQuery"
|
||||||
:devices="devices"
|
:devices="devices"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
:has-next-page="hasNextPage"
|
|
||||||
:has-prev-page="hasPrevPage"
|
|
||||||
:resolution="resolutionMeters"
|
:resolution="resolutionMeters"
|
||||||
@refresh="locationQuery = $event"
|
@refresh="locationQuery = $event"
|
||||||
@reset-page="locationQuery.minId = locationQuery.maxId = null"
|
|
||||||
@next-page="fetchNextPage"
|
|
||||||
@prev-page="fetchPrevPage"
|
|
||||||
@set-resolution="setResolution" />
|
@set-resolution="setResolution" />
|
||||||
</div>
|
</div>
|
||||||
<FilterButton @input="showControls = !showControls"
|
<FilterButton @input="showControls = !showControls"
|
||||||
|
@ -70,8 +65,12 @@
|
||||||
|
|
||||||
<div class="timeline">
|
<div class="timeline">
|
||||||
<Timeline :loading="loading"
|
<Timeline :loading="loading"
|
||||||
|
:locationQuery="locationQuery"
|
||||||
:points="gpsPoints"
|
:points="gpsPoints"
|
||||||
:show-metrics="showMetrics"
|
:show-metrics="showMetrics"
|
||||||
|
@next-page="fetchNextPage"
|
||||||
|
@prev-page="fetchPrevPage"
|
||||||
|
@reset-page="resetPage"
|
||||||
@point-hover="onTimelinePointHover"
|
@point-hover="onTimelinePointHover"
|
||||||
@show-metrics="setShowMetrics" />
|
@show-metrics="setShowMetrics" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -283,6 +282,12 @@ export default {
|
||||||
this.locationQuery = prevPageQuery
|
this.locationQuery = prevPageQuery
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async resetPage() {
|
||||||
|
const oldQuery = { ...this.locationQuery }
|
||||||
|
this.locationQuery.minId = this.locationQuery.maxId = null
|
||||||
|
await this.processQueryChange(this.locationQuery, oldQuery)
|
||||||
|
},
|
||||||
|
|
||||||
createMap(): Map {
|
createMap(): Map {
|
||||||
this.pointsLayer = this.createPointsLayer(Object.values(this.mappedPoints) as Point[])
|
this.pointsLayer = this.createPointsLayer(Object.values(this.mappedPoints) as Point[])
|
||||||
this.routesLayer = this.createRoutesLayer(Object.values(this.mappedPoints) as Point[])
|
this.routesLayer = this.createRoutesLayer(Object.values(this.mappedPoints) as Point[])
|
||||||
|
@ -431,6 +436,8 @@ export default {
|
||||||
...this.locationQuery,
|
...this.locationQuery,
|
||||||
startDate: null,
|
startDate: null,
|
||||||
endDate: null,
|
endDate: null,
|
||||||
|
minId: null,
|
||||||
|
maxId: null,
|
||||||
minLongitude: startLon,
|
minLongitude: startLon,
|
||||||
minLatitude: startLat,
|
minLatitude: startLat,
|
||||||
maxLongitude: endLon,
|
maxLongitude: endLon,
|
||||||
|
@ -444,6 +451,8 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.locationQuery = {
|
this.locationQuery = {
|
||||||
...this.locationQuery,
|
...this.locationQuery,
|
||||||
|
minId: null,
|
||||||
|
maxId: null,
|
||||||
minLongitude: null,
|
minLongitude: null,
|
||||||
minLatitude: null,
|
minLatitude: null,
|
||||||
maxLongitude: null,
|
maxLongitude: null,
|
||||||
|
@ -451,18 +460,8 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
locationQuery: {
|
|
||||||
async handler(newQuery: LocationQuery, oldQuery: LocationQuery) {
|
|
||||||
if (!this.isQueryChanged({
|
|
||||||
newValue: newQuery,
|
|
||||||
oldValue: oldQuery,
|
|
||||||
})) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
async processQueryChange(newQuery: LocationQuery, oldQuery: LocationQuery) {
|
||||||
// If startDate/endDate have changed, reset minId/maxId
|
// If startDate/endDate have changed, reset minId/maxId
|
||||||
if (newQuery.startDate !== oldQuery.startDate || newQuery.endDate !== oldQuery.endDate) {
|
if (newQuery.startDate !== oldQuery.startDate || newQuery.endDate !== oldQuery.endDate) {
|
||||||
newQuery.minId = null
|
newQuery.minId = null
|
||||||
|
@ -507,6 +506,20 @@ export default {
|
||||||
this.refreshMap()
|
this.refreshMap()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
locationQuery: {
|
||||||
|
async handler(newQuery: LocationQuery, oldQuery: LocationQuery) {
|
||||||
|
if (!this.isQueryChanged({
|
||||||
|
newValue: newQuery,
|
||||||
|
oldValue: oldQuery,
|
||||||
|
})) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.processQueryChange(newQuery, oldQuery)
|
||||||
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,31 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="page-button-container">
|
||||||
|
<button @click="$emit('prev-page')"
|
||||||
|
title="Previous results">
|
||||||
|
<font-awesome-icon icon="chevron-left" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="timeline">
|
<div class="timeline">
|
||||||
<Line :data="graphData" :options="graphOptions" />
|
<Line :data="graphData" :options="graphOptions" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="page-button-container">
|
||||||
|
<button @click="$emit('next-page')"
|
||||||
|
title="Next results">
|
||||||
|
<font-awesome-icon icon="chevron-right" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-button-container"
|
||||||
|
v-if="locationQuery?.minId || locationQuery?.maxId">
|
||||||
|
<button @click="$emit('reset-page')"
|
||||||
|
title="Reset pagination">
|
||||||
|
<font-awesome-icon icon="fas fa-undo" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -47,6 +69,7 @@ import 'chartjs-adapter-date-fns';
|
||||||
|
|
||||||
import Geo from '../mixins/Geo.vue';
|
import Geo from '../mixins/Geo.vue';
|
||||||
import GPSPoint from '../models/GPSPoint';
|
import GPSPoint from '../models/GPSPoint';
|
||||||
|
import LocationQuery from '../models/LocationQuery';
|
||||||
import TimelineMetricsConfiguration from '../models/TimelineMetricsConfiguration';
|
import TimelineMetricsConfiguration from '../models/TimelineMetricsConfiguration';
|
||||||
|
|
||||||
ChartJS.register(
|
ChartJS.register(
|
||||||
|
@ -60,7 +83,13 @@ ChartJS.register(
|
||||||
);
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['point-hover', 'show-metrics'],
|
emits: [
|
||||||
|
'next-page',
|
||||||
|
'point-hover',
|
||||||
|
'prev-page',
|
||||||
|
'reset-page',
|
||||||
|
'show-metrics',
|
||||||
|
],
|
||||||
mixins: [Geo],
|
mixins: [Geo],
|
||||||
components: {
|
components: {
|
||||||
Line,
|
Line,
|
||||||
|
@ -71,6 +100,9 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
locationQuery: {
|
||||||
|
type: LocationQuery,
|
||||||
|
},
|
||||||
points: {
|
points: {
|
||||||
type: Array as () => GPSPoint[],
|
type: Array as () => GPSPoint[],
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
@ -332,4 +364,26 @@ $options-width: 5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-button-container {
|
||||||
|
width: 3em;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: var(--color-background);
|
||||||
|
border: 0;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -86,24 +86,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<div class="page-button-container">
|
|
||||||
<button type="button"
|
|
||||||
:disabled="disabled"
|
|
||||||
v-if="value?.minId || value?.maxId"
|
|
||||||
@click.stop="$emit('reset-page')">
|
|
||||||
<font-awesome-icon icon="fas fa-undo" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page-button-container">
|
|
||||||
<button type="button"
|
|
||||||
@click="$emit('prev-page')"
|
|
||||||
title="Previous Results"
|
|
||||||
:disabled="disabled || !hasPrevPage">
|
|
||||||
<font-awesome-icon icon="fas fa-chevron-left" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limit-container">
|
<div class="limit-container">
|
||||||
<label for="limit">Max Results</label>
|
<label for="limit">Max Results</label>
|
||||||
<input type="number"
|
<input type="number"
|
||||||
|
@ -115,15 +97,6 @@
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
min="1" />
|
min="1" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page-button-container">
|
|
||||||
<button type="button"
|
|
||||||
@click="$emit('next-page')"
|
|
||||||
title="Next Results"
|
|
||||||
:disabled="disabled || !hasNextPage">
|
|
||||||
<font-awesome-icon icon="fas fa-chevron-right" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="resolution-container">
|
<div class="resolution-container">
|
||||||
|
@ -176,9 +149,6 @@ import UserDevice from '../../models/UserDevice'
|
||||||
export default {
|
export default {
|
||||||
mixins: [LocationQueryMixin],
|
mixins: [LocationQueryMixin],
|
||||||
emit: [
|
emit: [
|
||||||
'next-page',
|
|
||||||
'prev-page',
|
|
||||||
'reset-page',
|
|
||||||
'refresh',
|
'refresh',
|
||||||
'set-resolution',
|
'set-resolution',
|
||||||
],
|
],
|
||||||
|
@ -193,14 +163,6 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
hasPrevPage: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
hasNextPage: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
resolution: {
|
resolution: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -432,11 +394,6 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-button-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
label {
|
||||||
margin-bottom: 0.25em;
|
margin-bottom: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue