Files
backroad/app/portainer/services/notifications.ts

116 lines
2.7 KiB
TypeScript

import _ from 'lodash';
import toastr from 'toastr';
import sanitize from 'sanitize-html';
import { v4 as uuid } from 'uuid';
import { get as localStorageGet } from '@/react/hooks/useLocalStorage';
import { notificationsStore } from '@/react/portainer/notifications/notifications-store';
import { ToastNotification } from '@/react/portainer/notifications/types';
const { addNotification } = notificationsStore.getState();
toastr.options = {
timeOut: 3000,
closeButton: true,
progressBar: true,
tapToDismiss: false,
escapeHtml: true,
// custom button, using the lucide icon x.svg inside
closeHtml: `<button type="button"><svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg></button>`,
};
export function notifySuccess(title: string, text: string) {
saveNotification(title, text, 'success');
toastr.success(sanitize(_.escape(text)), sanitize(_.escape(title)));
}
export function notifyWarning(title: string, text: string) {
saveNotification(title, text, 'warning');
toastr.warning(sanitize(_.escape(text)), sanitize(title), { timeOut: 6000 });
}
export function notifyError(title: string, e?: unknown, fallbackText = '') {
const msg = pickErrorMsg(e) || fallbackText;
saveNotification(title, msg, 'error');
if (!_.get(e, 'resource.password')) {
// eslint-disable-next-line no-console
console.error(e);
}
if (msg !== 'Invalid JWT token') {
toastr.error(sanitize(_.escape(msg)), sanitize(title), { timeOut: 6000 });
}
}
export const success = notifySuccess;
export const error = notifyError;
export const warning = notifyWarning;
/* @ngInject */
export function Notifications() {
return {
success: notifySuccess,
warning: notifyWarning,
error: notifyError,
};
}
function pickErrorMsg(e?: unknown) {
if (!e) {
return '';
}
const props = [
'err.data.details',
'err.data.message',
'data.details',
'data.message',
'data.content',
'data.error',
'message',
'err.data[0].message',
'err.data.err',
'data.err',
'msg',
];
let msg = '';
props.forEach((prop) => {
const val = _.get(e, prop);
if (typeof val === 'string') {
msg = msg || val;
}
});
return msg;
}
function saveNotification(title: string, text: string, type: string) {
const notif: ToastNotification = {
id: uuid(),
title,
details: text,
type,
timeStamp: new Date(),
};
const userId = localStorageGet('USER_ID', '');
if (userId !== '') {
addNotification(userId, notif);
}
}