Fix datetime issues.

This commit is contained in:
Buster Neece 2023-01-06 12:39:51 -06:00
parent 4ceb167f5e
commit 10c8069719
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
4 changed files with 223 additions and 215 deletions

View File

@ -20,9 +20,6 @@
:fields="fields"
:api-url="apiUrl"
>
<template #cell(date_time)="row">
{{ formatTimestamp(row.item.timestamp) }}
</template>
<template #cell(operation)="row">
<span
v-if="row.item.operation_text === 'insert'"
@ -135,9 +132,21 @@ const dateRange = ref({
});
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const fields = [
{key: 'date_time', label: $gettext('Date/Time'), sortable: false},
{
key: 'timestamp',
label: $gettext('Date/Time'),
sortable: false,
formatter: (value) => {
return DateTime.fromSeconds(value).toLocaleString(
{
...DateTime.DATETIME_SHORT, ...timeConfig
}
);
}
},
{key: 'user', label: $gettext('User'), sortable: false},
{key: 'operation', isRowHeader: true, label: $gettext('Operation'), sortable: false},
{key: 'identifier', label: $gettext('Identifier'), sortable: false},
@ -160,16 +169,6 @@ const $dataTable = ref(); // DataTable Template Ref
const relist = () => {
$dataTable.value.relist();
};
const formatTimestamp = (unix_timestamp) => {
const {timeConfig} = useAzuraCast();
return DateTime.fromSeconds(unix_timestamp).toLocaleString(
{
...DateTime.DATETIME_SHORT, ...timeConfig
}
);
}
</script>
<style lang="scss">

View File

@ -5,7 +5,7 @@
<h2 class="card-title flex-fill my-0">
{{ $gettext('Song Playback Timeline') }}
</h2>
<div class="flex-shrink">
<div class="flex-shrink buttons">
<a
id="btn-export"
class="btn btn-bg"
@ -26,22 +26,13 @@
</div>
</div>
<data-table
ref="datatable"
ref="$datatable"
responsive
paginated
select-fields
:fields="fields"
:api-url="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>
<template #cell(delta)="row">
<span class="typography-subheading">
<template v-if="row.item.delta_total > 0">
@ -92,116 +83,121 @@
</div>
</template>
<script>
<script setup>
import Icon from "~/components/Common/Icon";
import DataTable from "~/components/Common/DataTable";
import DateRangeDropdown from "~/components/Common/DateRangeDropdown";
import {DateTime} from 'luxon';
import {useAzuraCast} from "~/vendor/azuracast";
import {computed, ref} from "vue";
import {useTranslate} from "~/vendor/gettext";
export default {
name: 'StationsReportsTimeline',
components: {DateRangeDropdown, DataTable, Icon},
props: {
baseApiUrl: {
type: String,
required: true
},
stationTimeZone: {
type: String,
required: true
}
const props = defineProps({
baseApiUrl: {
type: String,
required: true
},
data() {
let nowTz = DateTime.now().setZone(this.stationTimeZone);
return {
dateRange: {
startDate: nowTz.minus({days: 13}).toJSDate(),
endDate: nowTz.toJSDate(),
},
fields: [
{
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
}
],
}
},
computed: {
apiUrl() {
let apiUrl = new URL(this.baseApiUrl, document.location);
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();
},
exportUrl() {
let exportUrl = new URL(this.apiUrl, document.location);
let exportUrlParams = exportUrl.searchParams;
exportUrlParams.set('format', 'csv');
return exportUrl.toString();
},
},
methods: {
relist() {
this.$refs.datatable.relist();
},
abs(val) {
return Math.abs(val);
},
formatTimestamp(unix_timestamp) {
const {timeConfig} = useAzuraCast();
return DateTime.fromSeconds(unix_timestamp).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
},
formatTimestampStation(unix_timestamp) {
const {timeConfig} = useAzuraCast();
return DateTime.fromSeconds(unix_timestamp).setZone(this.stationTimeZone).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
}
stationTimeZone: {
type: String,
required: true
}
});
const nowTz = DateTime.now().setZone(props.stationTimeZone);
const dateRange = ref(
{
startDate: nowTz.minus({days: 13}).toJSDate(),
endDate: nowTz.toJSDate(),
}
);
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const fields = [
{
key: 'played_at',
label: $gettext('Date/Time (Browser)'),
selectable: true,
sortable: false,
formatter: (value) => {
return DateTime.fromSeconds(
value,
{zone: 'system'}
).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
}
},
{
key: 'played_at_station',
label: $gettext('Date/Time (Station)'),
sortable: false,
selectable: true,
visible: false,
formatter: (value, key, item) => {
return DateTime.fromSeconds(
item.played_at,
{zone: props.stationTimeZone}
).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
}
},
{
key: 'listeners_start',
label: $gettext('Listeners'),
selectable: true,
sortable: false
},
{
key: 'delta',
label: $gettext('Change'),
selectable: true,
sortable: false
},
{
key: 'song',
isRowHeader: true,
label: $gettext('Song Title'),
selectable: true,
sortable: false
},
{
key: 'source',
label: $gettext('Source'),
selectable: true,
sortable: false
}
];
const apiUrl = computed(() => {
let apiUrl = new URL(props.baseApiUrl, document.location);
let apiUrlParams = apiUrl.searchParams;
apiUrlParams.set('start', DateTime.fromJSDate(dateRange.value.startDate).toISO());
apiUrlParams.set('end', DateTime.fromJSDate(dateRange.value.endDate).toISO());
return apiUrl.toString();
});
const exportUrl = computed(() => {
let exportUrl = new URL(apiUrl.value, document.location);
let exportUrlParams = exportUrl.searchParams;
exportUrlParams.set('format', 'csv');
return exportUrl.toString();
});
const abs = (val) => {
return Math.abs(val);
};
const $datatable = ref(); // Template Ref
const relist = () => {
$datatable.value.relist();
};
</script>

View File

@ -1,7 +1,7 @@
<template>
<b-modal
id="streamer_broadcasts"
ref="modal"
ref="$modal"
size="lg"
centered
:title="$gettext('Streamer Broadcasts')"
@ -11,12 +11,12 @@
style="min-height: 40px;"
class="flex-fill text-left bg-primary rounded mb-2"
>
<inline-player ref="player" />
<inline-player ref="$player" />
</div>
<data-table
id="station_streamer_broadcasts"
ref="datatable"
ref="$datatable"
:show-toolbar="false"
:fields="fields"
:api-url="listUrl"
@ -65,7 +65,8 @@
</template>
</b-modal>
</template>
<script>
<script setup>
import DataTable from '~/components/Common/DataTable.vue';
import formatFileSize from '~/functions/formatFileSize.js';
import InlinePlayer from '~/components/InlinePlayer';
@ -74,95 +75,108 @@ import PlayButton from "~/components/Common/PlayButton";
import {DateTime} from 'luxon';
import '~/vendor/sweetalert';
import {useAzuraCast} from "~/vendor/azuracast";
import {ref} from "vue";
import {useTranslate} from "~/vendor/gettext";
import {useSweetAlert} from "~/vendor/sweetalert";
import {useNotify} from "~/vendor/bootstrapVue";
import {useAxios} from "~/vendor/axios";
export default {
name: 'StreamerBroadcastsModal',
components: {PlayButton, Icon, InlinePlayer, DataTable},
data() {
return {
listUrl: null,
fields: [
{
key: 'download',
label: ' ',
sortable: false,
class: 'shrink pr-3'
},
{
key: 'timestampStart',
label: this.$gettext('Start Time'),
sortable: false,
formatter: (value) => {
const {timeConfig} = useAzuraCast();
const listUrl = ref(null);
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
},
class: 'pl-3'
},
{
key: 'timestampEnd',
label: this.$gettext('End Time'),
sortable: false,
formatter: (value) => {
if (value === 0) {
return this.$gettext('Live');
}
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const {timeConfig} = useAzuraCast();
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
}
},
{
key: 'size',
label: this.$gettext('Size'),
sortable: false,
formatter: (value, key, item) => {
if (!item.recording?.size) {
return '';
}
return formatFileSize(item.recording.size);
}
},
{
key: 'actions',
label: this.$gettext('Actions'),
sortable: false,
class: 'shrink'
}
]
};
const fields = [
{
key: 'download',
label: ' ',
sortable: false,
class: 'shrink pr-3'
},
methods: {
doDelete (url) {
this.$confirmDelete({
title: this.$gettext('Delete Broadcast?')
}).then((result) => {
if (result.value) {
this.axios.delete(url).then((resp) => {
this.$notifySuccess(resp.data.message);
this.$refs.datatable.refresh();
});
this.$refs.datatable.refresh();
}
});
{
key: 'timestampStart',
label: $gettext('Start Time'),
sortable: false,
formatter: (value) => {
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
},
open (listUrl) {
this.listUrl = listUrl;
this.$refs.modal.show();
},
close () {
this.$refs.player.stop();
class: 'pl-3'
},
{
key: 'timestampEnd',
label: $gettext('End Time'),
sortable: false,
formatter: (value) => {
if (value === 0) {
return $gettext('Live');
}
this.listUrl = null;
this.$refs.modal.hide();
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
}
},
{
key: 'size',
label: $gettext('Size'),
sortable: false,
formatter: (value, key, item) => {
if (!item.recording?.size) {
return '';
}
return formatFileSize(item.recording.size);
}
},
{
key: 'actions',
label: $gettext('Actions'),
sortable: false,
class: 'shrink'
}
];
const {confirmDelete} = useSweetAlert();
const {notifySuccess} = useNotify();
const {axios} = useAxios();
const $datatable = ref(); // Template Ref
const doDelete = (url) => {
confirmDelete({
title: $gettext('Delete Broadcast?')
}).then((result) => {
if (result.value) {
axios.delete(url).then((resp) => {
notifySuccess(resp.data.message);
$datatable.value.refresh();
});
$datatable.value.refresh();
}
});
};
const $modal = ref(); // Template Ref
const open = (newListUrl) => {
listUrl.value = newListUrl;
$modal.value.show();
};
const $player = ref(); // Template Ref
const close = () => {
$player.value.stop();
listUrl.value = null;
$modal.value.hide();
};
defineExpose({
open
});
</script>

View File

@ -5,5 +5,4 @@ const {localeWithDashes} = useAzuraCast();
document.addEventListener('DOMContentLoaded', function () {
Settings.defaultLocale = localeWithDashes;
Settings.defaultZone = 'UTC';
});