Skip to content

Commit dd8825f

Browse files
committed
[frontend] Fix various Vue 3 related issues with the DateRangePicker
1 parent e8bca34 commit dd8825f

File tree

1 file changed

+72
-92
lines changed

1 file changed

+72
-92
lines changed

desktop/core/src/desktop/js/components/DateRangePicker.vue

Lines changed: 72 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,28 @@
1717
-->
1818

1919
<template>
20-
<dropdown-panel :text="selectedRange.title" :inline="inline">
20+
<dropdown-panel
21+
:text="(isCustom && CUSTOM_TITLE) || selectedRange.title"
22+
:inline="inline"
23+
:close-on-click="false"
24+
>
2125
<template #default="{ closePanel }">
2226
<div class="date-range-picker-panel">
2327
<div class="date-range-picker-body">
2428
<div class="date-range-picker-preset">
2529
<div style="border-right: 1px solid gray;">
2630
<header>Quick Ranges</header>
2731
<div class="preset-list">
28-
<div v-for="(rangeSet, index) in rangeSets" :key="index" class="preset-column">
32+
<div v-for="(rangeSet, index) in RANGE_SETS" :key="index" class="preset-column">
2933
<div
3034
v-for="range in rangeSet"
3135
:key="range.title"
3236
class="preset-value"
3337
:class="{ selected: range === selectedRange }"
3438
>
35-
<hue-link @click="selectedRange = range">{{ range.title }}</hue-link>
39+
<hue-link @click="quickSelect(range, closePanel)">
40+
{{ range.title }}
41+
</hue-link>
3642
</div>
3743
</div>
3844
</div>
@@ -43,25 +49,23 @@
4349
<div>
4450
<div class="range-header">FROM:</div>
4551
<datepicker
46-
:value="customFrom"
52+
v-model="customFrom"
4753
:typeable="true"
4854
input-class="range-input"
4955
calendar-class="range-calendar"
5056
format="dd/MM/yyyy"
5157
placeholder="DD/MM/YYYY"
52-
@selected="setCustomFrom"
5358
/>
5459
</div>
5560
<div>
5661
<div class="range-header">TO:</div>
5762
<datepicker
58-
:value="customTo"
63+
v-model="customTo"
5964
:typeable="true"
6065
input-class="range-input"
6166
calendar-class="range-calendar"
6267
format="dd/MM/yyyy"
6368
placeholder="DD/MM/YYYY"
64-
@selected="setCustomTo"
6569
/>
6670
</div>
6771
</div>
@@ -76,7 +80,7 @@
7680
</template>
7781

