cordis/client/webapp/elements/error-indicator.ts

67 lines
2.3 KiB
TypeScript
Raw Normal View History

2021-10-30 17:26:41 +00:00
import * as electronRemote from '@electron/remote';
const electronConsole = electronRemote.getGlobal('console') as Console;
import Logger from '../../../logger/logger';
2021-11-02 04:29:24 +00:00
const LOG = Logger.create(__filename, electronConsole);
2021-10-30 17:26:41 +00:00
import { $, $$, $$$, $$$$ } from './require/q-module';
import IState from './require/elements-state';
import ElementsUtil from './require/elements-util';
export interface CreateErrorIndicatorProps {
container: HTMLElement;
classes?: string[];
message: string;
taskFunc: (() => Promise<void>);
resolveFunc: ((result: unknown) => void);
rejectFunc: ((err: Error) => void);
}
// resolveFunc and rejectFunc should be the resolve/reject functions from the withPotentialError promise
export default function createErrorIndicator(state: IState, props: CreateErrorIndicatorProps): HTMLElement {
const { document } = state;
let { container, classes, message, taskFunc, resolveFunc, rejectFunc } = props;
$.setDocument(document);
classes = classes || [];
let element = $.create({
class: [ 'error-indicator', ...classes ], content: [
{ tag: 'img', src: './img/error.png', alt: 'error' },
{ content: [
{ content: message },
{ class: 'retry-button', content: 'Try Again' }
] }
]
}) as HTMLElement;
let observer = new MutationObserver(() => {
if (element.parentElement == null) {
rejectFunc(new Error('indicator removed'));
observer.disconnect();
}
});
observer.observe(container, { childList: true });
let retrying = false;
$$$(element, '.retry-button').addEventListener('click', async () => {
if (retrying) return;
retrying = true;
$$$(element, '.retry-button').innerText = 'Fetching...';
try {
observer.disconnect();
await taskFunc();
resolveFunc(null);
} catch (e) {
observer.observe(container, { childList: true });
LOG.error('error during retry', e);
$$$(element, '.retry-button').innerText = 'Try Again';
await ElementsUtil.shakeElement($$$(element, '.retry-button'), 400);
}
retrying = false;
});
return element;
}