Implement new date/time range picker

Co-authored-by: Christophe Chapuis <chris.chapuis@gmail.com>
This commit is contained in:
jduar
2024-06-09 23:04:48 +01:00
committed by GitHub
parent 723ce684ae
commit b141444b56
7 changed files with 176 additions and 183 deletions

131
package-lock.json generated
View File

@@ -14,13 +14,13 @@
"leaflet.heat": "^0.2.0",
"moment": "^2.30.1",
"vue": "^2.7.16",
"vue-ctk-date-time-picker": "^2.5.0",
"vue-feather-icons": "^5.1.0",
"vue-i18n": "^8.28.2",
"vue-js-modal": "^2.0.1",
"vue-mq": "^1.0.1",
"vue-outside-events": "^1.1.3",
"vue-router": "^3.6.5",
"vue2-datepicker": "^3.11.1",
"vue2-leaflet": "^2.7.1",
"vuex": "^3.6.2"
},
@@ -1720,18 +1720,6 @@
"version": "3.1.3",
"license": "MIT"
},
"node_modules/d": {
"version": "1.0.1",
"license": "ISC",
"dependencies": {
"es5-ext": "^0.10.50",
"type": "^1.0.1"
}
},
"node_modules/d/node_modules/type": {
"version": "1.2.0",
"license": "ISC"
},
"node_modules/data-urls": {
"version": "5.0.0",
"dev": true,
@@ -1752,6 +1740,11 @@
"node": ">=18"
}
},
"node_modules/date-format-parse": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/date-format-parse/-/date-format-parse-0.2.7.tgz",
"integrity": "sha512-/+lyMUKoRogMuTeOVii6lUwjbVlesN9YRYLzZT/g3TEZ3uD9QnpjResujeEqUW+OSNbT7T1+SYdyEkTcRv+KDQ=="
},
"node_modules/debug": {
"version": "4.3.4",
"dev": true,
@@ -1862,37 +1855,6 @@
"license": "MIT",
"peer": true
},
"node_modules/es5-ext": {
"version": "0.10.63",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"es6-iterator": "^2.0.3",
"es6-symbol": "^3.1.3",
"esniff": "^2.0.1",
"next-tick": "^1.1.0"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/es6-iterator": {
"version": "2.0.3",
"license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "^0.10.35",
"es6-symbol": "^3.1.1"
}
},
"node_modules/es6-symbol": {
"version": "3.1.3",
"license": "ISC",
"dependencies": {
"d": "^1.0.1",
"ext": "^1.1.2"
}
},
"node_modules/esbuild": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
@@ -2245,19 +2207,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/esniff": {
"version": "2.0.1",
"license": "ISC",
"dependencies": {
"d": "^1.0.1",
"es5-ext": "^0.10.62",
"event-emitter": "^0.3.5",
"type": "^2.7.2"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/espree": {
"version": "9.6.1",
"dev": true,
@@ -2322,14 +2271,6 @@
"node": ">=0.10.0"
}
},
"node_modules/event-emitter": {
"version": "0.3.5",
"license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "~0.10.14"
}
},
"node_modules/eventemitter3": {
"version": "1.2.0",
"dev": true,
@@ -2344,13 +2285,6 @@
"node": ">=0.8.x"
}
},
"node_modules/ext": {
"version": "1.7.0",
"license": "ISC",
"dependencies": {
"type": "^2.7.2"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"dev": true,
@@ -3337,19 +3271,6 @@
"webpack": "^1 || ^2 || ^3 || ^4 || ^5"
}
},
"node_modules/moment-range": {
"version": "4.0.2",
"license": "Unlicense",
"dependencies": {
"es6-symbol": "^3.1.0"
},
"engines": {
"node": "*"
},
"peerDependencies": {
"moment": ">= 2"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"funding": [
@@ -3377,10 +3298,6 @@
"license": "MIT",
"peer": true
},
"node_modules/next-tick": {
"version": "1.1.0",
"license": "ISC"
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -4299,10 +4216,6 @@
"dev": true,
"license": "0BSD"
},
"node_modules/type": {
"version": "2.7.2",
"license": "ISC"
},
"node_modules/type-check": {
"version": "0.4.0",
"dev": true,
@@ -4409,13 +4322,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/v-click-outside": {
"version": "2.1.5",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/vite": {
"version": "5.2.13",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz",
@@ -4685,20 +4591,6 @@
"csstype": "^3.1.0"
}
},
"node_modules/vue-ctk-date-time-picker": {
"version": "2.5.0",
"license": "MIT",
"dependencies": {
"moment": "^2.24.0",
"moment-range": "^4.0.1",
"v-click-outside": "^2.0.2",
"vue": "^2.6.9"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/vue-eslint-parser": {
"version": "9.4.3",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
@@ -4803,6 +4695,17 @@
"version": "3.6.5",
"license": "MIT"
},
"node_modules/vue2-datepicker": {
"version": "3.11.1",
"resolved": "https://registry.npmjs.org/vue2-datepicker/-/vue2-datepicker-3.11.1.tgz",
"integrity": "sha512-6PU/+pnp2mgZAfnSXmbdwj9516XsEvTiw61Q5SNrvvdy8W/FCxk1GAe9UZn/m9YfS5A47yK6XkcjMHbp7aFApA==",
"dependencies": {
"date-format-parse": "^0.2.7"
},
"peerDependencies": {
"vue": "^2.5.0"
}
},
"node_modules/vue2-leaflet": {
"version": "2.7.1",
"license": "MIT",

View File

@@ -30,13 +30,13 @@
"leaflet.heat": "^0.2.0",
"moment": "^2.30.1",
"vue": "^2.7.16",
"vue-ctk-date-time-picker": "^2.5.0",
"vue-feather-icons": "^5.1.0",
"vue-i18n": "^8.28.2",
"vue-js-modal": "^2.0.1",
"vue-mq": "^1.0.1",
"vue-outside-events": "^1.1.3",
"vue-router": "^3.6.5",
"vue2-datepicker": "^3.11.1",
"vue2-leaflet": "^2.7.1",
"vuex": "^3.6.2"
},

View File

@@ -53,35 +53,31 @@
</div>
<div class="nav-item">
<CalendarIcon size="1x" aria-hidden="true" role="img" />
<VueCtkDateTimePicker
v-model="startDateTime"
:format="DATE_TIME_FORMAT"
:color="$config.primaryColor"
:locale="$config.locale"
:max-date="endDateTime"
:button-now-translation="$t('Now')"
<date-picker
v-model="dateTimeRange"
type="datetime"
format="YYYY-MM-DD HH:mm"
:editable="false"
:clearable="false"
:confirm="true"
:show-second="false"
:range="true"
range-separator=" "
:shortcuts="shortcuts"
:show-time-panel="showTimeRangePanel"
:disabled-date="(date, _) => date > new Date()"
@change="handleDateTimeRangeChange"
>
<button
type="button"
class="dropdown-button button"
:title="$t('Select start date')"
/>
</VueCtkDateTimePicker>
<span>{{ $t("to") }}</span>
<VueCtkDateTimePicker
v-model="endDateTime"
:format="DATE_TIME_FORMAT"
:color="$config.primaryColor"
:locale="$config.locale"
:min-date="startDateTime"
:button-now-translation="$t('Now')"
>
<button
type="button"
class="dropdown-button button"
:title="$t('Select end date')"
/>
</VueCtkDateTimePicker>
<template v-slot:footer>
<button
class="mx-btn toggle-date-btn"
type="button"
@click="toggleTimeRangePanel"
>
{{ showTimeRangePanel ? $t("Select date") : $t("Select time") }}
</button>
</template>
</date-picker>
</div>
<div class="nav-item">
<UserIcon size="1x" aria-hidden="true" role="img" />
@@ -162,8 +158,9 @@ import {
SmartphoneIcon,
UserIcon,
} from "vue-feather-icons";
import VueCtkDateTimePicker from "vue-ctk-date-time-picker";
import "vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css";
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import DropdownButton from "@/components/DropdownButton.vue";
import { DATE_TIME_FORMAT } from "@/constants";
@@ -176,12 +173,12 @@ export default {
ArrowUpIcon,
CalendarIcon,
CrosshairIcon,
DatePicker,
InfoIcon,
LayersIcon,
MenuIcon,
SmartphoneIcon,
UserIcon,
VueCtkDateTimePicker,
DropdownButton,
},
data() {
@@ -194,6 +191,41 @@ export default {
{ layer: "heatmap", label: this.$t("Show location heatmap") },
],
showMobileNav: false,
shortcuts: [
{
text: this.$t("Today"),
onClick() {
const end = new Date();
end.setHours(23, 59, 59, 0);
const start = new Date();
start.setHours(0, 0, 0, 0);
return [start, end];
},
},
{
text: this.$t("7 days"),
onClick() {
const end = new Date();
end.setHours(23, 59, 59, 0);
const start = new Date();
start.setDate(end.getDate() - 7);
start.setHours(0, 0, 0, 0);
return [start, end];
},
},
{
text: this.$t("30 days"),
onClick() {
const end = new Date();
end.setHours(23, 59, 59, 0);
const start = new Date();
start.setDate(end.getDate() - 30);
start.setHours(0, 0, 0, 0);
return [start, end];
},
},
],
showTimeRangePanel: false,
};
},
computed: {
@@ -221,32 +253,25 @@ export default {
this.setSelectedDevice(value);
},
},
startDateTime: {
dateTimeRange: {
get() {
return moment
const startDateTime = moment
.utc(this.$store.state.startDateTime, DATE_TIME_FORMAT)
.local()
.format(DATE_TIME_FORMAT);
},
set(value) {
this.setStartDateTime(
moment(value, DATE_TIME_FORMAT).utc().format(DATE_TIME_FORMAT)
);
},
},
endDateTime: {
get() {
return moment
.toDate();
const endDateTime = moment
.utc(this.$store.state.endDateTime, DATE_TIME_FORMAT)
.local()
.format(DATE_TIME_FORMAT);
.toDate();
return [startDateTime, endDateTime];
},
set(value) {
set([startDateTime, endDateTime]) {
this.setStartDateTime(
moment(startDateTime).utc().format(DATE_TIME_FORMAT)
);
this.setEndDateTime(
moment(value, DATE_TIME_FORMAT)
.set("seconds", 59)
.utc()
.format(DATE_TIME_FORMAT)
moment(endDateTime).set("seconds", 59).utc().format(DATE_TIME_FORMAT)
);
},
},
@@ -262,6 +287,13 @@ export default {
"setEndDateTime",
]),
humanReadableDistance,
toggleTimeRangePanel() {
this.showTimeRangePanel = !this.showTimeRangePanel;
},
// Resetting to date choice after value change
handleDateTimeRangeChange(value, type) {
this.showTimeRangePanel = false;
},
},
};
</script>

