Mass Composition-API-ification and Gettext clarification.

This commit is contained in:
Buster Neece 2022-12-26 00:50:50 -06:00
parent d2cb74095a
commit f46ff95928
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
56 changed files with 360 additions and 661 deletions

View File

@ -1,12 +0,0 @@
import {ref} from "vue";
import {cloneDeep} from "lodash";
export function useResettableForm(blankForm) {
const form = ref(cloneDeep(blankForm));
const resetForm = () => {
form.value = cloneDeep(blankForm);
}
return {form, resetForm};
}

View File

@ -1,14 +1,14 @@
import useVuelidate from "@vuelidate/core";
import {useResettableForm} from "~/components/Form/UseResettableForm";
import {useResettableRef} from "~/functions/useResettableRef";
export function useVuelidateOnForm(validations, blankForm, options = {}) {
const {form, resetForm: parentResetForm} = useResettableForm(blankForm);
const {record: form, reset} = useResettableRef(blankForm);
const v$ = useVuelidate(validations, form, options);
const resetForm = () => {
v$.value.$reset();
parentResetForm();
reset();
}
return {

View File

@ -18,7 +18,7 @@
<form id="recover-form" class="form vue-form" action="" method="post">
<input type="hidden" name="csrf" :value="csrf"/>
<b-wrapped-form-group id="password" name="password" label-class="mb-2" :field="v$.form.password"
<b-wrapped-form-group id="password" name="password" label-class="mb-2" :field="v$.password"
input-type="password">
<template #label>
<icon icon="vpn_key" class="mr-1"></icon>
@ -26,7 +26,7 @@
</template>
</b-wrapped-form-group>
<b-button type="submit" size="lg" block variant="primary" :disabled="v$.form.$invalid"
<b-button type="submit" size="lg" block variant="primary" :disabled="v$.$invalid"
class="mt-2">
{{ $gettext('Recover Account') }}
</b-button>
@ -36,36 +36,24 @@
</div>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import Icon from "~/components/Common/Icon";
import validatePassword from '~/functions/validatePassword.js';
import useVuelidate from "@vuelidate/core";
import {required} from '@vuelidate/validators';
import {useVuelidateOnForm} from "~/components/Form/useVuelidateOnForm";
export default {
name: 'SetupRegister',
components: {Icon, BWrappedFormGroup},
setup() {
return {v$: useVuelidate()}
const props = defineProps({
csrf: String,
error: String,
});
const {form, v$} = useVuelidateOnForm(
{
password: {required, validatePassword}
},
props: {
csrf: String,
error: String,
},
validations() {
return {
form: {
password: {required, validatePassword}
}
}
},
data() {
return {
form: {
password: null,
}
}
{
password: null,
}
}
)
</script>

View File

@ -60,7 +60,7 @@
</section>
</div>
<b-modal id="import_modal" ref="modal" :title="langModalTitle">
<b-modal id="import_modal" ref="modal" :title="$gettext('Import Results')">
<div>
<p class="card-text">{{ importResults.message }}</p>
@ -124,11 +124,6 @@ export default {
importResults: {},
};
},
computed: {
langModalTitle() {
return this.$gettext('Import Results');
}
},
methods: {
doSubmit() {
let formData = new FormData();

View File

@ -20,7 +20,7 @@
{{ $gettext('Select Custom Fallback File') }}
</template>
<flow-upload :target-url="apiUrl" :valid-mime-types="acceptMimeTypes"
<flow-upload :target-url="apiUrl" :valid-mime-types="['audio/*']"
@success="onFileSuccess"></flow-upload>
</b-form-group>
@ -50,32 +50,28 @@
</section>
</template>
<script>
<script setup>
import FlowUpload from '~/components/Common/FlowUpload';
import InfoCard from "~/components/Common/InfoCard";
import {ref} from "vue";
import {useAxios} from "~/vendor/axios";
export default {
name: 'StationsFallback',
components: {InfoCard, FlowUpload},
props: {
apiUrl: String,
recordHasFallback: Boolean
},
data() {
return {
hasFallback: this.recordHasFallback,
acceptMimeTypes: ['audio/*']
};
},
methods: {
onFileSuccess() {
this.hasFallback = true;
},
deleteFallback() {
this.axios.delete(this.apiUrl).then(() => {
this.hasFallback = false;
});
}
}
const props = defineProps({
apiUrl: String,
recordHasFallback: Boolean
});
const hasFallback = ref(props.recordHasFallback);
const onFileSuccess = () => {
hasFallback.value = true;
};
const {axios} = useAxios();
const deleteFallback = () => {
axios.delete(props.apiUrl).then(() => {
hasFallback.value = false;
});
}
</script>

View File

@ -47,21 +47,19 @@
</div>
</template>
<script>
<script setup>
import Icon from "~/components/Common/Icon";
import StreamingLogModal from "~/components/Common/StreamingLogModal";
import LogList from "~/components/Common/LogList";
import {ref} from "vue";
export default {
name: 'StationsHelp',
components: {LogList, StreamingLogModal, Icon},
props: {
logsUrl: String,
},
methods: {
viewLog(url) {
this.$refs.modal.show(url);
}
}
}
const props = defineProps({
logsUrl: String,
});
const modal = ref(); // BModal
const viewLog = (url) => {
modal.value?.show(url);
};
</script>

View File

@ -1,35 +1,44 @@
<template>
<modal-form ref="modal" :loading="loading" :title="langTitle" :error="error" :disable-save-button="v$.form.$invalid"
<modal-form ref="modal" :loading="loading" :title="langTitle" :error="error" :disable-save-button="v$.$invalid"
@submit="doSubmit" @hidden="clearContents">
<b-tabs content-class="mt-3" pills>
<form-basic-info :form="v$.form"></form-basic-info>
<form-basic-info :form="v$"></form-basic-info>
</b-tabs>
</modal-form>
</template>
<script>
import {required} from '@vuelidate/validators';
import BaseEditModal from '~/components/Common/BaseEditModal';
import FormBasicInfo from './Form/BasicInfo';
import mergeExisting from "~/functions/mergeExisting";
import useVuelidate from "@vuelidate/core";
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
export default {
name: 'EditModal',
emits: ['needs-restart'],
setup() {
return {v$: useVuelidate()}
},
mixins: [BaseEditModal],
components: {FormBasicInfo},
validations() {
return {
form: {
const {form, resetForm, v$} = useVuelidateOnForm(
{
name: {required},
format: {required},
bitrate: {required}
},
{
name: null,
format: 'aac',
bitrate: 128
}
};
);
return {
form,
resetForm,
v$
}
},
mixins: [BaseEditModal],
components: {FormBasicInfo},
computed: {
langTitle() {
return this.isEditMode
@ -38,13 +47,6 @@ export default {
}
},
methods: {
resetForm() {
this.form = {
name: null,
format: 'aac',
bitrate: 128
};
},
populateForm(d) {
this.record = d;
this.form = mergeExisting(this.form, d);

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle" active>
<b-tab :title="$gettext('Basic Info')" active>
<b-form-group>
<div class="form-row mb-3">
<b-wrapped-form-group class="col-md-12" id="edit_form_name" :field="form.name">
@ -46,39 +46,29 @@
</b-tab>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
import {map} from "lodash";
export default {
name: 'HlsStreamFormBasicInfo',
components: {BWrappedFormCheckbox, BWrappedFormGroup},
props: {
form: Object,
stationFrontendType: String
},
computed: {
langTabTitle() {
return this.$gettext('Basic Info');
},
formatOptions() {
return [
{
value: 'aac',
text: 'AAC'
}
];
},
bitrateOptions() {
let options = [];
[32, 48, 64, 96, 128, 192, 256, 320].forEach((val) => {
options.push({
value: val,
text: val
});
});
return options;
},
const props = defineProps({
form: Object,
stationFrontendType: String
});
const formatOptions = [
{
value: 'aac',
text: 'AAC'
}
};
];
const bitrateOptions = map(
[32, 48, 64, 96, 128, 192, 256, 320],
(val) => {
return {
value: val,
text: val
}
},
);
</script>

View File

@ -109,7 +109,7 @@
<template #cell(playlists)="row">
<template v-for="(playlist, index) in row.item.playlists">
<a class="btn-search" href="#" @click.prevent="filter('playlist:'+playlist.name)"
:title="langPlaylistSelect">{{ playlist.name }}</a>
:title="$gettext('View tracks in playlist')">{{ playlist.name }}</a>
<span v-if="index+1 < row.item.playlists.length">, </span>
</template>
</template>
@ -117,12 +117,12 @@
<template v-if="row.item.media.links.edit">
<b-button size="sm" variant="primary"
@click.prevent="edit(row.item.media.links.edit, row.item.media.links.art, row.item.media.links.play, row.item.media.links.waveform)">
{{ langEditButton }}
{{ $gettext('Edit') }}
</b-button>
</template>
<template v-else>
<b-button size="sm" variant="primary" @click.prevent="rename(row.item.path)">
{{ langRenameButton }}
{{ $gettext('Rename') }}
</b-button>
</template>
</template>
@ -304,20 +304,6 @@ export default {
unmounted() {
window.removeEventListener('hashchange', this.onHashChange);
},
computed: {
langAlbumArt() {
return this.$gettext('Album Art');
},
langRenameButton() {
return this.$gettext('Rename');
},
langEditButton() {
return this.$gettext('Edit');
},
langPlaylistSelect() {
return this.$gettext('View tracks in playlist');
},
},
methods: {
formatFileSize(size) {
return formatFileSize(size);

View File

@ -80,15 +80,11 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'MediaFormAdvancedSettings',
components: {BWrappedFormGroup},
props: {
form: Object,
songLength: String
},
};
const props = defineProps({
form: Object,
songLength: String
});
</script>

View File

@ -52,14 +52,10 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'MediaFormBasicInfo',
components: {BWrappedFormGroup},
props: {
form: Object
}
};
const props = defineProps({
form: Object
});
</script>

View File

@ -10,15 +10,11 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'MediaFormCustomFields',
components: {BWrappedFormGroup},
props: {
form: Object,
customFields: Array
},
};
const props = defineProps({
form: Object,
customFields: Array
});
</script>

View File

@ -18,26 +18,22 @@
</b-form-group>
</template>
<script>
import _ from 'lodash';
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import {map} from "lodash";
import {computed} from "vue";
export default {
name: 'MediaFormPlaylists',
components: {BWrappedFormGroup},
props: {
form: Object,
playlists: Array
},
computed: {
options() {
return _.map(this.playlists, function (row) {
return {
text: row.name,
value: row.id
};
});
}
}
};
const props = defineProps({
form: Object,
playlists: Array
});
const options = computed(() => {
return map(props.playlists, function (row) {
return {
text: row.name,
value: row.id
};
});
});
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-modal id="create_directory" centered ref="modal" :title="langNewDirectory">
<b-modal id="create_directory" centered ref="modal" :title="$gettext('New Directory')">
<b-form @submit.prevent="doMkdir">
<b-wrapped-form-group id="new_directory_name" :field="v$.newDirectory" autofocus>
<template #label>
@ -42,11 +42,6 @@ export default {
required
}
},
computed: {
langNewDirectory () {
return this.$gettext('New Directory');
}
},
methods: {
close() {
this.newDirectory = null;

View File

@ -1,5 +1,5 @@
<template>
<b-modal id="rename_file" centered ref="modal" :title="langRenameFile">
<b-modal id="rename_file" centered ref="modal" :title="$gettext('Rename File/Directory')">
<b-form @submit.prevent="doRename">
<b-wrapped-form-group id="new_directory_name" :field="v$.form.newPath" autofocus>
<template #label>
@ -46,11 +46,6 @@ export default {
}
}
},
computed: {
langRenameFile () {
return this.$gettext('Rename File/Directory');
}
},
methods: {
open(filePath) {
this.form.file = filePath;

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('Advanced')">
<b-form-group>
<div class="form-row mb-3">
<b-wrapped-form-group class="col-md-12" id="edit_form_custom_listen_url"
@ -44,9 +44,6 @@ export default {
stationFrontendType: String
},
computed: {
langTabTitle() {
return this.$gettext('Advanced');
},
isIcecast() {
return FRONTEND_ICECAST === this.stationFrontendType;
}

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('AutoDJ')">
<b-form-group>
<div class="form-row mb-3">
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_autodj" :field="form.enable_autodj">
@ -60,9 +60,6 @@ export default {
stationFrontendType: String
},
computed: {
langTabTitle() {
return this.$gettext('AutoDJ');
},
formatOptions() {
return [
{

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle" active>
<b-tab :title="$gettext('Basic Info')" active>
<b-form-group>
<div class="form-row mb-3">
<b-wrapped-form-group class="col-md-6" id="edit_form_name" :field="form.name">
@ -120,9 +120,6 @@ export default {
stationFrontendType: String
},
computed: {
langTabTitle() {
return this.$gettext('Basic Info');
},
langAuthhashDesc() {
let text = 'If your stream is set to advertise to YP directories above, you must specify an authorization hash. You can manage authhashes <a href="%{ url }" target="_blank">on the Shoutcast web site</a>.';
let url = 'https://radiomanager.shoutcast.com/';

View File

@ -16,7 +16,7 @@
</b-row>
</b-card-header>
<b-tabs pills card lazy>
<b-tab :title="langAllPlaylistsTab" no-body>
<b-tab :title="$gettext('All Playlists')" no-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
@ -35,28 +35,28 @@
{{ $gettext('Delete') }}
</b-button>
<b-dropdown size="sm" variant="dark" boundary="window" :text="langMore">
<b-dropdown size="sm" variant="dark" boundary="window" :text="$gettext('More')">
<b-dropdown-item @click.prevent="doModify(row.item.links.toggle)">
{{ langToggleButton(row.item) }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doImport(row.item.links.import)"
v-if="row.item.source === 'songs'">
{{ langImportButton }}
{{ $gettext('Import from PLS/M3U') }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doReorder(row.item.links.order)"
v-if="row.item.source === 'songs' && row.item.order === 'sequential'">
{{ langReorderButton }}
{{ $gettext('Reorder') }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doQueue(row.item.links.queue)"
v-if="row.item.source === 'songs' && row.item.order !== 'random'">
{{ langQueueButton }}
{{ $gettext('Playback Queue') }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doModify(row.item.links.reshuffle)"
v-if="row.item.order === 'shuffle'">
{{ langReshuffleButton }}
{{ $gettext('Reshuffle') }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doClone(row.item.name, row.item.links.clone)">
{{ langCloneButton }}
{{ $gettext('Duplicate') }}
</b-dropdown-item>
<template v-for="format in ['pls', 'm3u']">
<b-dropdown-item :href="row.item.links.export[format]" target="_blank">
@ -114,7 +114,7 @@
</template>
</data-table>
</b-tab>
<b-tab :title="langScheduleViewTab" no-body>
<b-tab :title="$gettext('Schedule View')" no-body>
<schedule ref="schedule" :schedule-url="scheduleUrl" :station-time-zone="stationTimeZone"
@click="doCalendarClick"></schedule>
</b-tab>
@ -166,32 +166,6 @@ export default {
]
};
},
computed: {
langAllPlaylistsTab () {
return this.$gettext('All Playlists');
},
langScheduleViewTab () {
return this.$gettext('Schedule View');
},
langMore () {
return this.$gettext('More');
},
langReorderButton () {
return this.$gettext('Reorder');
},
langQueueButton () {
return this.$gettext('Playback Queue');
},
langReshuffleButton () {
return this.$gettext('Reshuffle');
},
langCloneButton () {
return this.$gettext('Duplicate');
},
langImportButton () {
return this.$gettext('Import from PLS/M3U');
}
},
methods: {
langToggleButton (record) {
return (record.is_enabled)

View File

@ -1,5 +1,5 @@
<template>
<modal-form ref="modal" id="clone_modal" :title="langTitle" :error="error"
<modal-form ref="modal" id="clone_modal" :title="$gettext('Duplicate Playlist')" :error="error"
:disable-save-button="v$.form.$invalid" @submit="doSubmit" @hidden="clearContents">
<div class="form-row">
@ -50,11 +50,6 @@ export default {
form: {}
};
},
computed: {
langTitle() {
return this.$gettext('Duplicate Playlist');
}
},
validations: {
form: {
'name': { required },

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('Advanced')">
<b-form-group>
<div class="form-row">
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_options" :field="form.backend_options">
@ -28,19 +28,10 @@
</b-tab>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'PlaylistEditAdvanced',
components: {BWrappedFormGroup},
props: {
form: Object
},
computed: {
langTabTitle() {
return this.$gettext('Advanced');
}
}
};
const props = defineProps({
form: Object
});
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle" active>
<b-tab :title="$gettext('Basic Info')" active>
<b-form-group>
<div class="form-row">
<b-wrapped-form-group class="col-md-6" id="form_edit_name" :field="form.name">
@ -343,11 +343,6 @@ export default {
return {
weightOptions: weightOptions
};
},
computed: {
langTabTitle() {
return this.$gettext('Basic Info');
}
}
};
</script>

View File

@ -1,11 +1,13 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('Schedule')">
<b-form-group v-if="scheduleItems.length === 0">
<label>
{{ $gettext('Not Scheduled') }}
</label>
<p>
{{ $gettext('This playlist currently has no scheduled times. It will play at all times. To add a new scheduled time, click the button below.') }}
{{
$gettext('This playlist currently has no scheduled times. It will play at all times. To add a new scheduled time, click the button below.')
}}
</p>
</b-form-group>
@ -37,11 +39,6 @@ export default {
stationTimeZone: String,
scheduleItems: Array
},
computed: {
langTabTitle() {
return this.$gettext('Schedule');
}
},
methods: {
add () {
this.scheduleItems.push({

View File

@ -1,5 +1,5 @@
<template>
<b-modal id="import_modal" ref="modal" :title="langTitle" @hidden="onHidden">
<b-modal id="import_modal" ref="modal" :title="$gettext('Import from PLS/M3U')" @hidden="onHidden">
<div v-if="results">
<p class="card-text">{{ results.message }}</p>
@ -65,11 +65,6 @@ export default {
results: null,
};
},
computed: {
langTitle () {
return this.$gettext('Import from PLS/M3U');
}
},
methods: {
open (importPlaylistUrl) {
this.playlistFile = null;

View File

@ -1,5 +1,5 @@
<template>
<b-modal size="lg" id="queue_modal" ref="modal" :title="langTitle" :busy="loading">
<b-modal size="lg" id="queue_modal" ref="modal" :title="$gettext('Playback Queue')" :busy="loading">
<p>
{{
$gettext('This queue contains the remaining tracks in the order they will be queued by the AzuraCast AutoDJ (if the tracks are eligible to be played).')
@ -45,11 +45,6 @@ export default {
media: []
};
},
computed: {
langTitle () {
return this.$gettext('Playback Queue');
}
},
methods: {
open (queueUrl) {
this.$refs.modal.show();

View File

@ -1,5 +1,5 @@
<template>
<b-modal size="lg" id="reorder_modal" ref="modal" :title="langTitle" :busy="loading" hide-footer>
<b-modal size="lg" id="reorder_modal" ref="modal" :title="$gettext('Reorder Playlist')" :busy="loading" hide-footer>
<b-overlay variant="card" :show="loading">
<div style="min-height: 40px;" class="flex-fill text-left bg-primary rounded mb-2">
<inline-player ref="player"></inline-player>
@ -27,11 +27,12 @@
<td>
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="moveDown(index)"
:title="langDownBtn"
:title="$gettext('Down')"
v-if="index+1 < media.length">
<icon icon="arrow_downward"></icon>
</b-button>
<b-button size="sm" variant="primary" @click.prevent="moveUp(index)" :title="langUpBtn"
<b-button size="sm" variant="primary" @click.prevent="moveUp(index)"
:title="$gettext('Up')"
v-if="index > 0">
<icon icon="arrow_upward"></icon>
</b-button>
@ -71,17 +72,6 @@ export default {
media: []
};
},
computed: {
langTitle () {
return this.$gettext('Reorder Playlist');
},
langDownBtn () {
return this.$gettext('Down');
},
langUpBtn () {
return this.$gettext('Up');
}
},
methods: {
open (reorderUrl) {
this.$refs.modal.show();

View File

@ -4,26 +4,23 @@
<list-view v-else v-bind="$props" @select-podcast="onSelectPodcast"></list-view>
</template>
<script>
<script setup>
import EpisodesView, {episodeViewProps} from './Podcasts/EpisodesView';
import ListView, {listViewProps} from './Podcasts/ListView';
import {ref} from "vue";
export default {
name: 'StationPodcasts',
components: {ListView, EpisodesView},
mixins: [episodeViewProps, listViewProps],
data() {
return {
activePodcast: null
};
},
methods: {
onSelectPodcast (podcast) {
this.activePodcast = podcast;
},
onClearPodcast () {
this.activePodcast = null;
}
}
const props = defineProps({
...episodeViewProps.props,
...listViewProps.props
});
const activePodcast = ref(null);
const onSelectPodcast = (podcast) => {
activePodcast.value = podcast;
};
const onClearPodcast = () => {
activePodcast.value = null;
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTitle" active>
<b-tab :title="$gettext('Basic Information')" active>
<b-form-group>
<div class="form-row">
@ -73,21 +73,12 @@
</b-tab>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
export default {
name: 'EpisodeFormBasicInfo',
components: {BWrappedFormCheckbox, BWrappedFormGroup},
props: {
form: Object,
locale: String
},
computed: {
langTitle() {
return this.$gettext('Basic Information');
}
}
};
const props = defineProps({
form: Object,
locale: String
});
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTitle" active>
<b-tab :title="$gettext('Basic Information')" active>
<b-form-group>
<div class="form-row">
@ -83,21 +83,12 @@
</b-tab>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'PodcastFormBasicInfo',
components: {BWrappedFormGroup},
props: {
form: Object,
languageOptions: Object,
categoriesOptions: Object
},
computed: {
langTitle() {
return this.$gettext('Basic Information');
}
}
};
const props = defineProps({
form: Object,
languageOptions: Object,
categoriesOptions: Object
});
</script>

View File

@ -11,27 +11,26 @@
</section>
</template>
<script>
<script setup>
import AdminStationsForm, {stationFormProps} from "~/components/Admin/Stations/StationForm";
import {onMounted, ref} from "vue";
export default {
name: 'StationsProfileEdit',
components: {AdminStationsForm},
props: {
...stationFormProps,
editUrl: String,
continueUrl: {
type: String,
required: true
}
},
mounted() {
this.$refs.form.reset();
},
methods: {
onSubmitted() {
window.location.href = this.continueUrl;
},
const props = defineProps({
...stationFormProps,
editUrl: String,
continueUrl: {
type: String,
required: true
}
});
const form = ref(); // AdminStationsForm
onMounted(() => {
form.value?.reset();
});
const onSubmitted = () => {
window.location.href = props.continueUrl;
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('AutoDJ')">
<div class="form-row mb-3">
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_autodj" :field="form.enable_autodj">
<template #label>
@ -102,9 +102,6 @@ export default {
stationFrontendType: String
},
computed: {
langTabTitle() {
return this.$gettext('AutoDJ');
},
formatOptions() {
return [
{

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle" active>
<b-tab :title="$gettext('Basic Info')" active>
<b-form-group>
<div class="form-row">
<b-wrapped-form-group class="col-md-12" id="edit_form_type" :field="form.type">
@ -90,9 +90,6 @@ export default {
form: Object
},
computed: {
langTabTitle() {
return this.$gettext('Basic Info');
},
typeOptions() {
return [
{

View File

@ -23,8 +23,10 @@
</div>
</div>
<b-tabs pills card>
<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-tab key="live" active @click="setIsLive(true)" :title="$gettext('Live Listeners')"
no-body></b-tab>
<b-tab key="not-live" @click="setIsLive(false)" :title="$gettext('Listener History')"
no-body></b-tab>
</b-tabs>
<div id="map">
<StationReportsListenersMap :listeners="listeners"></StationReportsListenersMap>
@ -154,12 +156,6 @@ export default {
};
},
computed: {
langLiveListeners() {
return this.$gettext('Live Listeners');
},
langListenerHistory() {
return this.$gettext('Listener History');
},
nowTz() {
return DateTime.now().setZone(this.stationTimeZone);
},

View File

@ -1,6 +1,6 @@
<template>
<common-metrics-view :date-range="dateRange" :api-url="apiUrl"
field-key="browser" :field-label="langFieldLabel">
field-key="browser" :field-label="$gettext('Browser')">
<template #by_listeners_legend>
{{ $gettext('Top Browsers by Listeners') }}
</template>
@ -10,20 +10,11 @@
</common-metrics-view>
</template>
<script>
<script setup>
import CommonMetricsView from "./CommonMetricsView";
export default {
name: 'BrowsersTab',
components: {CommonMetricsView},
props: {
dateRange: Object,
apiUrl: String,
},
computed: {
langFieldLabel() {
return this.$gettext('Browser');
}
}
}
const props = defineProps({
dateRange: Object,
apiUrl: String,
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<common-metrics-view :date-range="dateRange" :api-url="apiUrl"
field-key="client" :field-label="langFieldLabel">
field-key="client" :field-label="$gettext('Client')">
<template #by_listeners_legend>
{{ $gettext('Clients by Listeners') }}
</template>
@ -10,20 +10,11 @@
</common-metrics-view>
</template>
<script>
<script setup>
import CommonMetricsView from "./CommonMetricsView";
export default {
name: 'ClientsTab',
components: {CommonMetricsView},
props: {
dateRange: Object,
apiUrl: String,
},
computed: {
langFieldLabel() {
return this.$gettext('Client');
}
}
}
const props = defineProps({
dateRange: Object,
apiUrl: String,
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<common-metrics-view :date-range="dateRange" :api-url="apiUrl"
field-key="country" :field-label="langFieldLabel">
field-key="country" :field-label="$gettext('Country')">
<template #by_listeners_legend>
{{ $gettext('Top Countries by Listeners') }}
</template>
@ -10,20 +10,11 @@
</common-metrics-view>
</template>
<script>
<script setup>
import CommonMetricsView from "./CommonMetricsView";
export default {
name: 'CountriesTab',
components: {CommonMetricsView},
props: {
dateRange: Object,
apiUrl: String,
},
computed: {
langFieldLabel() {
return this.$gettext('Country');
}
}
}
const props = defineProps({
dateRange: Object,
apiUrl: String,
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<common-metrics-view :date-range="dateRange" :api-url="apiUrl"
field-key="stream" :field-label="langFieldLabel">
field-key="stream" :field-label="$gettext('Stream')">
<template #by_listeners_legend>
{{ $gettext('Top Streams by Listeners') }}
</template>
@ -10,20 +10,11 @@
</common-metrics-view>
</template>
<script>
<script setup>
import CommonMetricsView from "./CommonMetricsView";
export default {
name: 'StreamsTab',
components: {CommonMetricsView},
props: {
dateRange: Object,
apiUrl: String,
},
computed: {
langFieldLabel() {
return this.$gettext('Stream');
}
}
}
const props = defineProps({
dateRange: Object,
apiUrl: String,
});
</script>

View File

@ -37,15 +37,11 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'SftpUsersForm',
components: {BWrappedFormGroup},
props: {
form: Object,
isEditMode: Boolean
},
};
const props = defineProps({
form: Object,
isEditMode: Boolean
});
</script>

View File

@ -19,7 +19,7 @@
</b-card-header>
<b-tabs pills card lazy>
<b-tab :title="langAccountListTab" no-body>
<b-tab :title="$gettext('Account List')" no-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
@ -56,7 +56,7 @@
</template>
</data-table>
</b-tab>
<b-tab :title="langScheduleViewTab" no-body>
<b-tab :title="$gettext('Schedule View')" no-body>
<schedule ref="schedule" :schedule-url="scheduleUrl" :station-time-zone="stationTimeZone"
@click="doCalendarClick"></schedule>
</b-tab>
@ -103,14 +103,6 @@ export default {
]
};
},
computed: {
langAccountListTab() {
return this.$gettext('Account List');
},
langScheduleViewTab() {
return this.$gettext('Schedule View');
}
},
methods: {
relist() {
this.$refs.datatable.refresh();

View File

@ -1,5 +1,5 @@
<template>
<b-modal id="streamer_broadcasts" size="lg" centered ref="modal" :title="langHeader">
<b-modal id="streamer_broadcasts" size="lg" centered ref="modal" :title="$gettext('Streamer Broadcasts')">
<template v-if="listUrl">
<div style="min-height: 40px;" class="flex-fill text-left bg-primary rounded mb-2">
<inline-player ref="player"></inline-player>
@ -13,7 +13,7 @@
:url="row.item.recording?.links?.download"></play-button>
&nbsp;
<a class="name" :href="row.item.recording?.links?.download" target="_blank"
:title="langDownload">
:title="$gettext('Download')">
<icon icon="cloud_download"></icon>
</a>
</template>
@ -108,17 +108,6 @@ export default {
]
};
},
computed: {
langHeader () {
return this.$gettext('Streamer Broadcasts');
},
langPlayPause () {
return this.$gettext('Play/Pause');
},
langDownload () {
return this.$gettext('Download');
}
},
methods: {
doDelete (url) {
this.$confirmDelete({

View File

@ -78,11 +78,9 @@
</div>
</div>
</template>
<script>
export default {
name: 'ConnectionInfo',
props: {
connectionInfo: Object
}
}
<script setup>
const props = defineProps({
connectionInfo: Object
});
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle" active>
<b-tab :title="$gettext('Basic Info')" active>
<b-form-group>
<div class="form-row">
@ -74,20 +74,11 @@
</b-tab>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
export default {
name: 'StreamerFormBasicInfo',
components: {BWrappedFormCheckbox, BWrappedFormGroup},
props: {
form: Object
},
computed: {
langTabTitle() {
return this.$gettext('Basic Info');
}
}
};
const props = defineProps({
form: Object
});
</script>

View File

@ -1,5 +1,5 @@
<template>
<b-tab :title="langTabTitle">
<b-tab :title="$gettext('Schedule')">
<b-form-group v-if="scheduleItems.length === 0">
<label>
{{ $gettext('Not Scheduled') }}
@ -50,11 +50,6 @@ export default {
]
};
},
computed: {
langTabTitle () {
return this.$gettext('Schedule');
}
},
methods: {
add () {
this.scheduleItems.push({

View File

@ -33,15 +33,11 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'BasicInfo',
components: {BWrappedFormGroup},
props: {
form: Object,
triggerOptions: Array
}
}
const props = defineProps({
form: Object,
triggerOptions: Array
});
</script>

View File

@ -19,11 +19,8 @@
</b-form-group>
</template>
<script>
export default {
name: 'CommonFormattingInfo',
props: {
nowPlayingUrl: String
}
}
<script setup>
const props = defineProps({
nowPlayingUrl: String
});
</script>

View File

@ -63,16 +63,12 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import CommonFormattingInfo from "./Common/FormattingInfo";
export default {
name: 'Discord',
components: {CommonFormattingInfo, BWrappedFormGroup},
props: {
form: Object,
nowPlayingUrl: String
}
}
const props = defineProps({
form: Object,
nowPlayingUrl: String
});
</script>

View File

@ -31,16 +31,12 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import CommonFormattingInfo from "./Common/FormattingInfo";
export default {
name: 'Email',
components: {CommonFormattingInfo, BWrappedFormGroup},
props: {
form: Object,
nowPlayingUrl: String
}
}
const props = defineProps({
form: Object,
nowPlayingUrl: String
});
</script>

View File

@ -76,14 +76,10 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'Generic',
components: {BWrappedFormGroup},
props: {
form: Object
}
}
const props = defineProps({
form: Object
});
</script>

View File

@ -13,14 +13,10 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'GoogleAnalytics',
components: {BWrappedFormGroup},
props: {
form: Object
}
}
const props = defineProps({
form: Object
});
</script>

View File

@ -70,41 +70,34 @@
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import RateLimitFields from "./Common/RateLimitFields";
import CommonRateLimitFields from "./Common/RateLimitFields";
import CommonSocialPostFields from "./Common/SocialPostFields";
import {computed} from "vue";
import {useTranslate} from "~/vendor/gettext";
export default {
name: 'Mastodon',
components: {
CommonRateLimitFields,
CommonSocialPostFields,
RateLimitFields,
BWrappedFormGroup
},
props: {
form: Object,
nowPlayingUrl: String
},
computed: {
visibilityOptions() {
return [
{
text: this.$gettext('Public'),
value: 'public',
},
{
text: this.$gettext('Unlisted'),
value: 'unlisted',
},
{
text: this.$gettext('Private'),
value: 'private',
}
];
const props = defineProps({
form: Object,
nowPlayingUrl: String
});
const {$gettext} = useTranslate();
const visibilityOptions = computed(() => {
return [
{
text: $gettext('Public'),
value: 'public',
},
{
text: $gettext('Unlisted'),
value: 'unlisted',
},
{
text: $gettext('Private'),
value: 'private',
}
}
}
];
});
</script>

View File

@ -32,14 +32,10 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'MatomoAnalytics',
components: {BWrappedFormGroup},
props: {
form: Object
}
}
const props = defineProps({
form: Object
});
</script>

View File

@ -64,30 +64,29 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import CommonFormattingInfo from "./Common/FormattingInfo";
import {computed} from "vue";
import {useTranslate} from "~/vendor/gettext";
export default {
name: 'Telegram',
components: {CommonFormattingInfo, BWrappedFormGroup},
props: {
form: Object,
nowPlayingUrl: String
},
computed: {
parseModeOptions() {
return [
{
text: this.$gettext('Markdown'),
value: 'Markdown',
},
{
text: this.$gettext('HTML'),
value: 'HTML',
}
];
const props = defineProps({
form: Object,
nowPlayingUrl: String
});
const {$gettext} = useTranslate();
const parseModeOptions = computed(() => {
return [
{
text: $gettext('Markdown'),
value: 'Markdown',
},
{
text: $gettext('HTML'),
value: 'HTML',
}
}
}
];
});
</script>

View File

@ -25,14 +25,10 @@
</b-form-group>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
export default {
name: 'Tunein',
components: {BWrappedFormGroup},
props: {
form: Object
}
}
const props = defineProps({
form: Object
});
</script>

View File

@ -65,17 +65,13 @@
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</template>
<script>
<script setup>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import CommonRateLimitFields from "./Common/RateLimitFields";
import CommonSocialPostFields from "./Common/SocialPostFields";
export default {
name: 'Twitter',
components: {CommonSocialPostFields, CommonRateLimitFields, BWrappedFormGroup},
props: {
form: Object,
nowPlayingUrl: String
}
}
const props = defineProps({
form: Object,
nowPlayingUrl: String
});
</script>

View File

@ -14,17 +14,14 @@
</b-form-group>
</template>
<script>
export default {
name: 'TypeSelect',
emits: ['select'],
props: {
webhookTypes: Object,
},
methods: {
selectType(type) {
this.$emit('select', type);
}
}
<script setup>
const props = defineProps({
webhookTypes: Object,
});
const emit = defineEmits(['select']);
const selectType = (type) => {
emit('select', type);
}
</script>

View File

@ -0,0 +1,12 @@
import {ref} from "vue";
import {cloneDeep} from "lodash";
export function useResettableRef(original) {
const record = ref(cloneDeep(original));
const reset = () => {
record.value = cloneDeep(original);
}
return {record, reset};
}