Create a second "silent" axios that doesn't show loading and error messages; use it for common repeating tasks.

This commit is contained in:
Buster Neece 2023-10-16 21:57:09 -05:00
parent 640b564e49
commit cf69dd034b
No known key found for this signature in database
5 changed files with 80 additions and 88 deletions

View File

@ -110,10 +110,10 @@ const statsUrl = getApiUrl('/admin/server/stats');
const menuItems = useAdminMenu();
const {axios} = useAxios();
const {axiosSilent} = useAxios();
const {state: stats, isLoading, execute: reloadStats} = useRefreshableAsyncState(
() => axios.get(statsUrl.value).then(r => r.data),
() => axiosSilent.get(statsUrl.value).then(r => r.data),
{
cpu: {
total: {

View File

@ -6,83 +6,74 @@
</h2>
</div>
<table class="table table-striped table-responsive mb-0">
<colgroup>
<col style="width: 5%;">
<col style="width: 75%;">
<col style="width: 20%;">
</colgroup>
<tbody>
<tr
v-for="service in services"
:key="service.name"
class="align-middle"
>
<td class="text-center pe-2">
<running-badge :running="service.running" />
</td>
<td class="ps-2">
<h6 class="mb-0">
{{ service.name }}<br>
<small>{{ service.description }}</small>
</h6>
</td>
<td>
<button
v-if="service.links.restart"
type="button"
class="btn btn-sm"
:class="service.running ? 'btn-primary' : 'btn-danger'"
@click="doRestart(service.links.restart)"
>
{{ $gettext('Restart') }}
</button>
</td>
</tr>
</tbody>
</table>
<loading :loading="isLoading">
<table class="table table-striped table-responsive mb-0">
<colgroup>
<col style="width: 5%;">
<col style="width: 75%;">
<col style="width: 20%;">
</colgroup>
<tbody>
<tr
v-for="service in services"
:key="service.name"
class="align-middle"
>
<td class="text-center pe-2">
<running-badge :running="service.running" />
</td>
<td class="ps-2">
<h6 class="mb-0">
{{ service.name }}<br>
<small>{{ service.description }}</small>
</h6>
</td>
<td>
<button
v-if="service.links.restart"
type="button"
class="btn btn-sm"
:class="service.running ? 'btn-primary' : 'btn-danger'"
@click="doRestart(service.links.restart)"
>
{{ $gettext('Restart') }}
</button>
</td>
</tr>
</tbody>
</table>
</loading>
</section>
</template>
<script setup lang="ts">
import RunningBadge from "~/components/Common/Badges/RunningBadge.vue";
import {getApiUrl} from "~/router.ts";
import {onMounted, onScopeDispose, ref} from "vue";
import {useAxios} from "~/vendor/axios.ts";
import {useNotify} from "~/functions/useNotify";
import useRefreshableAsyncState from "~/functions/useRefreshableAsyncState.ts";
import {useIntervalFn} from "@vueuse/core";
import {computed} from "vue";
import Loading from "~/components/Common/Loading.vue";
const servicesUrl = getApiUrl('/admin/services');
const services = ref([]);
const {axios, axiosSilent} = useAxios();
const {axios} = useAxios();
let serviceTimeout = null;
const clearUpdates = () => {
if (serviceTimeout) {
clearTimeout(serviceTimeout);
serviceTimeout = null;
const {state: services, isLoading, execute: reloadServices} = useRefreshableAsyncState(
() => axiosSilent.get(servicesUrl.value).then(r => r.data),
[],
{
shallow: true
}
};
);
onScopeDispose(clearUpdates);
const updateServices = () => {
axios.get(servicesUrl.value).then((response) => {
services.value = response.data;
clearUpdates();
serviceTimeout = setTimeout(updateServices, (!document.hidden) ? 5000 : 15000);
}).catch((error) => {
if (!error.response || error.response.data.code !== 403) {
clearUpdates();
serviceTimeout = setTimeout(updateServices, (!document.hidden) ? 15000 : 30000);
}
});
};
onMounted(updateServices);
useIntervalFn(
() => {
reloadServices()
},
computed(() => (!document.hidden) ? 5000 : 15000)
);
const {notifySuccess} = useNotify();

View File

@ -362,7 +362,7 @@ const langShowHideCharts = computed(() => {
: $gettext('Show Charts')
});
const {axios} = useAxios();
const {axios, axiosSilent} = useAxios();
const {state: user} = useAsyncState(
() => axios.get(props.userUrl)
@ -394,17 +394,13 @@ const {state: notifications, isLoading: notificationsLoading} = useAsyncState(
);
const {state: stations, isLoading: stationsLoading, execute: reloadStations} = useRefreshableAsyncState(
() => axios.get(props.stationsUrl).then((r) => r.data),
() => axiosSilent.get(props.stationsUrl).then((r) => r.data),
[],
);
const stationsReloadTimeout = computed(() => {
return (!document.hidden) ? 15000 : 30000
});
useIntervalFn(
reloadStations,
stationsReloadTimeout
computed(() => (!document.hidden) ? 15000 : 30000)
);
const $lightbox = ref<LightboxTemplateRef>(null);

View File

@ -127,10 +127,10 @@ const hasActiveBackend = computed(() => {
return props.backendType !== BackendAdapter.None;
});
const {axios} = useAxios();
const {axios, axiosSilent} = useAxios();
const {state: profileInfo, execute: reloadProfile} = useRefreshableAsyncState(
() => axios.get(props.profileApiUri).then((r) => r.data),
() => axiosSilent.get(props.profileApiUri).then((r) => r.data),
{
station: {
...NowPlaying.station
@ -145,13 +145,9 @@ const {state: profileInfo, execute: reloadProfile} = useRefreshableAsyncState(
}
);
const profileReloadTimeout = computed(() => {
return (!document.hidden) ? 15000 : 30000
});
useIntervalFn(
reloadProfile,
profileReloadTimeout
computed(() => (!document.hidden) ? 15000 : 30000)
);
const {showAlert} = useSweetAlert();

View File

@ -7,22 +7,28 @@ import {useAzuraCast} from "~/vendor/azuracast.ts";
import {useNProgress} from "~/vendor/nprogress.ts";
const injectKey: InjectionKey<AxiosStatic> = Symbol() as InjectionKey<AxiosStatic>;
const injectKeySilent: InjectionKey<AxiosStatic> = Symbol() as InjectionKey<AxiosStatic>;
/* Composition API Axios utilities */
interface UseAxios {
axios: AxiosStatic
axios: AxiosStatic,
axiosSilent: AxiosStatic
}
export const useAxios = (): UseAxios => ({
axios: inject<AxiosStatic>(injectKey)
axios: inject<AxiosStatic>(injectKey),
axiosSilent: inject<AxiosStatic>(injectKeySilent)
});
export default function installAxios(vueApp: App) {
// Configure auto-CSRF on requests
const {apiCsrf} = useAzuraCast();
if (apiCsrf) {
axios.defaults.headers.common['X-API-CSRF'] = apiCsrf;
}
const axiosInstance = axios.create({
headers: {
'X-API-CSRF': apiCsrf
}
});
// Configure some Axios settings that depend on the BootstrapVue $bvToast superglobal.
const handleAxiosError = (error) => {
@ -45,9 +51,11 @@ export default function installAxios(vueApp: App) {
notifyError(notifyMessage);
};
const axiosSilent = axiosInstance.create({});
const {setLoading} = useNProgress();
axios.interceptors.request.use((config) => {
axiosInstance.interceptors.request.use((config) => {
setLoading(true);
return config;
}, (error) => {
@ -56,7 +64,7 @@ export default function installAxios(vueApp: App) {
return Promise.reject(error);
});
axios.interceptors.response.use((response) => {
axiosInstance.interceptors.response.use((response) => {
setLoading(false);
return response;
}, (error) => {
@ -65,7 +73,8 @@ export default function installAxios(vueApp: App) {
return Promise.reject(error);
});
vueApp.use(VueAxios, axios);
vueApp.use(VueAxios, axiosInstance);
vueApp.provide(injectKey, axios);
vueApp.provide(injectKey, axiosInstance);
vueApp.provide(injectKeySilent, axiosSilent);
}