View File

@@ -32,5 +32,10 @@
"Battery": "Battery",
"Speed": "Speed",
"Regions:": "Regions:",
"WiFi": "WiFi"
"WiFi": "WiFi",
"Select date": "Select date",
"Select time": "Select time",
"Today": "Today",
"7 days": "7 days",
"30 days": "30 days"
}

View File

@@ -32,5 +32,10 @@
"Battery": "Battery",
"Speed": "Speed",
"Regions:": "Regions:",
"WiFi": "WiFi"
"WiFi": "WiFi",
"Select date": "Select date",
"Select time": "Select time",
"Today": "Today",
"7 days": "7 days",
"30 days": "30 days"
}

View File

@@ -101,8 +101,7 @@ pre {
min-height: 100%;
flex-direction: column;
// Only select immediate child as the datepicker contains a <header> as well
> header {
header {
display: flex;
padding: 20px;
white-space: nowrap;
@@ -182,19 +181,33 @@ pre {
}
> .button,
> .dropdown,
> .date-time-picker {
> .mx-datepicker,
> .mx-input,
> .dropdown {
flex: 1;
}
> .dropdown .dropdown-button,
> .date-time-picker .dropdown-button {
> .dropdown .dropdown-button {
width: 100%;
}
> .date-time-picker {
margin-left: 0;
margin-right: 0;
.mx-datepicker {
display: flex;
width: auto;
.mx-datepicker-range {
width: auto;
}
.mx-input-wrapper {
display: flex;
width: 100%;
.mx-input {
font-size: 13px;
letter-spacing: -0.6px;
}
}
}
> span {

View File

@@ -1,10 +1,45 @@
.date-time-picker {
display: inline-block;
width: auto;
.mx-datepicker {
width: 280px;
.datepicker {
box-shadow: none !important;
filter: var(--drop-shadow);
margin-top: 5px;
.mx-input {
border: 0;
border-radius: 18px;
text-align: center;
height: 33px;
padding-right: 0px;
padding-left: 0px;
}
}
@media screen and (max-width: 400px) {
.mx-datepicker-main {
display: flex;
top: 0 !important;
left: 0 !important;
width: 100%;
height: 100%;
.mx-datepicker-sidebar {
flex: 0.7;
}
.mx-datepicker-content {
display: flex;
flex-direction: column;
flex: 1;
margin-left: 0px;
}
}
}
.mx-time {
width: 100%;
}
.toggle-date-btn {
margin-right: 10px;
}
.mx-icon-calendar {
display: none;
}