mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-14 05:06:37 +00:00
Restructure main Vue app invocation to support using BootstrapVue components in Composition API.
This commit is contained in:
parent
250dafcbb1
commit
f20a78ccad
|
@ -1,39 +1,91 @@
|
||||||
import installPinia from './vendor/pinia';
|
import installPinia from './vendor/pinia';
|
||||||
import gettext from './vendor/gettext';
|
import gettext from './vendor/gettext';
|
||||||
import {createApp} from "vue";
|
import {createApp, h} from "vue";
|
||||||
import installBootstrapVue from "./vendor/bootstrapVue";
|
import installBootstrapVue from "./vendor/bootstrapVue";
|
||||||
import installSweetAlert from "./vendor/sweetalert";
|
import installSweetAlert from "./vendor/sweetalert";
|
||||||
import installAxios from "~/vendor/axios";
|
import installAxios from "~/vendor/axios";
|
||||||
|
import useAzuraCast from "~/vendor/azuracast";
|
||||||
|
import axios from "axios";
|
||||||
|
import {useEventBus} from "@vueuse/core";
|
||||||
|
|
||||||
export default function (component, options) {
|
export default function (component) {
|
||||||
return function (el, props) {
|
const vueApp = createApp({
|
||||||
const vueApp = createApp(
|
render() {
|
||||||
component,
|
return h(component, this.$appProps)
|
||||||
{
|
},
|
||||||
...options,
|
mounted() {
|
||||||
...props
|
// Workaround to use BootstrapVue toast notifications in Vue 3 composition API.
|
||||||
}
|
const notifyBus = useEventBus('notify');
|
||||||
);
|
|
||||||
|
|
||||||
/* Gettext */
|
notifyBus.on((event, payload) => {
|
||||||
if (typeof App.locale !== 'undefined') {
|
if (event === 'show') {
|
||||||
vueApp.config.language = App.locale;
|
this.$bvToast.toast(payload.message, payload.options);
|
||||||
|
} else if (event === 'hide') {
|
||||||
|
this.$bvToast.hide(payload.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure some Axios settings that depend on the BootstrapVue $bvToast superglobal.
|
||||||
|
const handleAxiosError = (error) => {
|
||||||
|
const {$gettext} = gettext;
|
||||||
|
|
||||||
|
let notifyMessage = $gettext('An error occurred and your request could not be completed.');
|
||||||
|
if (error.response) {
|
||||||
|
// Request made and server responded
|
||||||
|
notifyMessage = error.response.data.message;
|
||||||
|
console.error(notifyMessage);
|
||||||
|
} else if (error.request) {
|
||||||
|
// The request was made but no response was received
|
||||||
|
console.error(error.request);
|
||||||
|
} else {
|
||||||
|
// Something happened in setting up the request that triggered an Error
|
||||||
|
console.error('Error', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this.$notifyError === 'function') {
|
||||||
|
this.$notifyError(notifyMessage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
axios.interceptors.request.use((config) => {
|
||||||
|
return config;
|
||||||
|
}, (error) => {
|
||||||
|
handleAxiosError(error);
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
axios.interceptors.response.use((response) => {
|
||||||
|
return response;
|
||||||
|
}, (error) => {
|
||||||
|
handleAxiosError(error);
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
vueApp.use(gettext);
|
/* Gettext */
|
||||||
|
const {locale} = useAzuraCast();
|
||||||
|
|
||||||
/* Axios */
|
if (typeof locale !== 'undefined') {
|
||||||
installAxios(vueApp);
|
vueApp.config.language = locale;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pinia */
|
vueApp.use(gettext);
|
||||||
installPinia(vueApp);
|
|
||||||
|
|
||||||
/* Bootstrap Vue */
|
/* Axios */
|
||||||
installBootstrapVue(vueApp);
|
installAxios(vueApp);
|
||||||
|
|
||||||
/* SweetAlert */
|
/* Pinia */
|
||||||
installSweetAlert(vueApp);
|
installPinia(vueApp);
|
||||||
|
|
||||||
|
/* Bootstrap Vue */
|
||||||
|
installBootstrapVue(vueApp);
|
||||||
|
|
||||||
|
/* SweetAlert */
|
||||||
|
installSweetAlert(vueApp);
|
||||||
|
|
||||||
|
return function (el, props) {
|
||||||
|
vueApp.config.globalProperties.$appProps = props;
|
||||||
vueApp.mount(el);
|
vueApp.mount(el);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<modal-form ref="modal" size="lg" :title="langTitle" :loading="loading" :disable-save-button="v$.form.$invalid"
|
<modal-form ref="modal" size="lg" :title="$gettext('Configure Backups')" :loading="loading"
|
||||||
@submit="submit" @hidden="clearContents">
|
:disable-save-button="v$.$invalid" @submit="submit" @hidden="clearContents">
|
||||||
<b-form-fieldset>
|
<b-form-fieldset>
|
||||||
<div class="form-row mb-3">
|
<div class="form-row mb-3">
|
||||||
<b-wrapped-form-checkbox class="col-md-12" id="form_edit_backup_enabled"
|
<b-wrapped-form-checkbox class="col-md-12" id="form_edit_backup_enabled"
|
||||||
:field="v$.form.backup_enabled">
|
:field="v$.backup_enabled">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Run Automatic Nightly Backups') }}
|
{{ $gettext('Run Automatic Nightly Backups') }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
</b-wrapped-form-checkbox>
|
</b-wrapped-form-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row" v-if="v$.form.backup_enabled.$model">
|
<div class="form-row" v-if="v$.backup_enabled.$model">
|
||||||
<b-wrapped-form-group class="col-md-6" id="form_backup_time_code" :field="v$.form.backup_time_code">
|
<b-wrapped-form-group class="col-md-6" id="form_backup_time_code" :field="v$.backup_time_code">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Scheduled Backup Time') }}
|
{{ $gettext('Scheduled Backup Time') }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</b-wrapped-form-group>
|
</b-wrapped-form-group>
|
||||||
|
|
||||||
<b-wrapped-form-checkbox class="col-md-6" id="form_edit_exclude_media"
|
<b-wrapped-form-checkbox class="col-md-6" id="form_edit_exclude_media"
|
||||||
:field="v$.form.backup_exclude_media">
|
:field="v$.backup_exclude_media">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Exclude Media from Backup') }}
|
{{ $gettext('Exclude Media from Backup') }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
</template>
|
</template>
|
||||||
</b-wrapped-form-checkbox>
|
</b-wrapped-form-checkbox>
|
||||||
|
|
||||||
<b-wrapped-form-group class="col-md-6" id="form_backup_keep_copies" :field="v$.form.backup_keep_copies"
|
<b-wrapped-form-group class="col-md-6" id="form_backup_keep_copies" :field="v$.backup_keep_copies"
|
||||||
input-type="number" :input-attrs="{min: '0', max: '365'}">
|
input-type="number" :input-attrs="{min: '0', max: '365'}">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Number of Backup Copies to Keep') }}
|
{{ $gettext('Number of Backup Copies to Keep') }}
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</b-wrapped-form-group>
|
</b-wrapped-form-group>
|
||||||
|
|
||||||
<b-wrapped-form-group class="col-md-6" id="edit_form_backup_storage_location"
|
<b-wrapped-form-group class="col-md-6" id="edit_form_backup_storage_location"
|
||||||
:field="v$.form.backup_storage_location">
|
:field="v$.backup_storage_location">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Storage Location') }}
|
{{ $gettext('Storage Location') }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
</template>
|
</template>
|
||||||
</b-wrapped-form-group>
|
</b-wrapped-form-group>
|
||||||
|
|
||||||
<b-wrapped-form-group class="col-md-6" id="edit_form_backup_format" :field="v$.form.backup_format">
|
<b-wrapped-form-group class="col-md-6" id="edit_form_backup_format" :field="v$.backup_format">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ $gettext('Backup Format') }}
|
{{ $gettext('Backup Format') }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -78,9 +78,7 @@
|
||||||
</modal-form>
|
</modal-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import useVuelidate from "@vuelidate/core";
|
|
||||||
import CodemirrorTextarea from "~/components/Common/CodemirrorTextarea";
|
|
||||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||||
import ModalForm from "~/components/Common/ModalForm";
|
import ModalForm from "~/components/Common/ModalForm";
|
||||||
import BFormFieldset from "~/components/Form/BFormFieldset";
|
import BFormFieldset from "~/components/Form/BFormFieldset";
|
||||||
|
@ -88,113 +86,113 @@ import mergeExisting from "~/functions/mergeExisting";
|
||||||
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
import BWrappedFormCheckbox from "~/components/Form/BWrappedFormCheckbox";
|
||||||
import TimeCode from "~/components/Common/TimeCode";
|
import TimeCode from "~/components/Common/TimeCode";
|
||||||
import objectToFormOptions from "~/functions/objectToFormOptions";
|
import objectToFormOptions from "~/functions/objectToFormOptions";
|
||||||
|
import {computed, ref} from "vue";
|
||||||
|
import {useAxios} from "~/vendor/axios";
|
||||||
|
import {useNotify} from "~/vendor/bootstrapVue";
|
||||||
|
import useVuelidate from "@vuelidate/core";
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
name: 'AdminBackupsConfigureModal',
|
settingsUrl: String,
|
||||||
emits: ['relist'],
|
storageLocations: Object
|
||||||
setup() {
|
});
|
||||||
return {v$: useVuelidate()}
|
|
||||||
},
|
const emit = defineEmits(['relist']);
|
||||||
props: {
|
|
||||||
settingsUrl: String,
|
const loading = ref(true);
|
||||||
storageLocations: Object
|
const error = ref(null);
|
||||||
},
|
|
||||||
components: {
|
const form = ref({});
|
||||||
ModalForm,
|
|
||||||
BFormFieldset,
|
const modal = ref(); // Template Ref
|
||||||
BWrappedFormGroup,
|
|
||||||
BWrappedFormCheckbox,
|
const validations = {
|
||||||
CodemirrorTextarea,
|
'backup_enabled': {},
|
||||||
TimeCode
|
'backup_time_code': {},
|
||||||
},
|
'backup_exclude_media': {},
|
||||||
data() {
|
'backup_keep_copies': {},
|
||||||
return {
|
'backup_storage_location': {},
|
||||||
loading: true,
|
'backup_format': {},
|
||||||
error: null,
|
};
|
||||||
form: {},
|
|
||||||
};
|
const v$ = useVuelidate(validations, form);
|
||||||
},
|
|
||||||
validations: {
|
const storageLocationOptions = computed(() => {
|
||||||
form: {
|
return objectToFormOptions(props.storageLocations);
|
||||||
'backup_enabled': {},
|
});
|
||||||
'backup_time_code': {},
|
|
||||||
'backup_exclude_media': {},
|
const formatOptions = computed(() => {
|
||||||
'backup_keep_copies': {},
|
return [
|
||||||
'backup_storage_location': {},
|
{
|
||||||
'backup_format': {},
|
value: 'zip',
|
||||||
|
text: 'Zip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'tgz',
|
||||||
|
text: 'TarGz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'tzst',
|
||||||
|
text: 'ZStd'
|
||||||
}
|
}
|
||||||
},
|
];
|
||||||
computed: {
|
});
|
||||||
langTitle() {
|
|
||||||
return this.$gettext('Configure Backups');
|
|
||||||
},
|
|
||||||
storageLocationOptions() {
|
|
||||||
return objectToFormOptions(this.storageLocations);
|
|
||||||
},
|
|
||||||
formatOptions() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
value: 'zip',
|
|
||||||
text: 'Zip',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'tgz',
|
|
||||||
text: 'TarGz'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'tzst',
|
|
||||||
text: 'ZStd'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
open() {
|
|
||||||
this.clearContents();
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
this.$refs.modal.show();
|
const clearContents = () => {
|
||||||
|
v$.value.$reset();
|
||||||
|
|
||||||
this.axios.get(this.settingsUrl).then((resp) => {
|
form.value = {
|
||||||
this.form = mergeExisting(this.form, resp.data);
|
backup_enabled: false,
|
||||||
this.loading = false;
|
backup_time_code: null,
|
||||||
}).catch(() => {
|
backup_exclude_media: null,
|
||||||
this.close();
|
backup_keep_copies: null,
|
||||||
});
|
backup_storage_location: null,
|
||||||
},
|
backup_format: null,
|
||||||
clearContents() {
|
};
|
||||||
this.v$.$reset();
|
};
|
||||||
|
|
||||||
this.form = {
|
const {axios} = useAxios();
|
||||||
backup_enabled: false,
|
|
||||||
backup_time_code: null,
|
|
||||||
backup_exclude_media: null,
|
|
||||||
backup_keep_copies: null,
|
|
||||||
backup_storage_location: null,
|
|
||||||
backup_format: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.$emit('relist');
|
|
||||||
this.$refs.modal.hide();
|
|
||||||
},
|
|
||||||
submit() {
|
|
||||||
this.v$.$touch();
|
|
||||||
if (this.v$.$errors.length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$wrapWithLoading(
|
const close = () => {
|
||||||
this.axios({
|
emit('relist');
|
||||||
method: 'PUT',
|
modal.value.hide();
|
||||||
url: this.settingsUrl,
|
};
|
||||||
data: this.form
|
|
||||||
})
|
const open = () => {
|
||||||
).then(() => {
|
clearContents();
|
||||||
this.$notifySuccess();
|
loading.value = true;
|
||||||
this.close();
|
|
||||||
});
|
modal.value.show();
|
||||||
}
|
|
||||||
|
axios.get(props.settingsUrl).then((resp) => {
|
||||||
|
form.value = mergeExisting(form.value, resp.data);
|
||||||
|
loading.value = false;
|
||||||
|
}).catch(() => {
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const {wrapWithLoading, notifySuccess} = useNotify();
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
v$.value.$touch();
|
||||||
|
|
||||||
|
if (v$.value.$errors.length > 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wrapWithLoading(
|
||||||
|
axios({
|
||||||
|
method: 'PUT',
|
||||||
|
url: props.settingsUrl,
|
||||||
|
data: form.value
|
||||||
|
})
|
||||||
|
).then(() => {
|
||||||
|
notifySuccess();
|
||||||
|
close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<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">
|
@submit="doSubmit" @hidden="clearContents">
|
||||||
|
|
||||||
<admin-custom-fields-form :form="v$.form" :auto-assign-types="autoAssignTypes">
|
<admin-custom-fields-form :form="v$" :auto-assign-types="autoAssignTypes">
|
||||||
</admin-custom-fields-form>
|
</admin-custom-fields-form>
|
||||||
|
|
||||||
</modal-form>
|
</modal-form>
|
||||||
|
@ -13,14 +13,39 @@ import useVuelidate from "@vuelidate/core";
|
||||||
import {required} from '@vuelidate/validators';
|
import {required} from '@vuelidate/validators';
|
||||||
import BaseEditModal from '~/components/Common/BaseEditModal';
|
import BaseEditModal from '~/components/Common/BaseEditModal';
|
||||||
import AdminCustomFieldsForm from "~/components/Admin/CustomFields/Form";
|
import AdminCustomFieldsForm from "~/components/Admin/CustomFields/Form";
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AdminCustomFieldsEditModal',
|
name: 'AdminCustomFieldsEditModal',
|
||||||
|
mixins: [BaseEditModal],
|
||||||
components: {AdminCustomFieldsForm},
|
components: {AdminCustomFieldsForm},
|
||||||
setup() {
|
setup() {
|
||||||
return {v$: useVuelidate()}
|
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);
|
||||||
|
|
||||||
|
return {
|
||||||
|
form,
|
||||||
|
resetForm,
|
||||||
|
v$
|
||||||
|
};
|
||||||
},
|
},
|
||||||
mixins: [BaseEditModal],
|
|
||||||
props: {
|
props: {
|
||||||
autoAssignTypes: Object
|
autoAssignTypes: Object
|
||||||
},
|
},
|
||||||
|
@ -31,23 +56,5 @@ export default {
|
||||||
: this.$gettext('Add Custom Field');
|
: this.$gettext('Add Custom Field');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validations() {
|
|
||||||
return {
|
|
||||||
form: {
|
|
||||||
'name': {required},
|
|
||||||
'short_name': {},
|
|
||||||
'auto_assign': {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
resetForm() {
|
|
||||||
this.form = {
|
|
||||||
'name': '',
|
|
||||||
'short_name': '',
|
|
||||||
'auto_assign': ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
42
frontend/vue/vendor/axios.js
vendored
42
frontend/vue/vendor/axios.js
vendored
|
@ -1,6 +1,5 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import VueAxios from "vue-axios";
|
import VueAxios from "vue-axios";
|
||||||
import gettext from "~/vendor/gettext";
|
|
||||||
import {inject} from "vue";
|
import {inject} from "vue";
|
||||||
import useAzuraCast from "~/vendor/azuracast";
|
import useAzuraCast from "~/vendor/azuracast";
|
||||||
|
|
||||||
|
@ -20,45 +19,6 @@ export default function installAxios(vueApp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vueApp.use(VueAxios, axios);
|
vueApp.use(VueAxios, axios);
|
||||||
|
|
||||||
vueApp.provide('axios', axios);
|
vueApp.provide('axios', axios);
|
||||||
|
|
||||||
vueApp.mixin({
|
|
||||||
mounted() {
|
|
||||||
const handleAxiosError = (error) => {
|
|
||||||
const {$gettext} = gettext;
|
|
||||||
|
|
||||||
let notifyMessage = $gettext('An error occurred and your request could not be completed.');
|
|
||||||
if (error.response) {
|
|
||||||
// Request made and server responded
|
|
||||||
notifyMessage = error.response.data.message;
|
|
||||||
console.error(notifyMessage);
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
console.error(error.request);
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof this.$notifyError === 'function') {
|
|
||||||
this.$notifyError(notifyMessage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios.interceptors.request.use((config) => {
|
|
||||||
return config;
|
|
||||||
}, (error) => {
|
|
||||||
handleAxiosError(error);
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
axios.interceptors.response.use((response) => {
|
|
||||||
return response;
|
|
||||||
}, (error) => {
|
|
||||||
handleAxiosError(error);
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
127
frontend/vue/vendor/bootstrapVue.js
vendored
127
frontend/vue/vendor/bootstrapVue.js
vendored
|
@ -1,15 +1,15 @@
|
||||||
import {BootstrapVue} from 'bootstrap-vue';
|
import {BootstrapVue} from 'bootstrap-vue';
|
||||||
|
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
||||||
import {inject} from "vue";
|
|
||||||
import gettext from "~/vendor/gettext";
|
import gettext from "~/vendor/gettext";
|
||||||
|
import {useEventBus} from "@vueuse/core";
|
||||||
|
|
||||||
/* Composition API BootstrapVue utilities */
|
/* Composition API BootstrapVue utilities */
|
||||||
export function useNotify() {
|
export function useNotify() {
|
||||||
const $bvToast = inject('bvToast');
|
|
||||||
const {$gettext} = gettext;
|
const {$gettext} = gettext;
|
||||||
|
const notifyBus = useEventBus('notify');
|
||||||
|
|
||||||
const notify = function (message = null, options = {}) {
|
const notify = (message = null, options = {}) => {
|
||||||
if (!!document.hidden) {
|
if (!!document.hidden) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,10 @@ export function useNotify() {
|
||||||
solid: true
|
solid: true
|
||||||
};
|
};
|
||||||
|
|
||||||
$bvToast.toast(message, {...defaults, ...options});
|
notifyBus.emit('show', {
|
||||||
|
message: message,
|
||||||
|
options: {...defaults, ...options}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const notifyError = (message = null, options = {}) => {
|
const notifyError = (message = null, options = {}) => {
|
||||||
|
@ -74,7 +77,9 @@ export function useNotify() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideLoading = () => {
|
const hideLoading = () => {
|
||||||
$bvToast.hide(LOADING_TOAST_ID);
|
notifyBus.emit('hide', {
|
||||||
|
id: LOADING_TOAST_ID
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let $isAxiosLoading = false;
|
let $isAxiosLoading = false;
|
||||||
|
@ -109,6 +114,15 @@ export function useNotify() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
install(app) {
|
||||||
|
app.config.globalProperties.$notify = notify;
|
||||||
|
app.config.globalProperties.$notifyError = notifyError;
|
||||||
|
app.config.globalProperties.$notifySuccess = notifySuccess;
|
||||||
|
app.config.globalProperties.$showLoading = showLoading;
|
||||||
|
app.config.globalProperties.$hideLoading = hideLoading;
|
||||||
|
app.config.globalProperties.$setLoading = setLoading;
|
||||||
|
app.config.globalProperties.$wrapWithLoading = wrapWithLoading;
|
||||||
|
},
|
||||||
notify,
|
notify,
|
||||||
notifyError,
|
notifyError,
|
||||||
notifySuccess,
|
notifySuccess,
|
||||||
|
@ -121,106 +135,5 @@ export function useNotify() {
|
||||||
|
|
||||||
export default function installBootstrapVue(vueApp) {
|
export default function installBootstrapVue(vueApp) {
|
||||||
vueApp.use(BootstrapVue);
|
vueApp.use(BootstrapVue);
|
||||||
|
vueApp.use(useNotify());
|
||||||
vueApp.provide('bvToast', vueApp.config.globalProperties.$bvToast);
|
|
||||||
vueApp.provide('bvModal', vueApp.config.globalProperties.$bvModal);
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$notify = function (message = null, options = {}) {
|
|
||||||
if (!!document.hidden) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaults = {
|
|
||||||
variant: 'default',
|
|
||||||
toaster: 'b-toaster-top-right',
|
|
||||||
autoHideDelay: 3000,
|
|
||||||
solid: true
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$bvToast.toast(message, {...defaults, ...options});
|
|
||||||
};
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$notifyError = function (message = null, options = {}) {
|
|
||||||
if (message === null) {
|
|
||||||
message = this.$gettext('An error occurred and your request could not be completed.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaults = {
|
|
||||||
variant: 'danger',
|
|
||||||
title: this.$gettext('Error')
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$notify(message, {...defaults, ...options});
|
|
||||||
|
|
||||||
return message;
|
|
||||||
};
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$notifySuccess = function (message = null, options = {}) {
|
|
||||||
if (message === null) {
|
|
||||||
message = this.$gettext('Changes saved.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaults = {
|
|
||||||
variant: 'success',
|
|
||||||
title: this.$gettext('Success')
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$notify(message, {...defaults, ...options});
|
|
||||||
|
|
||||||
return message;
|
|
||||||
};
|
|
||||||
|
|
||||||
const LOADING_TOAST_ID = 'toast-loading';
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$showLoading = function (message = null, options = {}) {
|
|
||||||
if (message === null) {
|
|
||||||
message = this.$gettext('Applying changes...');
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaults = {
|
|
||||||
id: LOADING_TOAST_ID,
|
|
||||||
variant: 'warning',
|
|
||||||
title: this.$gettext('Please wait...'),
|
|
||||||
autoHideDelay: 10000,
|
|
||||||
isStatus: true
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$notify(message, {...defaults, ...options});
|
|
||||||
return message;
|
|
||||||
};
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$hideLoading = function () {
|
|
||||||
this.$bvToast.hide(LOADING_TOAST_ID);
|
|
||||||
};
|
|
||||||
|
|
||||||
let $isAxiosLoading = false;
|
|
||||||
let $axiosLoadCount = 0;
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$setLoading = function (isLoading) {
|
|
||||||
let prevIsLoading = $isAxiosLoading;
|
|
||||||
if (isLoading) {
|
|
||||||
$axiosLoadCount++;
|
|
||||||
$isAxiosLoading = true;
|
|
||||||
} else if ($axiosLoadCount > 0) {
|
|
||||||
$axiosLoadCount--;
|
|
||||||
$isAxiosLoading = ($axiosLoadCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle state changes
|
|
||||||
if (!prevIsLoading && $isAxiosLoading) {
|
|
||||||
this.$showLoading();
|
|
||||||
} else if (prevIsLoading && !$isAxiosLoading) {
|
|
||||||
this.$hideLoading();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
vueApp.config.globalProperties.$wrapWithLoading = function (promise) {
|
|
||||||
this.$setLoading(true);
|
|
||||||
|
|
||||||
promise.finally(() => {
|
|
||||||
this.$setLoading(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user