7882
<script lang="ts">
79-
import { defineComponent } from 'vue';
83+
import { defineComponent, ref, watch } from 'vue';
8084
8185
import { Range } from './DateRangePicker';
8286
import { DateTime } from 'luxon';
@@ -137,6 +141,8 @@
137141
138142
const DEFAULT_RANGE = RANGE_SETS[0][0];
139143
144+
const CUSTOM_TITLE = I18n('Custom Range');
145+
140146
export default defineComponent({
141147
name: 'DateRangePicker',
142148
components: {
@@ -145,113 +151,87 @@
145151
HueButton,
146152
HueLink
147153
},
148-
149154
props: {
150155
inline: {
151156
type: Boolean,
152157
required: false,
153158
default: false
154159
}
155160
},
156-
157161
emits: ['date-range-changed'],
158-
159-
setup(): {
160-
rangeSets: Range[][];
161-
162-
customRange: Range;
163-
} {
164-
return {
165-
rangeSets: RANGE_SETS,
166-
167-
customRange: {
168-
title: I18n('Custom Range'),
169-
from: RANGE_NOW.toMillis() - DEFAULT_RANGE.from,
170-
to: RANGE_NOW.toMillis(),
171-
custom: true
162+
setup(props, { emit }) {
163+
const selectedRange = ref<Range>(DEFAULT_RANGE);
164+
const isCustom = ref<boolean>(false);
165+
const customFrom = ref<Date>(new Date(RANGE_NOW.toMillis() - DEFAULT_RANGE.from));
166+
const customTo = ref<Date>(new Date(RANGE_NOW.toMillis()));
167+
168+
watch(customFrom, () => {
169+
if (customFrom.value.getTime() > customTo.value.getTime()) {
170+
customTo.value = customFrom.value;
172171
}
173-
};
174-
},
175-
176-
data(): {
177-
selectedRange: Range;
178-
} {
179-
return {
180-
selectedRange: DEFAULT_RANGE
181-
};
182-
},
183-
184-
computed: {
185-
customFrom(): number | undefined {
186-
if (this.selectedRange.custom) {
187-
return this.selectedRange.from;
188-
}
189-
return undefined;
190-
},
191-
192-
customTo(): number | undefined {
193-
if (this.selectedRange.custom) {
194-
return this.selectedRange.to;
195-
}
196-
return undefined;
197-
}
198-
},
172+
});
199173
200-
methods: {
201-
// TODO: Switch to v-model and value prop
202-
clear(): void {
203-
if (this.selectedRange !== DEFAULT_RANGE) {
204-
this.selectedRange = DEFAULT_RANGE;
205-
this.notify();
174+
watch(customTo, () => {
175+
if (customTo.value.getTime() < customFrom.value.getTime()) {
176+
customFrom.value = customTo.value;
206177
}
207-
},
178+
});
208179
209-
setCustomFrom(from?: Date): void {
210-
if (from) {
211-
this.customRange.from = from.valueOf();
212-
if (this.customRange.from > this.customRange.to) {
213-
this.customRange.to = this.customRange.from;
214-
}
215-
this.selectedRange = this.customRange;
216-
this.$forceUpdate();
217-
}
218-
},
219-
220-
setCustomTo(to?: Date): void {
221-
if (to) {
222-
this.customRange.to = to.valueOf();
223-
if (this.customRange.to < this.customRange.from) {
224-
this.customRange.from = this.customRange.to;
225-
}
226-
this.selectedRange = this.customRange;
227-
this.$forceUpdate();
228-
}
229-
},
230-
231-
notify(): void {
180+
const notify = (): void => {
232181
let range: Range;
233-
if (this.selectedRange.custom) {
182+
if (isCustom.value) {
234183
range = {
235-
title: this.selectedRange.title,
236-
from: DateTime.fromMillis(this.selectedRange.from).startOf('day').valueOf(),
237-
to: DateTime.fromMillis(this.selectedRange.to).endOf('day').valueOf(),
184+
title: CUSTOM_TITLE,
185+
from: DateTime.fromJSDate(customFrom.value).startOf('day').valueOf(),
186+
to: DateTime.fromJSDate(customTo.value).endOf('day').valueOf(),
238187
custom: true
239188
};
240189
} else {
190+
const { title, from, to } = selectedRange.value;
241191
const now = DateTime.utc().valueOf();
242192
range = {
243-
title: this.selectedRange.title,
244-
from: now - this.selectedRange.from,
245-
to: now - this.selectedRange.to
193+
title,
194+
from: now - from,
195+
to: now - to
246196
};
247197
}
248-
this.$emit('date-range-changed', range);
249-
},
198+
emit('date-range-changed', range);
199+
};
200+
201+
const clear = (): void => {
202+
if (isCustom.value || selectedRange.value !== DEFAULT_RANGE) {
203+
customFrom.value = new Date(RANGE_NOW.toMillis() - DEFAULT_RANGE.from);
204+
customTo.value = new Date(RANGE_NOW.toMillis());
205+
selectedRange.value = DEFAULT_RANGE;
206+
isCustom.value = false;
207+
notify();
208+
}
209+
};
250210
251-
apply(closePanel: () => void): void {
252-
this.notify();
211+
const apply = (closePanel: () => void): void => {
212+
isCustom.value = true;
213+
notify();
253214
closePanel();
254-
}
215+
};
216+
217+
const quickSelect = (range: Range, closePanel: () => void): void => {
218+
isCustom.value = false;
219+
selectedRange.value = range;
220+
notify();
221+
closePanel();
222+
};
223+
224+
return {
225+
apply,
226+
clear,
227+
CUSTOM_TITLE,
228+
customFrom,
229+
customTo,
230+
isCustom,
231+
quickSelect,
232+
RANGE_SETS,
233+
selectedRange
234+
};
255235
}
256236
});
257237
</script>

0 commit comments

Comments
 (0)