Datetime and date picker fixes.

This commit is contained in:
Buster "Silver Eagle" Neece 2022-03-22 02:52:32 -05:00
parent 04bd45fc2d
commit b25fbd92ba
No known key found for this signature in database
GPG Key ID: 9FC8B9E008872109
7 changed files with 119 additions and 86 deletions

View File

@ -129,11 +129,13 @@ export default {
return this.$gettext('Delete');
},
apiUrl() {
let params = {};
params.start = DateTime.fromJSDate(this.dateRange.startDate).toISODate();
params.end = DateTime.fromJSDate(this.dateRange.endDate).toISODate();
let apiUrl = new URL(this.baseApiUrl, document.location);
return this.baseApiUrl + '?start=' + params.start + '&end=' + params.end;
let apiUrlParams = apiUrl.searchParams;
apiUrlParams.set('start', DateTime.fromJSDate(this.dateRange.startDate).toISO());
apiUrlParams.set('end', DateTime.fromJSDate(this.dateRange.endDate).toISO());
return apiUrl.toString();
},
},
methods: {

View File

@ -1,7 +1,8 @@
<template>
<date-range-picker
ref="picker" controlContainerClass="" opens="left" show-dropdowns
v-bind="$props" :ranges="ranges" @update="onUpdate">
v-bind="$props"
:time-picker-increment="1" :ranges="ranges" @update="onUpdate">
<template #input="datePicker">
<a class="btn btn-bg dropdown-toggle" id="reportrange" href="#" @click.prevent="">
<icon icon="date_range"></icon>
@ -63,48 +64,48 @@ export default {
default: null,
},
},
data() {
let ranges = {};
computed: {
ranges() {
let ranges = {};
if (null !== this.customRanges) {
return this.customRanges;
}
if (null !== this.customRanges) {
ranges = this.customRanges;
} else {
let nowTz = DateTime.now().setZone(this.tz);
let nowTzDate = nowTz.toJSDate();
ranges[this.$gettext('Today')] = [
nowTzDate,
nowTz.minus({days: 1}).toJSDate(),
nowTzDate
];
ranges[this.$gettext('Yesterday')] = [
nowTz.minus({days: 1}).toJSDate(),
nowTz.minus({days: 2}).toJSDate(),
nowTz.minus({days: 1}).toJSDate()
];
ranges[this.$gettext('Last 7 Days')] = [
nowTz.minus({days: 6}).toJSDate(),
nowTz.minus({days: 7}).toJSDate(),
nowTzDate
];
ranges[this.$gettext('Last 14 Days')] = [
nowTz.minus({days: 13}).toJSDate(),
nowTz.minus({days: 14}).toJSDate(),
nowTzDate
];
ranges[this.$gettext('Last 30 Days')] = [
nowTz.minus({days: 29}).toJSDate(),
nowTz.minus({days: 30}).toJSDate(),
nowTzDate
];
ranges[this.$gettext('This Month')] = [
nowTz.startOf('month').toJSDate(),
nowTz.endOf('month').toJSDate()
nowTz.startOf('month').startOf('day').toJSDate(),
nowTz.endOf('month').endOf('day').toJSDate()
];
ranges[this.$gettext('Last Month')] = [
nowTz.minus({months: 1}).startOf('month').toJSDate(),
nowTz.minus({months: 1}).endOf('month').toJSDate()
nowTz.minus({months: 1}).startOf('month').startOf('day').toJSDate(),
nowTz.minus({months: 1}).endOf('month').endOf('day').toJSDate()
];
}
return {
ranges: ranges
};
return ranges;
}
},
methods: {
onUpdate(newValue) {

View File

@ -4,33 +4,28 @@
<div class="card">
<div class="card-header bg-primary-dark">
<div class="d-flex align-items-center">
<h2 class="card-title flex-fill my-0">
<translate key="lang_header">Listeners</translate>
</h2>
<div class="flex-fill my-0">
<h2 class="card-title">
<translate key="lang_header">Listeners</translate>
</h2>
</div>
<div class="flex-shrink">
<a class="btn btn-bg" id="btn-export" :href="exportUrl" target="_blank">
<icon icon="file_download"></icon>
<translate key="lang_download_csv_button">Download CSV</translate>
</a>
<date-range-dropdown time-picker :min-date="minDate" :max-date="maxDate"
<date-range-dropdown v-if="!isLive" time-picker :min-date="minDate" :max-date="maxDate"
:tz="stationTimeZone" :custom-ranges="dateRanges"
v-model="dateRange" @update="updateListeners">
<template #input="datePicker">
<a class="btn btn-bg dropdown-toggle" id="reportrange" href="#" @click.prevent="">
<icon icon="date_range"></icon>
<template v-if="isLive">
<translate key="lang_live_listeners">Live Listeners</translate>
</template>
<template v-else>
{{ datePicker.rangeText }}
</template>
</a>
</template>
</date-range-dropdown>
</div>
</div>
</div>
<b-tabs pills card lazy>
<b-tab key="live" active @click="setIsLive(true)" :title="langLiveListeners" no-body></b-tab>
<b-tab key="not-live" @click="setIsLive(false)" :title="langListenerHistory" no-body></b-tab>
</b-tabs>
<div id="map">
<StationReportsListenersMap :listeners="listeners"></StationReportsListenersMap>
</div>
@ -137,26 +132,32 @@ export default {
stationTimeZone: String,
},
data() {
let liveTime = DateTime.now().setZone(this.stationTimeZone).plus({days: 1}).toJSDate();
const nowTz = DateTime.now().setZone(this.stationTimeZone);
return {
isLive: true,
listeners: [],
liveTime: liveTime,
dateRange: {
startDate: liveTime,
endDate: liveTime
startDate: nowTz.minus({days: 1}).toJSDate(),
endDate: nowTz
},
fields: [
{ key: 'ip', label: this.$gettext('IP'), sortable: false },
{ key: 'time', label: this.$gettext('Time'), sortable: false },
{ key: 'time_sec', label: this.$gettext('Time (sec)'), sortable: false },
{ key: 'user_agent', isRowHeader: true, label: this.$gettext('User Agent'), sortable: false },
{ key: 'stream', label: this.$gettext('Stream'), sortable: false },
{ key: 'location', label: this.$gettext('Location'), sortable: false }
{key: 'ip', label: this.$gettext('IP'), sortable: false},
{key: 'time', label: this.$gettext('Time'), sortable: false},
{key: 'time_sec', label: this.$gettext('Time (sec)'), sortable: false},
{key: 'user_agent', isRowHeader: true, label: this.$gettext('User Agent'), sortable: false},
{key: 'stream', label: this.$gettext('Stream'), sortable: false},
{key: 'location', label: this.$gettext('Location'), sortable: false}
]
};
},
computed: {
langLiveListeners() {
return this.$gettext('Live Listeners');
},
langListenerHistory() {
return this.$gettext('Listener History');
},
nowTz() {
return DateTime.now().setZone(this.stationTimeZone);
},
@ -168,25 +169,21 @@ export default {
},
dateRanges() {
let ranges = {};
ranges[this.$gettext('Live Listeners')] = [
this.liveTime,
this.liveTime
];
ranges[this.$gettext('Today')] = [
this.nowTz.startOf('day').toJSDate(),
this.nowTz.endOf('day').toJSDate()
this.nowTz.minus({days: 1}).toJSDate(),
this.nowTz.toJSDate()
];
ranges[this.$gettext('Yesterday')] = [
this.nowTz.minus({days: 1}).startOf('day').toJSDate(),
this.nowTz.minus({days: 1}).endOf('day').toJSDate()
this.nowTz.minus({days: 2}).toJSDate(),
this.nowTz.minus({days: 1}).toJSDate()
];
ranges[this.$gettext('Last 7 Days')] = [
this.nowTz.minus({days: 6}).startOf('day').toJSDate(),
this.nowTz.endOf('day').toJSDate()
this.nowTz.minus({days: 6}).toJSDate(),
this.nowTz.toJSDate()
];
ranges[this.$gettext('Last 30 Days')] = [
this.nowTz.minus({days: 29}).startOf('day').toJSDate(),
this.nowTz.endOf('day').toJSDate()
this.nowTz.minus({days: 29}).toJSDate(),
this.nowTz.toJSDate()
];
ranges[this.$gettext('This Month')] = [
this.nowTz.startOf('month').startOf('day').toJSDate(),
@ -196,11 +193,9 @@ export default {
this.nowTz.minus({months: 1}).startOf('month').startOf('day').toJSDate(),
this.nowTz.minus({months: 1}).endOf('month').endOf('day').toJSDate()
];
return ranges;
},
isLive() {
return DateTime.fromJSDate(this.liveTime).equals(DateTime.fromJSDate(this.dateRange.startDate));
},
exportUrl() {
let exportUrl = new URL(this.apiUrl, document.location);
let exportUrlParams = exportUrl.searchParams;
@ -227,6 +222,10 @@ export default {
this.updateListeners();
},
methods: {
setIsLive(newValue) {
this.isLive = newValue;
this.updateListeners();
},
formatTime(time) {
return formatTime(time);
},

View File

@ -16,11 +16,14 @@
</div>
</div>
</div>
<data-table ref="datatable" responsive paginated
<data-table ref="datatable" responsive paginated select-fields
:fields="fields" :apiUrl="apiUrl">
<template #cell(datetime)="row">
{{ formatTimestamp(row.item.played_at) }}
</template>
<template #cell(datetime_station)="row">
{{ formatTimestampStation(row.item.played_at) }}
</template>
<template #cell(listeners_start)="row">
{{ row.item.listeners_start }}
</template>
@ -92,11 +95,44 @@ export default {
endDate: nowTz.toJSDate(),
},
fields: [
{key: 'datetime', label: this.$gettext('Date/Time'), sortable: false},
{key: 'listeners_start', label: this.$gettext('Listeners'), sortable: false},
{key: 'delta', label: this.$gettext('Change'), sortable: false},
{key: 'song', isRowHeader: true, label: this.$gettext('Song Title'), sortable: false},
{key: 'source', label: this.$gettext('Source'), sortable: false}
{
key: 'datetime',
label: this.$gettext('Date/Time (Browser)'),
selectable: true,
sortable: false
},
{
key: 'datetime_station',
label: this.$gettext('Date/Time (Station)'),
sortable: false,
selectable: true,
visible: false
},
{
key: 'listeners_start',
label: this.$gettext('Listeners'),
selectable: true,
sortable: false
},
{
key: 'delta',
label: this.$gettext('Change'),
selectable: true,
sortable: false
},
{
key: 'song',
isRowHeader: true,
label: this.$gettext('Song Title'),
selectable: true,
sortable: false
},
{
key: 'source',
label: this.$gettext('Source'),
selectable: true,
sortable: false
}
],
}
},
@ -127,6 +163,9 @@ export default {
return Math.abs(val);
},
formatTimestamp(unix_timestamp) {
return DateTime.fromSeconds(unix_timestamp).toLocaleString(DateTime.DATETIME_SHORT);
},
formatTimestampStation(unix_timestamp) {
return DateTime.fromSeconds(unix_timestamp).setZone(this.stationTimeZone).toLocaleString(DateTime.DATETIME_SHORT);
}
}

View File

@ -27,9 +27,9 @@ class AuditLogAction
$tz = new DateTimeZone('UTC');
$params = $request->getParams();
if (!empty($params['start'])) {
$start = CarbonImmutable::parse($params['start'] . ' 00:00:00', $tz);
$end = CarbonImmutable::parse(($params['end'] ?? $params['start']) . ' 23:59:59', $tz);
if (!empty($params['start']) && !empty($params['end'])) {
$start = CarbonImmutable::parse($params['start'], $tz)->setSecond(0);
$end = CarbonImmutable::parse($params['end'], $tz)->setSecond(59);
} else {
$start = CarbonImmutable::parse('-2 weeks', $tz);
$end = CarbonImmutable::now($tz);

View File

@ -80,8 +80,8 @@ class HistoryController
$params = $request->getQueryParams();
if (!empty($params['start']) && !empty($params['end'])) {
$start = CarbonImmutable::parse($params['start'], $station_tz);
$end = CarbonImmutable::parse($params['end'], $station_tz);
$start = CarbonImmutable::parse($params['start'], $station_tz)->setSecond(0);
$end = CarbonImmutable::parse($params['end'], $station_tz)->setSecond(59);
} else {
$start = CarbonImmutable::parse('-2 weeks', $station_tz);
$end = CarbonImmutable::now($station_tz);

View File

@ -81,20 +81,12 @@ class ListenersAction
$qb = $qb->andWhere('l.timestamp_end = 0');
} else {
$startString = $params['start'];
if (10 === strlen($startString)) {
$startString .= ' 00:00:00';
}
$start = CarbonImmutable::parse($startString, $stationTz);
$start = CarbonImmutable::parse($params['start'], $stationTz)
->setSecond(0);
$startTimestamp = $start->getTimestamp();
$endString = $params['end'] ?? $params['start'];
if (10 === strlen($endString)) {
$endString .= ' 23:59:59';
}
$end = CarbonImmutable::parse($endString, $stationTz);
$end = CarbonImmutable::parse($params['end'] ?? $params['start'], $stationTz)
->setSecond(59);
$endTimestamp = $end->getTimestamp();
$range = $start->format('Y-m-d_H-i-s') . '_to_' . $end->format('Y-m-d_H-i-s');