feat: add backend status down indicator (#3889)
This commit is contained in:
@ -4,7 +4,7 @@ import { ThunkDispatch } from 'redux-thunk';
|
||||
import { AnyAction } from 'redux';
|
||||
import { actions as notifActions } from 'redux-notifications';
|
||||
|
||||
const { notifSend } = notifActions;
|
||||
const { notifSend, notifDismiss } = notifActions;
|
||||
|
||||
export const STATUS_REQUEST = 'STATUS_REQUEST';
|
||||
export const STATUS_SUCCESS = 'STATUS_SUCCESS';
|
||||
@ -16,7 +16,10 @@ export function statusRequest() {
|
||||
};
|
||||
}
|
||||
|
||||
export function statusSuccess(status: { auth: boolean }) {
|
||||
export function statusSuccess(status: {
|
||||
auth: { status: boolean };
|
||||
api: { status: boolean; statusPage: string };
|
||||
}) {
|
||||
return {
|
||||
type: STATUS_SUCCESS,
|
||||
payload: { status },
|
||||
@ -26,7 +29,7 @@ export function statusSuccess(status: { auth: boolean }) {
|
||||
export function statusFailure(error: Error) {
|
||||
return {
|
||||
type: STATUS_FAILURE,
|
||||
error,
|
||||
payload: { error },
|
||||
};
|
||||
}
|
||||
|
||||
@ -42,7 +45,30 @@ export function checkBackendStatus() {
|
||||
const backend = currentBackend(state.config);
|
||||
const status = await backend.status();
|
||||
|
||||
const authError = status.auth === false;
|
||||
const backendDownKey = 'ui.toast.onBackendDown';
|
||||
const previousBackendDownNotifs = state.notifs.filter(n => n.message?.key === backendDownKey);
|
||||
|
||||
if (status.api.status === false) {
|
||||
if (previousBackendDownNotifs.length === 0) {
|
||||
dispatch(
|
||||
notifSend({
|
||||
message: {
|
||||
details: status.api.statusPage,
|
||||
key: 'ui.toast.onBackendDown',
|
||||
},
|
||||
kind: 'danger',
|
||||
}),
|
||||
);
|
||||
}
|
||||
return dispatch(statusSuccess(status));
|
||||
} else if (status.api.status === true && previousBackendDownNotifs.length > 0) {
|
||||
// If backend is up, clear all the danger messages
|
||||
previousBackendDownNotifs.forEach(notif => {
|
||||
dispatch(notifDismiss(notif.id));
|
||||
});
|
||||
}
|
||||
|
||||
const authError = status.auth.status === false;
|
||||
if (authError) {
|
||||
const key = 'ui.toast.onLoggedOut';
|
||||
const existingNotification = state.notifs.find(n => n.message?.key === key);
|
||||
|
@ -181,11 +181,17 @@ export class Backend {
|
||||
|
||||
async status() {
|
||||
const attempts = 3;
|
||||
let status: { auth: boolean } = { auth: false };
|
||||
let status: {
|
||||
auth: { status: boolean };
|
||||
api: { status: boolean; statusPage: string };
|
||||
} = {
|
||||
auth: { status: false },
|
||||
api: { status: false, statusPage: '' },
|
||||
};
|
||||
for (let i = 1; i <= attempts; i++) {
|
||||
status = await this.implementation!.status();
|
||||
// return on first success
|
||||
if (Object.values(status).every(s => s === true)) {
|
||||
if (Object.values(status).every(s => s.status === true)) {
|
||||
return status;
|
||||
} else {
|
||||
await new Promise(resolve => setTimeout(resolve, i * 1000));
|
||||
|
@ -3,11 +3,14 @@ import { AnyAction } from 'redux';
|
||||
import { STATUS_REQUEST, STATUS_SUCCESS, STATUS_FAILURE } from '../actions/status';
|
||||
import { Status } from '../types/redux';
|
||||
|
||||
export interface EntriesAction extends AnyAction {
|
||||
payload: { status: { auth: boolean }; error?: Error };
|
||||
interface StatusAction extends AnyAction {
|
||||
payload: {
|
||||
status: { auth: { status: boolean }; api: { status: boolean; statusPage: string } };
|
||||
error?: Error;
|
||||
};
|
||||
}
|
||||
|
||||
const status = (state = Map(), action: EntriesAction) => {
|
||||
const status = (state = Map(), action: StatusAction) => {
|
||||
switch (action.type) {
|
||||
case STATUS_REQUEST:
|
||||
return state.set('isFetching', true);
|
||||
|
Reference in New Issue
Block a user