More Composition conversion and fixes.
This commit is contained in:
parent
1ef68f64fc
commit
e0f5178ba4
|
@ -106,4 +106,8 @@ const update = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(update);
|
onMounted(update);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
update
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="col-md-8 buttons">
|
<div class="col-md-8 buttons">
|
||||||
<div class="btn-group dropdown allow-focus">
|
<div class="btn-group dropdown allow-focus">
|
||||||
<b-dropdown
|
<b-dropdown
|
||||||
ref="setPlaylistsDropdown"
|
ref="$setPlaylistsDropdown"
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
@ -69,21 +69,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<b-button
|
<div class="buttons">
|
||||||
type="submit"
|
<b-button
|
||||||
size="sm"
|
type="submit"
|
||||||
variant="primary"
|
size="sm"
|
||||||
>
|
variant="primary"
|
||||||
{{ $gettext('Save') }}
|
>
|
||||||
</b-button>
|
{{ $gettext('Save') }}
|
||||||
<b-button
|
</b-button>
|
||||||
type="button"
|
<b-button
|
||||||
size="sm"
|
type="button"
|
||||||
variant="warning"
|
size="sm"
|
||||||
@click="clearPlaylists()"
|
variant="warning"
|
||||||
>
|
@click="clearPlaylists()"
|
||||||
{{ $gettext('Clear') }}
|
>
|
||||||
</b-button>
|
{{ $gettext('Clear') }}
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
</b-dropdown-form>
|
</b-dropdown-form>
|
||||||
</b-dropdown>
|
</b-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
@ -148,188 +150,200 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
|
<script setup>
|
||||||
import {forEach, intersection, map} from 'lodash';
|
import {forEach, intersection, map} from 'lodash';
|
||||||
import Icon from '~/components/Common/Icon';
|
import Icon from '~/components/Common/Icon';
|
||||||
import '~/vendor/sweetalert';
|
import '~/vendor/sweetalert';
|
||||||
|
import {h, ref, toRef, watch} from "vue";
|
||||||
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
|
import {useNotify} from "~/vendor/bootstrapVue";
|
||||||
|
import {useAxios} from "~/vendor/axios";
|
||||||
|
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
currentDirectory: {
|
||||||
export default {
|
type: String,
|
||||||
name: 'StationMediaToolbar',
|
required: true
|
||||||
components: {Icon},
|
},
|
||||||
props: {
|
selectedItems: {
|
||||||
currentDirectory: {
|
type: Object,
|
||||||
type: String,
|
required: true
|
||||||
required: true
|
},
|
||||||
},
|
playlists: {
|
||||||
selectedItems: {
|
type: Array,
|
||||||
type: Object,
|
default: () => {
|
||||||
required: true
|
return [];
|
||||||
},
|
|
||||||
playlists: {
|
|
||||||
type: Array,
|
|
||||||
default: () => {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
batchUrl: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
supportsImmediateQueue: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['relist', 'add-playlist'],
|
batchUrl: {
|
||||||
data() {
|
type: String,
|
||||||
return {
|
required: true
|
||||||
checkedPlaylists: [],
|
|
||||||
newPlaylist: '',
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
supportsImmediateQueue: {
|
||||||
langErrors() {
|
type: Boolean,
|
||||||
return this.$gettext('The request could not be processed.');
|
required: true
|
||||||
},
|
}
|
||||||
},
|
});
|
||||||
watch: {
|
|
||||||
selectedItems (items) {
|
|
||||||
// Get all playlists that are active on ALL selected items.
|
|
||||||
let playlistsForItems = map(items.all, (item) => {
|
|
||||||
return map(item.playlists, 'id');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check the checkboxes for those playlists.
|
const emit = defineEmits(['relist', 'add-playlist']);
|
||||||
this.checkedPlaylists = intersection(...playlistsForItems);
|
|
||||||
},
|
|
||||||
newPlaylist (text) {
|
|
||||||
if (text !== '') {
|
|
||||||
if (!this.checkedPlaylists.includes('new')) {
|
|
||||||
this.checkedPlaylists.push('new');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
doImmediateQueue() {
|
|
||||||
this.doBatch('immediate', this.$gettext('Files played immediately:'));
|
|
||||||
},
|
|
||||||
doQueue() {
|
|
||||||
this.doBatch('queue', this.$gettext('Files queued for playback:'));
|
|
||||||
},
|
|
||||||
doReprocess() {
|
|
||||||
this.doBatch('reprocess', this.$gettext('Files marked for reprocessing:'));
|
|
||||||
},
|
|
||||||
doDelete() {
|
|
||||||
let buttonConfirmText = this.$gettext('Delete %{ num } media files?');
|
|
||||||
let numFiles = this.selectedItems.all.length;
|
|
||||||
|
|
||||||
this.$confirmDelete({
|
const checkedPlaylists = ref([]);
|
||||||
title: this.$gettextInterpolate(buttonConfirmText, {num: numFiles}),
|
const newPlaylist = ref('');
|
||||||
}).then((result) => {
|
|
||||||
if (result.value) {
|
|
||||||
this.doBatch('delete', this.$gettext('Files removed:'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
doBatch (action, notifyMessage) {
|
|
||||||
if (this.selectedItems.all.length) {
|
|
||||||
this.$wrapWithLoading(
|
|
||||||
this.axios.put(this.batchUrl, {
|
|
||||||
'do': action,
|
|
||||||
'current_directory': this.currentDirectory,
|
|
||||||
'files': this.selectedItems.files,
|
|
||||||
'dirs': this.selectedItems.directories
|
|
||||||
})
|
|
||||||
).then((resp) => {
|
|
||||||
if (resp.data.success) {
|
|
||||||
let allItemNodes = [];
|
|
||||||
forEach(this.selectedItems.all, (item) => {
|
|
||||||
allItemNodes.push(this.$createElement('div', {}, item.path_short));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$notifySuccess(allItemNodes, {
|
const {$gettext} = useTranslate();
|
||||||
title: notifyMessage
|
const langErrors = $gettext('The request could not be processed.');
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let errorNodes = [];
|
|
||||||
forEach(resp.data.errors, (error) => {
|
|
||||||
errorNodes.push(this.$createElement('div', {}, error));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$notifyError(errorNodes, {
|
watch(toRef(props, 'selectedItems'), (items) => {
|
||||||
title: this.langErrors
|
// Get all playlists that are active on ALL selected items.
|
||||||
});
|
let playlistsForItems = map(items.all, (item) => {
|
||||||
}
|
return map(item.playlists, 'id');
|
||||||
|
});
|
||||||
|
|
||||||
this.$emit('relist');
|
// Check the checkboxes for those playlists.
|
||||||
});
|
checkedPlaylists.value = intersection(...playlistsForItems);
|
||||||
} else {
|
});
|
||||||
this.notifyNoFiles();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
clearPlaylists () {
|
|
||||||
this.checkedPlaylists = [];
|
|
||||||
this.newPlaylist = '';
|
|
||||||
|
|
||||||
this.setPlaylists();
|
watch(newPlaylist, (text) => {
|
||||||
},
|
if (text !== '') {
|
||||||
setPlaylists () {
|
if (!checkedPlaylists.value.includes('new')) {
|
||||||
this.$refs.setPlaylistsDropdown.hide();
|
checkedPlaylists.value.push('new');
|
||||||
|
|
||||||
if (this.selectedItems.all.length) {
|
|
||||||
this.$wrapWithLoading(
|
|
||||||
this.axios.put(this.batchUrl, {
|
|
||||||
'do': 'playlist',
|
|
||||||
'playlists': this.checkedPlaylists,
|
|
||||||
'new_playlist_name': this.newPlaylist,
|
|
||||||
'currentDirectory': this.currentDirectory,
|
|
||||||
'files': this.selectedItems.files,
|
|
||||||
'dirs': this.selectedItems.directories
|
|
||||||
})
|
|
||||||
).then((resp) => {
|
|
||||||
if (resp.data.success) {
|
|
||||||
if (resp.data.record) {
|
|
||||||
this.$emit('add-playlist', resp.data.record);
|
|
||||||
}
|
|
||||||
|
|
||||||
let notifyMessage = (this.checkedPlaylists.length > 0)
|
|
||||||
? this.$gettext('Playlists updated for selected files:')
|
|
||||||
: this.$gettext('Playlists cleared for selected files:');
|
|
||||||
|
|
||||||
let allItemNodes = [];
|
|
||||||
forEach(this.selectedItems.all, (item) => {
|
|
||||||
allItemNodes.push(this.$createElement('div', {}, item.path_short));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$notifySuccess(allItemNodes, {
|
|
||||||
title: notifyMessage
|
|
||||||
});
|
|
||||||
|
|
||||||
this.checkedPlaylists = [];
|
|
||||||
this.newPlaylist = '';
|
|
||||||
} else {
|
|
||||||
let errorNodes = [];
|
|
||||||
forEach(resp.data.errors, (error) => {
|
|
||||||
errorNodes.push(this.$createElement('div', {}, error));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$notifyError(errorNodes, {
|
|
||||||
title: this.langErrors
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('relist');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.notifyNoFiles();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
notifyNoFiles() {
|
|
||||||
this.$notifyError(this.$gettext('No files selected.'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const {wrapWithLoading, notifySuccess, notifyError} = useNotify();
|
||||||
|
const {axios} = useAxios();
|
||||||
|
|
||||||
|
const notifyNoFiles = () => {
|
||||||
|
notifyError($gettext('No files selected.'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const doBatch = (action, notifyMessage) => {
|
||||||
|
if (props.selectedItems.all.length) {
|
||||||
|
wrapWithLoading(
|
||||||
|
axios.put(props.batchUrl, {
|
||||||
|
'do': action,
|
||||||
|
'current_directory': props.currentDirectory,
|
||||||
|
'files': props.selectedItems.files,
|
||||||
|
'dirs': props.selectedItems.directories
|
||||||
|
})
|
||||||
|
).then((resp) => {
|
||||||
|
if (resp.data.success) {
|
||||||
|
let allItemNodes = [];
|
||||||
|
forEach(props.selectedItems.all, (item) => {
|
||||||
|
allItemNodes.push(h('div', {}, item.path_short));
|
||||||
|
});
|
||||||
|
|
||||||
|
notifySuccess(allItemNodes, {
|
||||||
|
title: notifyMessage
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let errorNodes = [];
|
||||||
|
forEach(resp.data.errors, (error) => {
|
||||||
|
errorNodes.push(h('div', {}, error));
|
||||||
|
});
|
||||||
|
|
||||||
|
notifyError(errorNodes, {
|
||||||
|
title: langErrors
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('relist');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notifyNoFiles();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const doImmediateQueue = () => {
|
||||||
|
doBatch('immediate', $gettext('Files played immediately:'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const doQueue = () => {
|
||||||
|
doBatch('queue', $gettext('Files queued for playback:'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const doReprocess = () => {
|
||||||
|
doBatch('reprocess', $gettext('Files marked for reprocessing:'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const {confirmDelete} = useSweetAlert();
|
||||||
|
|
||||||
|
const doDelete = () => {
|
||||||
|
let numFiles = this.selectedItems.all.length;
|
||||||
|
let buttonConfirmText = $gettext(
|
||||||
|
'Delete %{ num } media files?',
|
||||||
|
{num: numFiles}
|
||||||
|
);
|
||||||
|
|
||||||
|
confirmDelete({
|
||||||
|
title: buttonConfirmText,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.value) {
|
||||||
|
doBatch('delete', $gettext('Files removed:'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const $setPlaylistsDropdown = ref(); // Template Ref
|
||||||
|
|
||||||
|
const setPlaylists = () => {
|
||||||
|
$setPlaylistsDropdown.value.hide();
|
||||||
|
|
||||||
|
if (props.selectedItems.all.length) {
|
||||||
|
wrapWithLoading(
|
||||||
|
axios.put(props.batchUrl, {
|
||||||
|
'do': 'playlist',
|
||||||
|
'playlists': checkedPlaylists.value,
|
||||||
|
'new_playlist_name': newPlaylist.value,
|
||||||
|
'currentDirectory': props.currentDirectory,
|
||||||
|
'files': props.selectedItems.files,
|
||||||
|
'dirs': props.selectedItems.directories
|
||||||
|
})
|
||||||
|
).then((resp) => {
|
||||||
|
if (resp.data.success) {
|
||||||
|
if (resp.data.record) {
|
||||||
|
emit('add-playlist', resp.data.record);
|
||||||
|
}
|
||||||
|
|
||||||
|
let notifyMessage = (checkedPlaylists.value.length > 0)
|
||||||
|
? $gettext('Playlists updated for selected files:')
|
||||||
|
: $gettext('Playlists cleared for selected files:');
|
||||||
|
|
||||||
|
let allItemNodes = [];
|
||||||
|
forEach(props.selectedItems.all, (item) => {
|
||||||
|
allItemNodes.push(h('div', {}, item.path_short));
|
||||||
|
});
|
||||||
|
|
||||||
|
notifySuccess(allItemNodes, {
|
||||||
|
title: notifyMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
checkedPlaylists.value = [];
|
||||||
|
newPlaylist.value = '';
|
||||||
|
} else {
|
||||||
|
let errorNodes = [];
|
||||||
|
forEach(resp.data.errors, (error) => {
|
||||||
|
errorNodes.push(h('div', {}, error));
|
||||||
|
});
|
||||||
|
|
||||||
|
notifyError(errorNodes, {
|
||||||
|
title: langErrors
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('relist');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notifyNoFiles();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearPlaylists = () => {
|
||||||
|
checkedPlaylists.value = [];
|
||||||
|
newPlaylist.value = '';
|
||||||
|
|
||||||
|
setPlaylists();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline-light"
|
variant="outline-light"
|
||||||
class="py-2 pr-0"
|
class="py-2 pr-0"
|
||||||
@click.prevent="$emit('remove')"
|
@click.prevent="doRemove()"
|
||||||
>
|
>
|
||||||
<icon icon="remove" />
|
<icon icon="remove" />
|
||||||
{{ $gettext('Remove') }}
|
{{ $gettext('Remove') }}
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_start_time_'+index"
|
:id="'edit_form_start_time_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.start_time"
|
:field="v$.start_time"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Start Time') }}
|
{{ $gettext('Start Time') }}
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_end_time_'+index"
|
:id="'edit_form_end_time_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.end_time"
|
:field="v$.end_time"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('End Time') }}
|
{{ $gettext('End Time') }}
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_start_date_'+index"
|
:id="'edit_form_start_date_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.start_date"
|
:field="v$.start_date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Start Date') }}
|
{{ $gettext('Start Date') }}
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_end_date_'+index"
|
:id="'edit_form_end_date_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.end_date"
|
:field="v$.end_date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('End Date') }}
|
{{ $gettext('End Date') }}
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
<b-wrapped-form-checkbox
|
<b-wrapped-form-checkbox
|
||||||
:id="'edit_form_loop_once_'+index"
|
:id="'edit_form_loop_once_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.loop_once"
|
:field="v$.loop_once"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Loop Once') }}
|
{{ $gettext('Loop Once') }}
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
<template #default>
|
<template #default>
|
||||||
<b-checkbox-group
|
<b-checkbox-group
|
||||||
:id="'edit_form_days_'+index"
|
:id="'edit_form_days_'+index"
|
||||||
v-model="v$.row.days.$model"
|
v-model="v$.days.$model"
|
||||||
stacked
|
stacked
|
||||||
:options="dayOptions"
|
:options="dayOptions"
|
||||||
/>
|
/>
|
||||||
|
@ -158,59 +158,56 @@
|
||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import PlaylistTime from '~/components/Common/TimeCode';
|
import PlaylistTime from '~/components/Common/TimeCode';
|
||||||
import Icon from "~/components/Common/Icon.vue";
|
import Icon from "~/components/Common/Icon.vue";
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup.vue";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup.vue";
|
||||||
import {required} from "@vuelidate/validators";
|
import {required} from "@vuelidate/validators";
|
||||||
import useVuelidate from "@vuelidate/core";
|
import useVuelidate from "@vuelidate/core";
|
||||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox.vue";
|
import {toRef} from "vue";
|
||||||
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
stationTimeZone: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(['remove']);
|
||||||
name: 'PlaylistsFormScheduleRow',
|
|
||||||
components: {BWrappedFormCheckbox, BWrappedFormGroup, Icon, PlaylistTime},
|
const v$ = useVuelidate(
|
||||||
props: {
|
{
|
||||||
index: {
|
'start_time': {required},
|
||||||
type: Number,
|
'end_time': {required},
|
||||||
required: true
|
'start_date': {},
|
||||||
},
|
'end_date': {},
|
||||||
row: {
|
'loop_once': {}
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
stationTimeZone: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
emits: ['remove'],
|
toRef(props, 'row')
|
||||||
setup() {
|
);
|
||||||
return {v$: useVuelidate()}
|
|
||||||
},
|
const {$gettext} = useTranslate();
|
||||||
validations: {
|
|
||||||
row: {
|
const dayOptions = [
|
||||||
'start_time': {required},
|
{value: 1, text: $gettext('Monday')},
|
||||||
'end_time': {required},
|
{value: 2, text: $gettext('Tuesday')},
|
||||||
'start_date': {},
|
{value: 3, text: $gettext('Wednesday')},
|
||||||
'end_date': {},
|
{value: 4, text: $gettext('Thursday')},
|
||||||
'days': {},
|
{value: 5, text: $gettext('Friday')},
|
||||||
'loop_once': {}
|
{value: 6, text: $gettext('Saturday')},
|
||||||
}
|
{value: 7, text: $gettext('Sunday')}
|
||||||
},
|
];
|
||||||
data() {
|
|
||||||
return {
|
const doRemove = () => {
|
||||||
dayOptions: [
|
emit('remove');
|
||||||
{value: 1, text: this.$gettext('Monday')},
|
};
|
||||||
{value: 2, text: this.$gettext('Tuesday')},
|
|
||||||
{value: 3, text: this.$gettext('Wednesday')},
|
|
||||||
{value: 4, text: this.$gettext('Thursday')},
|
|
||||||
{value: 5, text: this.$gettext('Friday')},
|
|
||||||
{value: 6, text: this.$gettext('Saturday')},
|
|
||||||
{value: 7, text: this.$gettext('Sunday')}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
class="text-right text-white-50"
|
class="text-right text-white-50"
|
||||||
>
|
>
|
||||||
<stations-common-quota
|
<stations-common-quota
|
||||||
ref="quota"
|
ref="$quota"
|
||||||
:quota-url="quotaUrl"
|
:quota-url="quotaUrl"
|
||||||
/>
|
/>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
<data-table
|
<data-table
|
||||||
id="station_podcast_episodes"
|
id="station_podcast_episodes"
|
||||||
ref="datatable"
|
ref="$datatable"
|
||||||
paginated
|
paginated
|
||||||
:fields="fields"
|
:fields="fields"
|
||||||
:responsive="false"
|
:responsive="false"
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<edit-modal
|
<edit-modal
|
||||||
ref="editEpisodeModal"
|
ref="$editEpisodeModal"
|
||||||
:create-url="podcast.links.episodes"
|
:create-url="podcast.links.episodes"
|
||||||
:station-time-zone="stationTimeZone"
|
:station-time-zone="stationTimeZone"
|
||||||
:new-art-url="podcast.links.episode_new_art"
|
:new-art-url="podcast.links.episode_new_art"
|
||||||
|
@ -118,68 +118,77 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import DataTable from '~/components/Common/DataTable';
|
import DataTable from '~/components/Common/DataTable';
|
||||||
import EditModal from './EpisodeEditModal';
|
import EditModal from './EpisodeEditModal';
|
||||||
import Icon from '~/components/Common/Icon';
|
import Icon from '~/components/Common/Icon';
|
||||||
import AlbumArt from '~/components/Common/AlbumArt';
|
import AlbumArt from '~/components/Common/AlbumArt';
|
||||||
import StationsCommonQuota from "~/components/Stations/Common/Quota";
|
import StationsCommonQuota from "~/components/Stations/Common/Quota";
|
||||||
import episodesViewProps from "~/components/Stations/Podcasts/episodesViewProps";
|
import episodesViewProps from "~/components/Stations/Podcasts/episodesViewProps";
|
||||||
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||||
|
import {useNotify} from "~/vendor/bootstrapVue";
|
||||||
|
import {useAxios} from "~/vendor/axios";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
...episodesViewProps,
|
||||||
|
podcast: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(['clear-podcast']);
|
||||||
name: 'EpisodesView',
|
|
||||||
components: {StationsCommonQuota, AlbumArt, Icon, EditModal, DataTable},
|
const {$gettext} = useTranslate();
|
||||||
props: {
|
|
||||||
...episodesViewProps,
|
const fields = [
|
||||||
podcast: {
|
{key: 'art', label: $gettext('Art'), sortable: false, class: 'shrink pr-0'},
|
||||||
type: Object,
|
{key: 'title', label: $gettext('Episode'), sortable: false},
|
||||||
required: true
|
{key: 'podcast_media', label: $gettext('File Name'), sortable: false},
|
||||||
}
|
{key: 'explicit', label: $gettext('Explicit'), sortable: false},
|
||||||
},
|
{key: 'actions', label: $gettext('Actions'), sortable: false, class: 'shrink'}
|
||||||
emits: ['clear-podcast'],
|
];
|
||||||
data() {
|
|
||||||
return {
|
const $quota = ref(); // Template Ref
|
||||||
fields: [
|
const $datatable = ref(); // Template Ref
|
||||||
{key: 'art', label: this.$gettext('Art'), sortable: false, class: 'shrink pr-0'},
|
|
||||||
{key: 'title', label: this.$gettext('Episode'), sortable: false},
|
const relist = () => {
|
||||||
{key: 'podcast_media', label: this.$gettext('File Name'), sortable: false},
|
$quota.value.update();
|
||||||
{key: 'explicit', label: this.$gettext('Explicit'), sortable: false},
|
$datatable.value?.refresh();
|
||||||
{key: 'actions', label: this.$gettext('Actions'), sortable: false, class: 'shrink'}
|
};
|
||||||
]
|
|
||||||
};
|
const $editEpisodeModal = ref(); // Template Ref
|
||||||
},
|
|
||||||
methods: {
|
const doCreate = () => {
|
||||||
relist () {
|
$editEpisodeModal.value.create();
|
||||||
this.$refs.quota.update();
|
};
|
||||||
if (this.$refs.datatable) {
|
|
||||||
this.$refs.datatable.refresh();
|
const doEdit = (url) => {
|
||||||
}
|
$editEpisodeModal.value.edit(url);
|
||||||
},
|
};
|
||||||
doCreate () {
|
|
||||||
this.$refs.editEpisodeModal.create();
|
const doClearPodcast = () => {
|
||||||
},
|
emit('clear-podcast');
|
||||||
doEdit (url) {
|
};
|
||||||
this.$refs.editEpisodeModal.edit(url);
|
|
||||||
},
|
const {confirmDelete} = useSweetAlert();
|
||||||
doClearPodcast () {
|
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||||
this.$emit('clear-podcast');
|
const {axios} = useAxios();
|
||||||
},
|
|
||||||
doDelete (url) {
|
const doDelete = (url) => {
|
||||||
this.$confirmDelete({
|
confirmDelete({
|
||||||
title: this.$gettext('Delete Episode?'),
|
title: $gettext('Delete Episode?'),
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.value) {
|
if (result.value) {
|
||||||
this.$wrapWithLoading(
|
wrapWithLoading(
|
||||||
this.axios.delete(url)
|
axios.delete(url)
|
||||||
).then((resp) => {
|
).then((resp) => {
|
||||||
this.$notifySuccess(resp.data.message);
|
notifySuccess(resp.data.message);
|
||||||
this.relist();
|
relist();
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
class="text-right text-white-50"
|
class="text-right text-white-50"
|
||||||
>
|
>
|
||||||
<stations-common-quota
|
<stations-common-quota
|
||||||
ref="quota"
|
ref="$quota"
|
||||||
:quota-url="quotaUrl"
|
:quota-url="quotaUrl"
|
||||||
/>
|
/>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<data-table
|
<data-table
|
||||||
id="station_podcasts"
|
id="station_podcasts"
|
||||||
ref="datatable"
|
ref="$datatable"
|
||||||
paginated
|
paginated
|
||||||
:fields="fields"
|
:fields="fields"
|
||||||
:responsive="false"
|
:responsive="false"
|
||||||
|
@ -58,9 +58,6 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ $gettext('RSS Feed') }}</a>
|
>{{ $gettext('RSS Feed') }}</a>
|
||||||
</template>
|
</template>
|
||||||
<template #cell(num_episodes)="row">
|
|
||||||
{{ countEpisodes(row.item.episodes) }}
|
|
||||||
</template>
|
|
||||||
<template #cell(actions)="row">
|
<template #cell(actions)="row">
|
||||||
<b-button-group size="sm">
|
<b-button-group size="sm">
|
||||||
<b-button
|
<b-button
|
||||||
|
@ -90,7 +87,7 @@
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<edit-modal
|
<edit-modal
|
||||||
ref="editPodcastModal"
|
ref="$editPodcastModal"
|
||||||
:create-url="listUrl"
|
:create-url="listUrl"
|
||||||
:station-time-zone="stationTimeZone"
|
:station-time-zone="stationTimeZone"
|
||||||
:new-art-url="newArtUrl"
|
:new-art-url="newArtUrl"
|
||||||
|
@ -100,65 +97,78 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import DataTable from '~/components/Common/DataTable';
|
import DataTable from '~/components/Common/DataTable';
|
||||||
import EditModal from './PodcastEditModal';
|
import EditModal from './PodcastEditModal';
|
||||||
import AlbumArt from '~/components/Common/AlbumArt';
|
import AlbumArt from '~/components/Common/AlbumArt';
|
||||||
import StationsCommonQuota from "~/components/Stations/Common/Quota";
|
import StationsCommonQuota from "~/components/Stations/Common/Quota";
|
||||||
import listViewProps from "./listViewProps";
|
import listViewProps from "./listViewProps";
|
||||||
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||||
|
import {useNotify} from "~/vendor/bootstrapVue";
|
||||||
|
import {useAxios} from "~/vendor/axios";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
...listViewProps
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(['select-podcast']);
|
||||||
name: 'ListView',
|
|
||||||
components: {StationsCommonQuota, AlbumArt, EditModal, DataTable},
|
const {$gettext} = useTranslate();
|
||||||
props: {
|
|
||||||
...listViewProps
|
const fields = [
|
||||||
|
{key: 'art', label: $gettext('Art'), sortable: false, class: 'shrink pr-0'},
|
||||||
|
{key: 'title', label: $gettext('Podcast'), sortable: false},
|
||||||
|
{
|
||||||
|
key: 'episodes',
|
||||||
|
label: $gettext('# Episodes'),
|
||||||
|
sortable: false,
|
||||||
|
formatter: (val) => {
|
||||||
|
return val.length;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emits: ['select-podcast'],
|
{key: 'actions', label: $gettext('Actions'), sortable: false, class: 'shrink'}
|
||||||
data() {
|
];
|
||||||
return {
|
|
||||||
fields: [
|
const $quota = ref(); // Template Ref
|
||||||
{key: 'art', label: this.$gettext('Art'), sortable: false, class: 'shrink pr-0'},
|
const $datatable = ref(); // Template Ref
|
||||||
{key: 'title', label: this.$gettext('Podcast'), sortable: false},
|
|
||||||
{key: 'num_episodes', label: this.$gettext('# Episodes'), sortable: false},
|
const relist = () => {
|
||||||
{key: 'actions', label: this.$gettext('Actions'), sortable: false, class: 'shrink'}
|
$quota.value.update();
|
||||||
]
|
$datatable.value?.refresh();
|
||||||
};
|
};
|
||||||
},
|
|
||||||
methods: {
|
const $editPodcastModal = ref(); // Template Ref
|
||||||
countEpisodes (episodes) {
|
|
||||||
return episodes.length;
|
const doCreate = () => {
|
||||||
},
|
$editPodcastModal.value.create();
|
||||||
relist () {
|
};
|
||||||
this.$refs.quota.update();
|
|
||||||
if (this.$refs.datatable) {
|
const doEdit = (url) => {
|
||||||
this.$refs.datatable.refresh();
|
$editPodcastModal.value.edit(url);
|
||||||
}
|
};
|
||||||
},
|
|
||||||
doCreate () {
|
const doSelectPodcast = (podcast) => {
|
||||||
this.$refs.editPodcastModal.create();
|
emit('select-podcast', podcast);
|
||||||
},
|
};
|
||||||
doEdit (url) {
|
|
||||||
this.$refs.editPodcastModal.edit(url);
|
const {confirmDelete} = useSweetAlert();
|
||||||
},
|
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||||
doSelectPodcast (podcast) {
|
const {axios} = useAxios();
|
||||||
this.$emit('select-podcast', podcast);
|
|
||||||
},
|
const doDelete = (url) => {
|
||||||
doDelete (url) {
|
confirmDelete({
|
||||||
this.$confirmDelete({
|
title: $gettext('Delete Podcast?'),
|
||||||
title: this.$gettext('Delete Podcast?'),
|
}).then((result) => {
|
||||||
}).then((result) => {
|
if (result.value) {
|
||||||
if (result.value) {
|
wrapWithLoading(
|
||||||
this.$wrapWithLoading(
|
axios.delete(url)
|
||||||
this.axios.delete(url)
|
).then((resp) => {
|
||||||
).then((resp) => {
|
notifySuccess(resp.data.message);
|
||||||
this.$notifySuccess(resp.data.message);
|
relist();
|
||||||
this.relist();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -132,74 +132,57 @@
|
||||||
</b-tab>
|
</b-tab>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
||||||
|
import {map} from "lodash";
|
||||||
|
import {computed} from "vue";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
form: {
|
||||||
export default {
|
type: Object,
|
||||||
name: 'RemoteFormAutoDj',
|
required: true
|
||||||
components: {BWrappedFormCheckbox, BWrappedFormGroup},
|
|
||||||
props: {
|
|
||||||
form: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
stationFrontendType: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
stationFrontendType: {
|
||||||
formatOptions() {
|
type: String,
|
||||||
return [
|
required: true
|
||||||
{
|
|
||||||
value: 'mp3',
|
|
||||||
text: 'MP3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'ogg',
|
|
||||||
text: 'OGG Vorbis'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'opus',
|
|
||||||
text: 'OGG Opus'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'aac',
|
|
||||||
text: 'AAC+ (MPEG4 HE-AAC v2)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'flac',
|
|
||||||
text: 'FLAC (OGG FLAC)'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
},
|
|
||||||
bitrateOptions() {
|
|
||||||
let options = [];
|
|
||||||
[32, 48, 64, 96, 128, 192, 256, 320].forEach((val) => {
|
|
||||||
options.push({
|
|
||||||
value: val,
|
|
||||||
text: val
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
},
|
|
||||||
formatSupportsBitrateOptions() {
|
|
||||||
switch (this.form.autodj_format.$model) {
|
|
||||||
case 'flac':
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case 'mp3':
|
|
||||||
case 'ogg':
|
|
||||||
case 'opus':
|
|
||||||
case 'aac':
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
const formatOptions = [
|
||||||
|
{
|
||||||
|
value: 'mp3',
|
||||||
|
text: 'MP3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'ogg',
|
||||||
|
text: 'OGG Vorbis'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'opus',
|
||||||
|
text: 'OGG Opus'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'aac',
|
||||||
|
text: 'AAC+ (MPEG4 HE-AAC v2)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'flac',
|
||||||
|
text: 'FLAC (OGG FLAC)'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const bitrateOptions = map(
|
||||||
|
[32, 48, 64, 96, 128, 192, 256, 320],
|
||||||
|
(val) => {
|
||||||
|
return {
|
||||||
|
value: val,
|
||||||
|
text: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const formatSupportsBitrateOptions = computed(() => {
|
||||||
|
return props.form.autodj_format.$model !== 'flac';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -103,39 +103,30 @@
|
||||||
</b-tab>
|
</b-tab>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import {REMOTE_ICECAST, REMOTE_SHOUTCAST1, REMOTE_SHOUTCAST2} from '~/components/Entity/RadioAdapters';
|
import {REMOTE_ICECAST, REMOTE_SHOUTCAST1, REMOTE_SHOUTCAST2} from '~/components/Entity/RadioAdapters';
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
form: {
|
||||||
export default {
|
type: Object,
|
||||||
name: 'RemoteFormBasicInfo',
|
required: true
|
||||||
components: {BWrappedFormCheckbox, BWrappedFormGroup},
|
|
||||||
props: {
|
|
||||||
form: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
typeOptions() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
value: REMOTE_ICECAST,
|
|
||||||
text: 'Icecast v2.4+',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: REMOTE_SHOUTCAST1,
|
|
||||||
text: 'Shoutcast v1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: REMOTE_SHOUTCAST2,
|
|
||||||
text: 'Shoutcast v2',
|
|
||||||
}
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
const typeOptions = [
|
||||||
|
{
|
||||||
|
value: REMOTE_ICECAST,
|
||||||
|
text: 'Icecast v2.4+',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: REMOTE_SHOUTCAST1,
|
||||||
|
text: 'Shoutcast v1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: REMOTE_SHOUTCAST2,
|
||||||
|
text: 'Shoutcast v2',
|
||||||
|
}
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -86,6 +86,7 @@ import {computed, ref} from "vue";
|
||||||
import {useTranslate} from "~/vendor/gettext";
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||||
import {useNotify} from "~/vendor/bootstrapVue";
|
import {useNotify} from "~/vendor/bootstrapVue";
|
||||||
|
import {useAxios} from "~/vendor/axios";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
listUrl: {
|
listUrl: {
|
||||||
|
@ -150,6 +151,7 @@ const formatTime = (time) => {
|
||||||
|
|
||||||
const {confirmDelete} = useSweetAlert();
|
const {confirmDelete} = useSweetAlert();
|
||||||
const {wrapWithLoading, notifySuccess} = useNotify();
|
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||||
|
const {axios} = useAxios();
|
||||||
|
|
||||||
const doDelete = (url) => {
|
const doDelete = (url) => {
|
||||||
confirmDelete({
|
confirmDelete({
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
id="form_start_date"
|
id="form_start_date"
|
||||||
name="start_date"
|
name="start_date"
|
||||||
:field="v$.form.start_date"
|
:field="v$.start_date"
|
||||||
input-type="date"
|
input-type="date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
id="form_end_date"
|
id="form_end_date"
|
||||||
name="end_date"
|
name="end_date"
|
||||||
:field="v$.form.end_date"
|
:field="v$.end_date"
|
||||||
input-type="date"
|
input-type="date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
<b-wrapped-form-checkbox
|
<b-wrapped-form-checkbox
|
||||||
id="form_edit_fetch_isrc"
|
id="form_edit_fetch_isrc"
|
||||||
name="fetch_isrc"
|
name="fetch_isrc"
|
||||||
:field="v$.form.fetch_isrc"
|
:field="v$.fetch_isrc"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Attempt to Automatically Retrieve ISRC When Missing') }}
|
{{ $gettext('Attempt to Automatically Retrieve ISRC When Missing') }}
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<b-button
|
<b-button
|
||||||
type="submit"
|
type="submit"
|
||||||
size="lg"
|
size="lg"
|
||||||
:variant="(v$.form.$invalid) ? 'danger' : 'primary'"
|
:variant="(v$.$invalid) ? 'danger' : 'primary'"
|
||||||
class="mt-2"
|
class="mt-2"
|
||||||
>
|
>
|
||||||
{{ $gettext('Generate Report') }}
|
{{ $gettext('Generate Report') }}
|
||||||
|
@ -112,52 +112,38 @@
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import useVuelidate from "@vuelidate/core";
|
|
||||||
import {required} from '@vuelidate/validators';
|
import {required} from '@vuelidate/validators';
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||||
import BFormFieldset from "~/components/Form/BFormFieldset";
|
import BFormFieldset from "~/components/Form/BFormFieldset";
|
||||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
||||||
|
import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
apiUrl: {
|
||||||
export default {
|
type: String,
|
||||||
name: 'StationsReportsSoundExchange',
|
required: true
|
||||||
components: {BWrappedFormGroup, BFormFieldset, BWrappedFormCheckbox},
|
|
||||||
props: {
|
|
||||||
apiUrl: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
startDate: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
endDate: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setup() {
|
startDate: {
|
||||||
return {v$: useVuelidate()}
|
type: String,
|
||||||
|
required: true
|
||||||
},
|
},
|
||||||
validations() {
|
endDate: {
|
||||||
return {
|
type: String,
|
||||||
form: {
|
required: true
|
||||||
start_date: {required},
|
|
||||||
end_date: {required},
|
|
||||||
fetch_isrc: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
form: {
|
|
||||||
start_date: this.startDate,
|
|
||||||
end_date: this.endDate,
|
|
||||||
fetch_isrc: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
const {v$} = useVuelidateOnForm(
|
||||||
|
{
|
||||||
|
start_date: {required},
|
||||||
|
end_date: {required},
|
||||||
|
fetch_isrc: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
start_date: props.startDate,
|
||||||
|
end_date: props.endDate,
|
||||||
|
fetch_isrc: false
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline-light"
|
variant="outline-light"
|
||||||
class="py-2 pr-0"
|
class="py-2 pr-0"
|
||||||
@click.prevent="$emit('remove')"
|
@click.prevent="doRemove()"
|
||||||
>
|
>
|
||||||
<icon icon="remove" />
|
<icon icon="remove" />
|
||||||
{{ $gettext('Remove') }}
|
{{ $gettext('Remove') }}
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_start_time_'+index"
|
:id="'edit_form_start_time_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.start_time"
|
:field="v$.start_time"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Start Time') }}
|
{{ $gettext('Start Time') }}
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_end_time_'+index"
|
:id="'edit_form_end_time_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.end_time"
|
:field="v$.end_time"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('End Time') }}
|
{{ $gettext('End Time') }}
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_start_date_'+index"
|
:id="'edit_form_start_date_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.start_date"
|
:field="v$.start_date"
|
||||||
input-type="date"
|
input-type="date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_end_date_'+index"
|
:id="'edit_form_end_date_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.end_date"
|
:field="v$.end_date"
|
||||||
input-type="date"
|
input-type="date"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
<b-wrapped-form-group
|
<b-wrapped-form-group
|
||||||
:id="'edit_form_days_'+index"
|
:id="'edit_form_days_'+index"
|
||||||
class="col-md-4"
|
class="col-md-4"
|
||||||
:field="v$.row.days"
|
:field="v$.days"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Scheduled Play Days of Week') }}
|
{{ $gettext('Scheduled Play Days of Week') }}
|
||||||
|
@ -128,57 +128,56 @@
|
||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import PlaylistTime from '~/components/Common/TimeCode';
|
import PlaylistTime from '~/components/Common/TimeCode';
|
||||||
import Icon from "~/components/Common/Icon.vue";
|
import Icon from "~/components/Common/Icon.vue";
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup.vue";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup.vue";
|
||||||
import {required} from "@vuelidate/validators";
|
import {required} from "@vuelidate/validators";
|
||||||
import useVuelidate from "@vuelidate/core";
|
import useVuelidate from "@vuelidate/core";
|
||||||
|
import {toRef} from "vue";
|
||||||
|
import {useTranslate} from "~/vendor/gettext";
|
||||||
|
|
||||||
/* TODO Options API */
|
const props = defineProps({
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
stationTimeZone: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(['remove']);
|
||||||
name: 'StreamersFormScheduleRow',
|
|
||||||
components: {BWrappedFormGroup, Icon, PlaylistTime},
|
const v$ = useVuelidate(
|
||||||
props: {
|
{
|
||||||
index: {
|
'start_time': {required},
|
||||||
type: Number,
|
'end_time': {required},
|
||||||
required: true
|
'start_date': {},
|
||||||
},
|
'end_date': {},
|
||||||
row: {
|
'days': {}
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
stationTimeZone: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
emits: ['remove'],
|
toRef(props, 'row')
|
||||||
setup() {
|
);
|
||||||
return {v$: useVuelidate()}
|
|
||||||
},
|
const {$gettext} = useTranslate();
|
||||||
validations: {
|
|
||||||
row: {
|
const dayOptions = [
|
||||||
'start_time': {required},
|
{value: 1, text: $gettext('Monday')},
|
||||||
'end_time': {required},
|
{value: 2, text: $gettext('Tuesday')},
|
||||||
'start_date': {},
|
{value: 3, text: $gettext('Wednesday')},
|
||||||
'end_date': {},
|
{value: 4, text: $gettext('Thursday')},
|
||||||
'days': {}
|
{value: 5, text: $gettext('Friday')},
|
||||||
}
|
{value: 6, text: $gettext('Saturday')},
|
||||||
},
|
{value: 7, text: $gettext('Sunday')}
|
||||||
data() {
|
];
|
||||||
return {
|
|
||||||
dayOptions: [
|
const doRemove = () => {
|
||||||
{value: 1, text: this.$gettext('Monday')},
|
emit('remove');
|
||||||
{value: 2, text: this.$gettext('Tuesday')},
|
};
|
||||||
{value: 3, text: this.$gettext('Wednesday')},
|
|
||||||
{value: 4, text: this.$gettext('Thursday')},
|
|
||||||
{value: 5, text: this.$gettext('Friday')},
|
|
||||||
{value: 6, text: this.$gettext('Saturday')},
|
|
||||||
{value: 7, text: this.$gettext('Sunday')}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue