Compose common form components.
This commit is contained in:
parent
f75dfd2fcb
commit
4065c7dbd9
|
@ -107,7 +107,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import Icon from "~/components/Common/Icon";
|
||||
import DataTable from "~/components/Common/DataTable";
|
||||
import AdminBackupsLastOutputModal from "./Backups/LastOutputModal";
|
||||
|
@ -117,108 +117,121 @@ import AdminBackupsConfigureModal from "~/components/Admin/Backups/ConfigureModa
|
|||
import AdminBackupsRunBackupModal from "~/components/Admin/Backups/RunBackupModal";
|
||||
import EnabledBadge from "~/components/Common/Badges/EnabledBadge.vue";
|
||||
import {useAzuraCast} from "~/vendor/azuracast";
|
||||
import {onMounted, ref} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||
|
||||
export default {
|
||||
name: 'AdminBackups',
|
||||
components: {
|
||||
EnabledBadge,
|
||||
AdminBackupsRunBackupModal,
|
||||
AdminBackupsConfigureModal,
|
||||
AdminBackupsLastOutputModal,
|
||||
DataTable,
|
||||
Icon
|
||||
},
|
||||
props: {
|
||||
listUrl: String,
|
||||
settingsUrl: String,
|
||||
runBackupUrl: String,
|
||||
storageLocations: Object,
|
||||
isDocker: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fields: [
|
||||
{
|
||||
key: 'basename',
|
||||
isRowHeader: true,
|
||||
label: this.$gettext('File Name'),
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'timestamp',
|
||||
label: this.$gettext('Last Modified'),
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'size',
|
||||
label: this.$gettext('Size'),
|
||||
sortable: false
|
||||
},
|
||||
{key: 'actions', label: this.$gettext('Actions'), sortable: false, class: 'shrink'}
|
||||
],
|
||||
settingsLoading: false,
|
||||
settings: {
|
||||
backupEnabled: false,
|
||||
backupLastRun: null,
|
||||
backupLastOutput: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.relist();
|
||||
},
|
||||
methods: {
|
||||
relist() {
|
||||
this.settingsLoading = true;
|
||||
this.$wrapWithLoading(
|
||||
this.axios.get(this.settingsUrl)
|
||||
).then((resp) => {
|
||||
this.settings = {
|
||||
backupEnabled: resp.data.backup_enabled,
|
||||
backupLastRun: resp.data.backup_last_run,
|
||||
backupLastOutput: resp.data.backup_last_output
|
||||
};
|
||||
this.settingsLoading = false;
|
||||
});
|
||||
const props = defineProps({
|
||||
listUrl: String,
|
||||
settingsUrl: String,
|
||||
runBackupUrl: String,
|
||||
storageLocations: Object,
|
||||
isDocker: Boolean,
|
||||
});
|
||||
|
||||
this.$refs.datatable.relist();
|
||||
},
|
||||
toRelativeTime(timestamp) {
|
||||
return DateTime.fromSeconds(timestamp).toRelative();
|
||||
},
|
||||
toLocaleTime(timestamp) {
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const settingsLoading = ref(false);
|
||||
|
||||
return DateTime.fromSeconds(timestamp).toLocaleString(
|
||||
{...DateTime.DATETIME_SHORT, timeConfig}
|
||||
);
|
||||
},
|
||||
formatFileSize(size) {
|
||||
return formatFileSize(size);
|
||||
},
|
||||
showLastOutput() {
|
||||
this.$refs.lastOutputModal.show();
|
||||
},
|
||||
doConfigure() {
|
||||
this.$refs.configureModal.open();
|
||||
},
|
||||
doRunBackup() {
|
||||
this.$refs.runBackupModal.open();
|
||||
},
|
||||
doDelete(url) {
|
||||
this.$confirmDelete({
|
||||
title: this.$gettext('Delete Backup?')
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
this.$wrapWithLoading(
|
||||
this.axios.delete(url)
|
||||
).then((resp) => {
|
||||
this.$notifySuccess(resp.data.message);
|
||||
this.relist();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
const blankSettings = {
|
||||
backupEnabled: false,
|
||||
backupLastRun: null,
|
||||
backupLastOutput: '',
|
||||
};
|
||||
|
||||
const settings = ref({...blankSettings});
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
|
||||
const fields = [
|
||||
{
|
||||
key: 'basename',
|
||||
isRowHeader: true,
|
||||
label: $gettext('File Name'),
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'timestamp',
|
||||
label: $gettext('Last Modified'),
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'size',
|
||||
label: $gettext('Size'),
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
label: $gettext('Actions'),
|
||||
sortable: false,
|
||||
class: 'shrink'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const datatable = ref(); // Template Ref
|
||||
|
||||
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||
const {axios} = useAxios();
|
||||
|
||||
const relist = () => {
|
||||
settingsLoading.value = true;
|
||||
wrapWithLoading(
|
||||
axios.get(props.settingsUrl)
|
||||
).then((resp) => {
|
||||
settings.value = {
|
||||
backupEnabled: resp.data.backup_enabled,
|
||||
backupLastRun: resp.data.backup_last_run,
|
||||
backupLastOutput: resp.data.backup_last_output
|
||||
};
|
||||
settingsLoading.value = false;
|
||||
});
|
||||
|
||||
datatable.value.relist();
|
||||
};
|
||||
|
||||
onMounted(relist);
|
||||
|
||||
const toRelativeTime = (timestamp) => {
|
||||
return DateTime.fromSeconds(timestamp).toRelative();
|
||||
};
|
||||
|
||||
const toLocaleTime = (timestamp) => {
|
||||
const {timeConfig} = useAzuraCast();
|
||||
|
||||
return DateTime.fromSeconds(timestamp).toLocaleString(
|
||||
{...DateTime.DATETIME_SHORT, timeConfig}
|
||||
);
|
||||
};
|
||||
|
||||
const lastOutputModal = ref(); // Template Ref
|
||||
const showLastOutput = () => {
|
||||
lastOutputModal.value.show();
|
||||
};
|
||||
|
||||
const configureModal = ref(); // Template Ref
|
||||
const doConfigure = () => {
|
||||
configureModal.value.open();
|
||||
};
|
||||
|
||||
const runBackupModal = ref(); // Template Ref
|
||||
const doRunBackup = () => {
|
||||
runBackupModal.value.open();
|
||||
};
|
||||
|
||||
const {confirmDelete} = useSweetAlert();
|
||||
|
||||
const doDelete = (url) => {
|
||||
confirmDelete({
|
||||
title: $gettext('Delete Backup?')
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
wrapWithLoading(
|
||||
axios.delete(url)
|
||||
).then((resp) => {
|
||||
notifySuccess(resp.data.message);
|
||||
relist();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import BFormFieldset from "~/components/Form/BFormFieldset";
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import InvisibleSubmitButton from "~/components/Common/InvisibleSubmitButton";
|
||||
|
@ -90,6 +89,7 @@ import StreamingLogView from "~/components/Common/StreamingLogView";
|
|||
import {computed, ref} from "vue";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
runBackupUrl: String,
|
||||
|
@ -106,21 +106,18 @@ const logUrl = ref(null);
|
|||
const error = ref(null);
|
||||
const modal = ref(); // BModal
|
||||
|
||||
const blankForm = {
|
||||
storage_location: null,
|
||||
path: '',
|
||||
exclude_media: false,
|
||||
};
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const validations = {
|
||||
'storage_location': {},
|
||||
'path': {},
|
||||
'exclude_media': {}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
'storage_location': {},
|
||||
'path': {},
|
||||
'exclude_media': {}
|
||||
},
|
||||
{
|
||||
storage_location: null,
|
||||
path: '',
|
||||
exclude_media: false,
|
||||
}
|
||||
);
|
||||
|
||||
const open = () => {
|
||||
modal.value.show();
|
||||
|
@ -158,7 +155,7 @@ const clearContents = () => {
|
|||
logUrl.value = null;
|
||||
error.value = null;
|
||||
|
||||
form.value = {...blankForm};
|
||||
resetForm();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
<div class="card-body">
|
||||
<ul class="list-unstyled">
|
||||
<custom-asset-form id="asset_background" class="mb-3" :api-url="backgroundApiUrl"
|
||||
:caption="langBackground"></custom-asset-form>
|
||||
:caption="$gettext('Public Page Background')"></custom-asset-form>
|
||||
<custom-asset-form id="asset_album_art" class="mb-3" :api-url="albumArtApiUrl"
|
||||
:caption="langAlbumArt"></custom-asset-form>
|
||||
:caption="$gettext('Default Album Art')"></custom-asset-form>
|
||||
<custom-asset-form id="asset_browser_icon" :api-url="browserIconApiUrl"
|
||||
:caption="langBrowserIcon"></custom-asset-form>
|
||||
:caption="$gettext('Browser Icon')"></custom-asset-form>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -26,29 +26,15 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import CustomAssetForm from "./Branding/CustomAssetForm";
|
||||
import BrandingForm from "./Branding/BrandingForm";
|
||||
|
||||
export default {
|
||||
name: 'Branding',
|
||||
components: {BrandingForm, CustomAssetForm},
|
||||
props: {
|
||||
settingsApiUrl: String,
|
||||
browserIconApiUrl: String,
|
||||
backgroundApiUrl: String,
|
||||
albumArtApiUrl: String
|
||||
},
|
||||
computed: {
|
||||
langBrowserIcon() {
|
||||
return this.$gettext('Browser Icon');
|
||||
},
|
||||
langBackground() {
|
||||
return this.$gettext('Public Page Background');
|
||||
},
|
||||
langAlbumArt() {
|
||||
return this.$gettext('Default Album Art');
|
||||
}
|
||||
}
|
||||
};
|
||||
const props = defineProps({
|
||||
settingsApiUrl: String,
|
||||
browserIconApiUrl: String,
|
||||
backgroundApiUrl: String,
|
||||
albumArtApiUrl: String
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -140,7 +140,6 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import CodemirrorTextarea from "~/components/Common/CodemirrorTextarea";
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
||||
|
@ -149,6 +148,7 @@ import {useAxios} from "~/vendor/axios";
|
|||
import mergeExisting from "~/functions/mergeExisting";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
apiUrl: String,
|
||||
|
@ -157,31 +157,28 @@ const props = defineProps({
|
|||
const loading = ref(true);
|
||||
const error = ref(null);
|
||||
|
||||
const blankForm = {
|
||||
'public_theme': '',
|
||||
'hide_album_art': false,
|
||||
'homepage_redirect_url': '',
|
||||
'default_album_art_url': '',
|
||||
'hide_product_name': false,
|
||||
'public_custom_css': '',
|
||||
'public_custom_js': '',
|
||||
'internal_custom_css': ''
|
||||
};
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const validations = {
|
||||
'public_theme': {},
|
||||
'hide_album_art': {},
|
||||
'homepage_redirect_url': {},
|
||||
'default_album_art_url': {},
|
||||
'hide_product_name': {},
|
||||
'public_custom_css': {},
|
||||
'public_custom_js': {},
|
||||
'internal_custom_css': {}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
'public_theme': {},
|
||||
'hide_album_art': {},
|
||||
'homepage_redirect_url': {},
|
||||
'default_album_art_url': {},
|
||||
'hide_product_name': {},
|
||||
'public_custom_css': {},
|
||||
'public_custom_js': {},
|
||||
'internal_custom_css': {}
|
||||
},
|
||||
{
|
||||
'public_theme': '',
|
||||
'hide_album_art': false,
|
||||
'homepage_redirect_url': '',
|
||||
'default_album_art_url': '',
|
||||
'hide_product_name': false,
|
||||
'public_custom_css': '',
|
||||
'public_custom_js': '',
|
||||
'internal_custom_css': ''
|
||||
}
|
||||
);
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
|
||||
|
@ -209,8 +206,8 @@ const populateForm = (data) => {
|
|||
};
|
||||
|
||||
const relist = () => {
|
||||
v$.value.$reset();
|
||||
form.value = {...blankForm};
|
||||
resetForm();
|
||||
|
||||
loading.value = true;
|
||||
|
||||
axios.get(props.apiUrl).then((resp) => {
|
||||
|
|
|
@ -39,60 +39,71 @@
|
|||
</data-table>
|
||||
</b-card>
|
||||
|
||||
<edit-modal ref="editModal" :create-url="listUrl" :auto-assign-types="autoAssignTypes"
|
||||
<edit-modal ref="editmodal" :create-url="listUrl" :auto-assign-types="autoAssignTypes"
|
||||
@relist="relist"></edit-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import DataTable from '~/components/Common/DataTable';
|
||||
import EditModal from './CustomFields/EditModal';
|
||||
import Icon from '~/components/Common/Icon';
|
||||
import InfoCard from '~/components/Common/InfoCard';
|
||||
import _ from 'lodash';
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {ref} from "vue";
|
||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
|
||||
export default {
|
||||
name: 'AdminCustomFields',
|
||||
components: {InfoCard, Icon, EditModal, DataTable},
|
||||
props: {
|
||||
listUrl: String,
|
||||
autoAssignTypes: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fields: [
|
||||
{key: 'name', isRowHeader: true, label: this.$gettext('Field Name'), sortable: false},
|
||||
{key: 'auto_assign', label: this.$gettext('Auto-Assign Value'), sortable: false},
|
||||
{key: 'actions', label: this.$gettext('Actions'), sortable: false, class: 'shrink'}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getAutoAssignName(autoAssign) {
|
||||
return _.get(this.autoAssignTypes, autoAssign, this.$gettext('None'));
|
||||
},
|
||||
relist() {
|
||||
this.$refs.datatable.refresh();
|
||||
},
|
||||
doCreate() {
|
||||
this.$refs.editModal.create();
|
||||
},
|
||||
doEdit(url) {
|
||||
this.$refs.editModal.edit(url);
|
||||
},
|
||||
doDelete(url) {
|
||||
this.$confirmDelete({
|
||||
title: this.$gettext('Delete Custom Field?')
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
this.$wrapWithLoading(
|
||||
this.axios.delete(url)
|
||||
).then((resp) => {
|
||||
this.$notifySuccess(resp.data.message);
|
||||
this.relist();
|
||||
});
|
||||
}
|
||||
const props = defineProps({
|
||||
listUrl: String,
|
||||
autoAssignTypes: Object
|
||||
});
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
|
||||
const fields = [
|
||||
{key: 'name', isRowHeader: true, label: $gettext('Field Name'), sortable: false},
|
||||
{key: 'auto_assign', label: $gettext('Auto-Assign Value'), sortable: false},
|
||||
{key: 'actions', label: $gettext('Actions'), sortable: false, class: 'shrink'}
|
||||
];
|
||||
|
||||
const getAutoAssignName = (autoAssign) => {
|
||||
return _.get(props.autoAssignTypes, autoAssign, $gettext('None'));
|
||||
};
|
||||
|
||||
const datatable = ref(); // Template Ref
|
||||
|
||||
const relist = () => {
|
||||
datatable.value.refresh();
|
||||
};
|
||||
|
||||
const editmodal = ref(); // Template Ref
|
||||
|
||||
const doCreate = () => {
|
||||
editmodal.value.create();
|
||||
}
|
||||
|
||||
const doEdit = (url) => {
|
||||
editmodal.value.edit(url);
|
||||
}
|
||||
|
||||
const {confirmDelete} = useSweetAlert();
|
||||
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||
const {axios} = useAxios();
|
||||
|
||||
const doDelete = (url) => {
|
||||
confirmDelete({
|
||||
title: $gettext('Delete Custom Field?')
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
wrapWithLoading(
|
||||
axios.delete(url)
|
||||
).then((resp) => {
|
||||
notifySuccess(resp.data.message);
|
||||
relist();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -9,38 +9,28 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {required} from '@vuelidate/validators';
|
||||
import BaseEditModal from '~/components/Common/BaseEditModal';
|
||||
import AdminCustomFieldsForm from "~/components/Admin/CustomFields/Form";
|
||||
import {ref} from "vue";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
export default {
|
||||
name: 'AdminCustomFieldsEditModal',
|
||||
mixins: [BaseEditModal],
|
||||
components: {AdminCustomFieldsForm},
|
||||
setup() {
|
||||
const blankForm = {
|
||||
'name': '',
|
||||
'short_name': '',
|
||||
'auto_assign': ''
|
||||
};
|
||||
|
||||
const form = ref({
|
||||
...blankForm
|
||||
});
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
}
|
||||
|
||||
const validations = {
|
||||
'name': {required},
|
||||
'short_name': {},
|
||||
'auto_assign': {}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
'name': {required},
|
||||
'short_name': {},
|
||||
'auto_assign': {}
|
||||
},
|
||||
{
|
||||
'name': '',
|
||||
'short_name': '',
|
||||
'auto_assign': ''
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
form,
|
||||
|
|
|
@ -44,21 +44,24 @@
|
|||
<script setup>
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import {computed} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
|
||||
const props = defineProps({
|
||||
form: Object,
|
||||
autoAssignTypes: Object
|
||||
});
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
|
||||
const autoAssignOptions = computed(() => {
|
||||
let autoAssignOptions = [
|
||||
{
|
||||
text: this.$gettext('Disable'),
|
||||
text: $gettext('Disable'),
|
||||
value: '',
|
||||
}
|
||||
];
|
||||
|
||||
_.forEach(this.autoAssignTypes, (typeName, typeKey) => {
|
||||
_.forEach(props.autoAssignTypes, (typeName, typeKey) => {
|
||||
autoAssignOptions.push({
|
||||
text: typeName,
|
||||
value: typeKey
|
||||
|
|
|
@ -86,22 +86,40 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import BFormFieldset from "~/components/Form/BFormFieldset";
|
||||
<script setup>
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import '~/vendor/sweetalert.js';
|
||||
import InfoCard from "~/components/Common/InfoCard";
|
||||
import {ref} from "vue";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
apiUrl: String
|
||||
});
|
||||
|
||||
const loading = ref(true);
|
||||
const version = ref(null);
|
||||
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
key: {}
|
||||
},
|
||||
{
|
||||
key: null
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
export default {
|
||||
name: 'GeoLite',
|
||||
components: {InfoCard, BWrappedFormGroup, BFormFieldset},
|
||||
setup() {
|
||||
return {v$: useVuelidate()}
|
||||
},
|
||||
props: {
|
||||
apiUrl: String
|
||||
},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
|
@ -109,9 +127,7 @@ export default {
|
|||
version: null
|
||||
};
|
||||
},
|
||||
validations: {
|
||||
key: {}
|
||||
},
|
||||
validations: {},
|
||||
computed: {
|
||||
langInstalledVersion() {
|
||||
const text = this.$gettext('GeoLite version "%{ version }" is currently installed.');
|
||||
|
|
|
@ -15,13 +15,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {required} from '@vuelidate/validators';
|
||||
import BaseEditModal from '~/components/Common/BaseEditModal';
|
||||
import AdminPermissionsGlobalForm from "./Form/GlobalForm";
|
||||
import AdminPermissionsStationForm from "./Form/StationForm";
|
||||
import _ from 'lodash';
|
||||
import {ref} from "vue";
|
||||
|
||||
export default {
|
||||
name: 'AdminPermissionsEditModal',
|
||||
|
@ -33,29 +31,22 @@ export default {
|
|||
stationPermissions: Object
|
||||
},
|
||||
setup() {
|
||||
const blankForm = {
|
||||
'name': '',
|
||||
'permissions': {
|
||||
'global': [],
|
||||
'station': [],
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
'name': {required},
|
||||
'permissions': {
|
||||
'global': {},
|
||||
'station': {},
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': '',
|
||||
'permissions': {
|
||||
'global': [],
|
||||
'station': [],
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const validations = {
|
||||
'name': {required},
|
||||
'permissions': {
|
||||
'global': {},
|
||||
'station': {},
|
||||
}
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
}
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
);
|
||||
|
||||
return {
|
||||
form,
|
||||
|
|
|
@ -63,11 +63,11 @@ import SettingsGeneralTab from "./Settings/GeneralTab";
|
|||
import SettingsServicesTab from "./Settings/ServicesTab";
|
||||
import SettingsSecurityPrivacyTab from "~/components/Admin/Settings/SecurityPrivacyTab";
|
||||
import {onMounted, ref} from "vue";
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import mergeExisting from "~/functions/mergeExisting";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
apiUrl: String,
|
||||
|
@ -82,88 +82,85 @@ const props = defineProps({
|
|||
|
||||
const emits = defineEmits(['saved']);
|
||||
|
||||
const blankForm = {
|
||||
base_url: '',
|
||||
instance_name: '',
|
||||
prefer_browser_url: true,
|
||||
use_radio_proxy: true,
|
||||
history_keep_days: 7,
|
||||
enable_static_nowplaying: true,
|
||||
enable_advanced_features: true,
|
||||
analytics: null,
|
||||
always_use_ssl: false,
|
||||
api_access_control: '*',
|
||||
check_for_updates: 1,
|
||||
acme_email: '',
|
||||
acme_domains: '',
|
||||
mail_enabled: false,
|
||||
mail_sender_name: '',
|
||||
mail_sender_email: '',
|
||||
mail_smtp_host: '',
|
||||
mail_smtp_port: '',
|
||||
mail_smtp_secure: '',
|
||||
mail_smtp_username: '',
|
||||
mail_smtp_password: '',
|
||||
avatar_service: 'gravatar',
|
||||
avatar_default_url: '',
|
||||
use_external_album_art_in_apis: false,
|
||||
use_external_album_art_when_processing_media: false,
|
||||
last_fm_api_key: ''
|
||||
};
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
base_url: {required},
|
||||
instance_name: {},
|
||||
prefer_browser_url: {},
|
||||
use_radio_proxy: {},
|
||||
history_keep_days: {required},
|
||||
enable_static_nowplaying: {},
|
||||
enable_advanced_features: {},
|
||||
|
||||
const form = ref({...blankForm});
|
||||
analytics: {required},
|
||||
|
||||
const validations = {
|
||||
base_url: {required},
|
||||
instance_name: {},
|
||||
prefer_browser_url: {},
|
||||
use_radio_proxy: {},
|
||||
history_keep_days: {required},
|
||||
enable_static_nowplaying: {},
|
||||
enable_advanced_features: {},
|
||||
always_use_ssl: {},
|
||||
api_access_control: {},
|
||||
|
||||
analytics: {required},
|
||||
|
||||
always_use_ssl: {},
|
||||
api_access_control: {},
|
||||
|
||||
check_for_updates: {},
|
||||
acme_email: {},
|
||||
acme_domains: {},
|
||||
mail_enabled: {},
|
||||
mail_sender_name: {},
|
||||
mail_sender_email: {},
|
||||
mail_smtp_host: {},
|
||||
mail_smtp_port: {},
|
||||
mail_smtp_secure: {},
|
||||
mail_smtp_username: {},
|
||||
mail_smtp_password: {},
|
||||
avatar_service: {},
|
||||
avatar_default_url: {},
|
||||
use_external_album_art_in_apis: {},
|
||||
use_external_album_art_when_processing_media: {},
|
||||
last_fm_api_key: {},
|
||||
$validationGroups: {
|
||||
generalTab: [
|
||||
'base_url', 'instance_name', 'prefer_browser_url', 'use_radio_proxy',
|
||||
'history_keep_days', 'enable_static_nowplaying', 'enable_advanced_features'
|
||||
],
|
||||
securityPrivacyTab: [
|
||||
'analytics', 'always_use_ssl', 'api_access_control'
|
||||
],
|
||||
servicesTab: [
|
||||
'check_for_updates',
|
||||
'acme_email', 'acme_domains',
|
||||
'mail_enabled', 'mail_sender_name', 'mail_sender_email',
|
||||
'mail_smtp_host', 'mail_smtp_port', 'mail_smtp_secure', 'mail_smtp_username',
|
||||
'mail_smtp_password', 'avatar_service', 'avatar_default_url',
|
||||
'use_external_album_art_in_apis', 'use_external_album_art_when_processing_media',
|
||||
'last_fm_api_key',
|
||||
]
|
||||
check_for_updates: {},
|
||||
acme_email: {},
|
||||
acme_domains: {},
|
||||
mail_enabled: {},
|
||||
mail_sender_name: {},
|
||||
mail_sender_email: {},
|
||||
mail_smtp_host: {},
|
||||
mail_smtp_port: {},
|
||||
mail_smtp_secure: {},
|
||||
mail_smtp_username: {},
|
||||
mail_smtp_password: {},
|
||||
avatar_service: {},
|
||||
avatar_default_url: {},
|
||||
use_external_album_art_in_apis: {},
|
||||
use_external_album_art_when_processing_media: {},
|
||||
last_fm_api_key: {},
|
||||
$validationGroups: {
|
||||
generalTab: [
|
||||
'base_url', 'instance_name', 'prefer_browser_url', 'use_radio_proxy',
|
||||
'history_keep_days', 'enable_static_nowplaying', 'enable_advanced_features'
|
||||
],
|
||||
securityPrivacyTab: [
|
||||
'analytics', 'always_use_ssl', 'api_access_control'
|
||||
],
|
||||
servicesTab: [
|
||||
'check_for_updates',
|
||||
'acme_email', 'acme_domains',
|
||||
'mail_enabled', 'mail_sender_name', 'mail_sender_email',
|
||||
'mail_smtp_host', 'mail_smtp_port', 'mail_smtp_secure', 'mail_smtp_username',
|
||||
'mail_smtp_password', 'avatar_service', 'avatar_default_url',
|
||||
'use_external_album_art_in_apis', 'use_external_album_art_when_processing_media',
|
||||
'last_fm_api_key',
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
base_url: '',
|
||||
instance_name: '',
|
||||
prefer_browser_url: true,
|
||||
use_radio_proxy: true,
|
||||
history_keep_days: 7,
|
||||
enable_static_nowplaying: true,
|
||||
enable_advanced_features: true,
|
||||
analytics: null,
|
||||
always_use_ssl: false,
|
||||
api_access_control: '*',
|
||||
check_for_updates: 1,
|
||||
acme_email: '',
|
||||
acme_domains: '',
|
||||
mail_enabled: false,
|
||||
mail_sender_name: '',
|
||||
mail_sender_email: '',
|
||||
mail_smtp_host: '',
|
||||
mail_smtp_port: '',
|
||||
mail_smtp_secure: '',
|
||||
mail_smtp_username: '',
|
||||
mail_smtp_password: '',
|
||||
avatar_service: 'gravatar',
|
||||
avatar_default_url: '',
|
||||
use_external_album_art_in_apis: false,
|
||||
use_external_album_art_when_processing_media: false,
|
||||
last_fm_api_key: ''
|
||||
}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
);
|
||||
|
||||
const loading = ref(true);
|
||||
const error = ref(null);
|
||||
|
|
|
@ -19,33 +19,26 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {email, required} from '@vuelidate/validators';
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import {ref} from "vue";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
testMessageUrl: String
|
||||
});
|
||||
|
||||
const blankForm = {
|
||||
emailAddress: null
|
||||
};
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const validations = {
|
||||
emailAddress: {required, email}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form, {$stopPropagation: true});
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
};
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
emailAddress: {required, email}
|
||||
},
|
||||
{
|
||||
emailAddress: null
|
||||
}
|
||||
);
|
||||
|
||||
const modal = ref(); // BModal
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {required} from '@vuelidate/validators';
|
||||
import ModalForm from "~/components/Common/ModalForm";
|
||||
import AdminStationsCloneModalForm from "~/components/Admin/Stations/CloneModalForm";
|
||||
|
@ -17,6 +16,7 @@ import {ref} from "vue";
|
|||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const emit = defineEmits(['relist']);
|
||||
|
||||
|
@ -24,25 +24,18 @@ const loading = ref(true);
|
|||
const cloneUrl = ref(null);
|
||||
const error = ref(null);
|
||||
|
||||
const blankForm = {
|
||||
name: '',
|
||||
description: '',
|
||||
clone: [],
|
||||
};
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const validations = {
|
||||
name: {required},
|
||||
description: {},
|
||||
clone: {}
|
||||
};
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
};
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(
|
||||
{
|
||||
name: {required},
|
||||
description: {},
|
||||
clone: {}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
description: '',
|
||||
clone: [],
|
||||
}
|
||||
);
|
||||
|
||||
const modal = ref(); // BVModal
|
||||
const {$gettext} = useTranslate();
|
||||
|
|
|
@ -98,10 +98,10 @@ import AdminStationsStreamersForm from "./Form/StreamersForm.vue";
|
|||
import {decimal, numeric, required, url} from '@vuelidate/validators';
|
||||
import {AUDIO_PROCESSING_NONE, BACKEND_LIQUIDSOAP, FRONTEND_ICECAST} from "~/components/Entity/RadioAdapters";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {useNotify} from "~/vendor/bootstrapVue";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import mergeExisting from "~/functions/mergeExisting";
|
||||
import {useVuelidateOnForm} from "~/components/Form/UseVuelidateOnForm";
|
||||
|
||||
const props = defineProps({
|
||||
...StationFormProps.props,
|
||||
|
@ -335,10 +335,7 @@ const buildForm = () => {
|
|||
};
|
||||
|
||||
const {blankForm, validations} = buildForm();
|
||||
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
const {form, resetForm, v$} = useVuelidateOnForm(validations, blankForm);
|
||||
|
||||
const isValid = computed(() => {
|
||||
return !v$.value?.$invalid ?? true;
|
||||
|
@ -379,10 +376,10 @@ const getTabClass = (validationGroup) => {
|
|||
}
|
||||
|
||||
const clear = () => {
|
||||
resetForm();
|
||||
loading.value = false;
|
||||
error.value = null;
|
||||
station.value = {...blankStation};
|
||||
form.value = {...blankForm};
|
||||
};
|
||||
|
||||
const populateForm = (data) => {
|
||||
|
|
|
@ -13,6 +13,7 @@ import BaseEditModal from '~/components/Common/BaseEditModal';
|
|||
import StorageLocationForm from './Form';
|
||||
import useVuelidate from "@vuelidate/core";
|
||||
import {computed} from "vue";
|
||||
import {useResettableForm} from "~/components/Form/UseResettableForm";
|
||||
|
||||
export default {
|
||||
name: 'AdminStorageLocationsEditModal',
|
||||
|
@ -41,11 +42,7 @@ export default {
|
|||
'storageQuota': ''
|
||||
}
|
||||
|
||||
const form = {...blankForm};
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
};
|
||||
const {form, resetForm} = useResettableForm(blankForm);
|
||||
|
||||
const validations = computed(() => {
|
||||
let validationRules = {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import {ref} from "vue";
|
||||
|
||||
export function useResettableForm(blankForm) {
|
||||
const form = ref({...blankForm});
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {...blankForm};
|
||||
}
|
||||
|
||||
return {form, resetForm};
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import useVuelidate from "@vuelidate/core";
|
||||
import {useResettableForm} from "~/components/Form/UseResettableForm";
|
||||
|
||||
export function useVuelidateOnForm(validations, blankForm) {
|
||||
const {form, resetForm: parentResetForm} = useResettableForm(blankForm);
|
||||
|
||||
const v$ = useVuelidate(validations, form);
|
||||
|
||||
const resetForm = () => {
|
||||
v$.value.$reset();
|
||||
parentResetForm();
|
||||
}
|
||||
|
||||
return {
|
||||
form,
|
||||
resetForm,
|
||||
v$
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue