- added api UserController.ts for 2FA
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
- added PersonalTotpSettings.vue vor enablin/disabling 2FA - changed User.ts: added attributes: state, twoFactorSecret and twoFactorRecoveryCodes - added resources/js/utils/toast.ts for notifications - modified start/routes/api.ts - npm updates
This commit is contained in:
parent
18635f77b3
commit
ebc62d9117
18 changed files with 1151 additions and 315 deletions
3
resources/js/utils/Close.svg
Normal file
3
resources/js/utils/Close.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
|
||||
<path d="M14 12.3L12.3 14 8 9.7 3.7 14 2 12.3 6.3 8 2 3.7 3.7 2 8 6.3 12.3 2 14 3.7 9.7 8z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 170 B |
103
resources/js/utils/toast.css
Normal file
103
resources/js/utils/toast.css
Normal file
|
@ -0,0 +1,103 @@
|
|||
|
||||
/* remember to import this scss file into your app */
|
||||
.toastify.dialogs {
|
||||
min-width: 200px;
|
||||
background: none;
|
||||
background-color: var(--color-main-background);
|
||||
color: var(--color-main-text);
|
||||
box-shadow: 0 0 6px 0 var(--color-box-shadow);
|
||||
padding: 0 12px;
|
||||
margin-top: 45px;
|
||||
position: fixed;
|
||||
z-index: 10100;
|
||||
border-radius: var(--border-radius);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.toast-undo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toast-undo-button,
|
||||
.toast-close {
|
||||
position: static;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
min-width: 44px;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
white-space: nowrap;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: transparent;
|
||||
min-height: 0;
|
||||
|
||||
/* icon styling */
|
||||
&.toast-close {
|
||||
text-indent: 0;
|
||||
opacity: 0.4;
|
||||
border: none;
|
||||
min-height: 44px;
|
||||
margin-left: 10px;
|
||||
font-size: 0;
|
||||
|
||||
/* dark theme overrides for Nextcloud 25 and later */
|
||||
&::before {
|
||||
background-image: url('./Close.svg');
|
||||
content: ' ';
|
||||
filter: var(--background-invert-if-dark);
|
||||
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.toast-undo-button {
|
||||
/* $margin: 3px; */
|
||||
/* margin: $margin; */
|
||||
/* height: calc(100% - 2 * #{$margin}); */
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.toastify-top {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
/* Toast with onClick callback */
|
||||
&.toast-with-click {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Various toasts types */
|
||||
&.toast-error {
|
||||
border-left: 3px solid var(--color-error);
|
||||
}
|
||||
|
||||
&.toast-info {
|
||||
border-left: 3px solid var(--color-primary);
|
||||
}
|
||||
|
||||
&.toast-warning {
|
||||
border-left: 3px solid var(--color-warning);
|
||||
}
|
||||
|
||||
&.toast-success {
|
||||
border-left: 3px solid var(--color-success);
|
||||
}
|
||||
|
||||
&.toast-undo {
|
||||
border-left: 3px solid var(--color-success);
|
||||
}
|
||||
}
|
||||
|
||||
|
216
resources/js/utils/toast.ts
Normal file
216
resources/js/utils/toast.ts
Normal file
|
@ -0,0 +1,216 @@
|
|||
import Toastify from 'toastify-js';
|
||||
// import { t } from './utils/l10n.js';
|
||||
import './toast.css';
|
||||
|
||||
/**
|
||||
* Enum of available Toast types
|
||||
*/
|
||||
export enum ToastType {
|
||||
ERROR = 'toast-error',
|
||||
WARNING = 'toast-warning',
|
||||
INFO = 'toast-info',
|
||||
SUCCESS = 'toast-success',
|
||||
PERMANENT = 'toast-error',
|
||||
UNDO = 'toast-undo',
|
||||
}
|
||||
|
||||
/** @deprecated Use ToastAriaLive.OFF */
|
||||
export const TOAST_ARIA_LIVE_OFF = 'off';
|
||||
/** @deprecated Use ToastAriaLive.POLITE */
|
||||
export const TOAST_ARIA_LIVE_POLITE = 'polite';
|
||||
/** @deprecated Use ToastAriaLive.ASSERTIVE */
|
||||
export const TOAST_ARIA_LIVE_ASSERTIVE = 'assertive';
|
||||
|
||||
export enum ToastAriaLive {
|
||||
OFF = TOAST_ARIA_LIVE_OFF,
|
||||
POLITE = TOAST_ARIA_LIVE_POLITE,
|
||||
ASSERTIVE = TOAST_ARIA_LIVE_ASSERTIVE,
|
||||
}
|
||||
|
||||
/** Timeout in ms of a undo toast */
|
||||
export const TOAST_UNDO_TIMEOUT = 10000;
|
||||
/** Default timeout in ms of toasts */
|
||||
export const TOAST_DEFAULT_TIMEOUT = 4000;
|
||||
/** Timeout value to show a toast permanently */
|
||||
export const TOAST_PERMANENT_TIMEOUT = -1;
|
||||
|
||||
/**
|
||||
* Type of a toast
|
||||
* @see https://apvarun.github.io/toastify-js/
|
||||
* @notExported
|
||||
*/
|
||||
type Toast = ReturnType<typeof Toastify>;
|
||||
|
||||
export interface ToastOptions {
|
||||
/**
|
||||
* Defines the timeout in milliseconds after which the toast is closed. Set to -1 to have a persistent toast.
|
||||
*/
|
||||
timeout?: number;
|
||||
|
||||
/**
|
||||
* Set to true to allow HTML content inside of the toast text
|
||||
* @default false
|
||||
*/
|
||||
isHTML?: boolean;
|
||||
|
||||
/**
|
||||
* Set a type of {ToastType} to style the modal
|
||||
*/
|
||||
type?: ToastType;
|
||||
|
||||
/**
|
||||
* Provide a function that is called after the toast is removed
|
||||
*/
|
||||
onRemove?: () => void;
|
||||
|
||||
/**
|
||||
* Provide a function that is called when the toast is clicked
|
||||
*/
|
||||
onClick?: () => void;
|
||||
|
||||
/**
|
||||
* Make the toast closable
|
||||
*/
|
||||
close?: boolean;
|
||||
|
||||
/**
|
||||
* Specify the element to attach the toast element to (for testing)
|
||||
*/
|
||||
selector?: string;
|
||||
|
||||
/**
|
||||
* Whether the messages should be announced to screen readers.
|
||||
* See the following docs for an explanation when to use which:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
|
||||
*
|
||||
* By default, errors are announced assertive and other messages "polite".
|
||||
*/
|
||||
ariaLive?: ToastAriaLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast message
|
||||
*
|
||||
* @param data Message to be shown in the toast, any HTML is removed by default
|
||||
* @param options
|
||||
*/
|
||||
export function showMessage(data: string | Node, options?: ToastOptions): Toast {
|
||||
options = Object.assign(
|
||||
{
|
||||
timeout: TOAST_DEFAULT_TIMEOUT,
|
||||
isHTML: false,
|
||||
type: undefined,
|
||||
// An undefined selector defaults to the body element
|
||||
selector: undefined,
|
||||
onRemove: () => {},
|
||||
onClick: undefined,
|
||||
close: true,
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
if (typeof data === 'string' && !options.isHTML) {
|
||||
// fime mae sure that text is extracted
|
||||
const element = document.createElement('div');
|
||||
element.innerHTML = data;
|
||||
data = element.innerText;
|
||||
}
|
||||
let classes = options.type ?? '';
|
||||
|
||||
if (typeof options.onClick === 'function') {
|
||||
classes += ' toast-with-click ';
|
||||
}
|
||||
|
||||
const isNode = data instanceof Node;
|
||||
|
||||
let ariaLive: ToastAriaLive = ToastAriaLive.POLITE;
|
||||
if (options.ariaLive) {
|
||||
ariaLive = options.ariaLive;
|
||||
} else if (options.type === ToastType.ERROR || options.type === ToastType.UNDO) {
|
||||
ariaLive = ToastAriaLive.ASSERTIVE;
|
||||
}
|
||||
|
||||
const toast = Toastify({
|
||||
[!isNode ? 'text' : 'node']: data,
|
||||
duration: options.timeout,
|
||||
callback: options.onRemove,
|
||||
onClick: options.onClick,
|
||||
close: options.close,
|
||||
gravity: 'top',
|
||||
selector: options.selector,
|
||||
position: 'right',
|
||||
backgroundColor: '',
|
||||
className: 'dialogs ' + classes,
|
||||
escapeMarkup: !options.isHTML,
|
||||
ariaLive,
|
||||
});
|
||||
|
||||
toast.showToast();
|
||||
|
||||
return toast;
|
||||
}
|
||||
|
||||
export default {
|
||||
updatableNotification: null,
|
||||
|
||||
getDefaultNotificationFunction: null,
|
||||
|
||||
/**
|
||||
* Shows a notification that disappears after x seconds, default is
|
||||
* 7 seconds
|
||||
*
|
||||
* @param {string} text Message to show
|
||||
* @param {Array} [options] options array
|
||||
* @param {number} [options.timeout=7] timeout in seconds, if this is 0 it will show the message permanently
|
||||
* @param {boolean} [options.isHTML=false] an indicator for HTML notifications (true) or text (false)
|
||||
* @param {string} [options.type] notification type
|
||||
* @return {JQuery} the toast element
|
||||
*/
|
||||
showTemporary(text, options = { timeout: 3000 }) {
|
||||
options = options || {};
|
||||
options.timeout = options.timeout || TOAST_DEFAULT_TIMEOUT;
|
||||
const toast = showMessage(text, options);
|
||||
toast.toastElement.toastify = toast;
|
||||
// return $(toast.toastElement)
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a toast message with error styling
|
||||
*
|
||||
* @param text Message to be shown in the toast, any HTML is removed by default
|
||||
* @param options
|
||||
*/
|
||||
showError(text: string, options?: ToastOptions): Toast {
|
||||
return showMessage(text, { ...options, type: ToastType.ERROR });
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a toast message with warning styling
|
||||
*
|
||||
* @param text Message to be shown in the toast, any HTML is removed by default
|
||||
* @param options
|
||||
*/
|
||||
showWarning(text: string, options?: ToastOptions): Toast {
|
||||
return showMessage(text, { ...options, type: ToastType.WARNING });
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a toast message with info styling
|
||||
*
|
||||
* @param text Message to be shown in the toast, any HTML is removed by default
|
||||
* @param options
|
||||
*/
|
||||
showInfo(text: string, options?: ToastOptions): Toast {
|
||||
return showMessage(text, { ...options, type: ToastType.INFO });
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a toast message with success styling
|
||||
*
|
||||
* @param text Message to be shown in the toast, any HTML is removed by default
|
||||
* @param options
|
||||
*/
|
||||
showSuccess(text: string, options?: ToastOptions): Toast {
|
||||
return showMessage(text, { ...options, type: ToastType.SUCCESS });
|
||||
},
|
||||
};
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue