cordis/client/webapp/elements/overlay-token-log.ts

134 lines
6.5 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 * as moment from 'moment';
import BaseElements from './require/base-elements';
import ElementsUtil from './require/elements-util';
import Util from '../util';
import { $, $$, $$$, $$$$ } from './require/q-module';
import IState from './require/elements-state';
import ClientController from '../client-controller';
import { Member } from '../data-types';
export default function createTokenLogOverlay(state: IState, server: ClientController): HTMLElement {
const { document } = state;
$.setDocument(document);
let element = BaseElements.createOverlay(document, {
class: 'content token-log', content: [
{ class: 'tokens', content: { tag: 'img', src: './img/loading.svg', alt: 'loading...' } },
]
});
(async () => {
Util.withPotentialErrorWarnOnCancel({
taskFunc: async () => {
let tokens = await server.queryTokens();
$.clearChildren($$$(element, '.tokens'));
let displayed = 0;
for (let token of tokens) {
// if (token.member != null) {
// continue;
// }
let expired = token.expires < new Date();
// NOTE: It may be nice to be able to click-to-copy the token
let memberText: string;
if (token.member instanceof Member) {
memberText = token.member.displayName;
} else if (token.member) {
memberText = '#' + token.member.id;
} else {
memberText = 'Unused Token';
}
let displayElement = $.create({
class: 'token-display', content: [
{ class: 'instance', content: [
{ class: 'left', content: [
{ class: 'member', content: memberText },
{ class: 'token', content: token.token },
] },
{ class: 'right', content: [
{ class: 'created', content: 'Created ' + moment(token.created).fromNow() },
{ class: 'expires', content: (expired ? 'Expired ' : 'Expires ') + moment(token.expires).fromNow() },
] }
] },
{ class: 'buttons', content: [
{ class: 'revoke', content: BaseElements.TRASHCAN }
] }
]
}) as HTMLElement;
let revokeElement = $$$(displayElement, '.buttons .revoke');
let contextElement = $.create({ class: 'context', content: {
class: 'above', content: [
{ class: 'tab', content: BaseElements.TAB_ABOVE },
{ class: 'content text', content: 'Revoke' },
] }
}) as HTMLElement;
let alignment = { centerX: 'centerX', top: 'bottom' };
ElementsUtil.bindHoverableContextElement(
revokeElement,
contextElement,
revokeElement,
alignment
);
let revoking = false;
let hoverTimeout: any | null = null;
revokeElement.addEventListener('click', async () => {
if (revoking) return;
revoking = true;
if (hoverTimeout) clearTimeout(hoverTimeout);
(contextElement as any).manualRemoval = true;
$$$(contextElement, '.content').innerText = 'Revoking...';
ElementsUtil.alignContextElement(contextElement, revokeElement, alignment);
try {
await server.revokeToken(token.token);
} catch (e) {
LOG.error('unable to revoke token', e);
$$$(contextElement, '.content').innerText = 'Unable to Revoke';
ElementsUtil.alignContextElement(contextElement, revokeElement, alignment);
await ElementsUtil.shakeElement(revokeElement, 400);
hoverTimeout = setTimeout(() => {
(contextElement as any).manualRemoval = false;
contextElement.parentElement?.removeChild(contextElement);
$$$(contextElement, '.content').innerText = 'Revoke';
}, 2000);
return;
} finally {
revoking = false;
}
contextElement.parentElement?.removeChild(contextElement);
displayElement.parentElement?.removeChild(displayElement);
displayed -= 1;
if (displayed == 0) {
$$$(element, '.tokens').appendChild($.create({
class: 'empty', content: 'No outstanding tokens'
}));
}
});
$$$(element, '.tokens').appendChild(displayElement);
displayed += 1;
}
if (displayed == 0) {
$$$(element, '.tokens').appendChild($.create({
class: 'empty', content: 'No outstanding tokens'
}));
}
},
errorIndicatorAddFunc: async (errorIndicatorElement) => {
$.clearChildren($$$(element, '.tokens'));
$$$(element, '.tokens').appendChild(errorIndicatorElement);
},
errorContainer: $$$(element, '.tokens'),
errorMessage: 'Error fetching tokens'
});
})();
return element;
}