116 lines
2.7 KiB
TypeScript
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);
|
|
}
|
|
}
|