@etsoo/website
Version:
ETSOO CMS Based NextJs Website Framework
341 lines (340 loc) • 14.2 kB
JavaScript
import { Notification, NotificationAlign, NotificationType } from '@etsoo/notificationbase';
import { DomUtils } from '@etsoo/shared';
import { SiteUtils } from '../site/SiteUtils';
/**
* Notification Dom
*/
export class NotificationDom extends Notification {
createButton(color, value) {
const button = document.createElement('button');
button.className = `btn btn-${color} w-25`;
button.innerHTML = value;
return button;
}
// Create confirm
createConfirm(_props, className) {
var _a, _b;
// Destruct
const { type, title = SiteUtils.getLabel(NotificationType[type].toLowerCase(), '') } = this;
const { buttons = (_notification, callback) => {
const div = document.createElement('div');
if (cancelButton && type === NotificationType.Confirm) {
const cButton = this.createButton('secondary', cancelLabel);
cButton.name = 'cancelButton';
cButton.addEventListener('click', async (event) => {
SiteUtils.toggleButtonSpinner(cButton);
await callback(event, false);
SiteUtils.toggleButtonSpinner(cButton);
});
div.append(cButton);
}
const okButton = this.createButton('primary', okLabel);
okButton.name = 'okButton';
okButton.addEventListener('click', async (event) => {
SiteUtils.toggleButtonSpinner(okButton);
await callback(event, true);
SiteUtils.toggleButtonSpinner(okButton);
});
if (primaryButton)
Object.assign(okButton, primaryButton);
div.append(okButton);
return div;
}, okLabel = SiteUtils.getLabel('ok', 'OK'), cancelLabel = SiteUtils.getLabel('cancel', 'Cancel'), cancelButton = true, closable = true, inputs, primaryButton } = (_a = this.inputProps) !== null && _a !== void 0 ? _a : {};
const callback = async (_event, value) => {
await this.returnValue(value);
return true;
};
// Modal
const div = this.createModal(className);
div.innerHTML = `<div class="modal-dialog${this.getDialogStyle()}">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
${closable
? `<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>`
: ''}
</div>
<div class="modal-body"></div>
</div>
</div>`;
const titleE = div.querySelector('.modal-title');
this.createContent(titleE, title);
const bodyE = div.querySelector('.modal-body');
this.createContent(bodyE, this.content);
if (bodyE) {
if (inputs) {
inputs.classList.add('mt-3');
bodyE.append(inputs);
}
const buttonsE = buttons(this, callback);
buttonsE.classList.add('modal-footer');
(_b = bodyE.parentElement) === null || _b === void 0 ? void 0 : _b.append(buttonsE);
}
// Setup callback
this.doSetup(div);
return div;
}
getDialogStyle() {
var _a;
// Destruct
const align = this.align;
const { maxWidth = false, fullScreen } = (_a = this.inputProps) !== null && _a !== void 0 ? _a : {};
const classNames = [];
if (align === NotificationAlign.Center)
classNames.push('modal-dialog-centered');
if (maxWidth !== false)
classNames.push(`modal-${maxWidth}`);
if (fullScreen)
classNames.push('modal-fullscreen');
if (classNames.length === 0)
return '';
return ' ' + classNames.join(' ');
}
createContent(container, content) {
if (container == null || content == null)
return;
if (typeof content === 'string') {
container.innerHTML = content;
}
else {
container.append(content);
}
}
createModal(className) {
// Div
const div = document.createElement('div');
// data-bs-backdrop="static" data-bs-keyboard="false"
div.dataset.bsBackdrop = 'static';
div.dataset.bsKeyboard = 'false';
div.className = 'modal fad';
if (className)
div.classList.add(className);
return div;
}
doSetup(div) {
if (this.renderSetup)
this.renderSetup(div);
}
// Create loading
createLoading(_props, className) {
// Modal
const div = this.createModal(className);
// Content
let content = this.content;
if (content === '@')
content = SiteUtils.getLabel('loading', 'Loading...');
div.innerHTML = `<div class="modal-dialog${this.getDialogStyle()}">
<div class="modal-content d-flex justify-content-between flex-row align-items-center p-2">
<div class="spinner-border spinner-border-sm" role="status"></div>
<div class="spinner-title fs-6"></div>
</div>
</div>`;
const titleE = div.querySelector('.spinner-title');
this.createContent(titleE, content);
// Setup callback
this.doSetup(div);
return div;
}
createPrompt(_props, className) {
var _a, _b;
// Destruct
const { buttons = (_notification, callback) => {
const div = document.createElement('div');
if (cancelButton) {
const cButton = this.createButton('secondary', cancelLabel);
cButton.name = 'cancelButton';
cButton.addEventListener('click', async (event) => {
SiteUtils.toggleButtonSpinner(cButton);
if (this.onReturn)
await this.onReturn(undefined);
SiteUtils.toggleButtonSpinner(cButton);
this.dismiss();
});
div.append(cButton);
}
const okButton = this.createButton('primary', okLabel);
okButton.name = 'okButton';
okButton.addEventListener('click', async (event) => {
SiteUtils.toggleButtonSpinner(okButton);
await callback(event);
SiteUtils.toggleButtonSpinner(okButton);
});
if (primaryButton)
Object.assign(okButton, primaryButton);
div.append(okButton);
return div;
}, okLabel = SiteUtils.getLabel('ok', 'OK'), cancelLabel = SiteUtils.getLabel('cancel', 'Cancel'), cancelButton = true, inputs, primaryButton, type, inputProps } = (_a = this.inputProps) !== null && _a !== void 0 ? _a : {};
let input = null;
let errorDiv = null;
const setError = (error) => {
if (errorDiv)
errorDiv.innerHTML = error;
};
const handleSubmit = async (event) => {
// Form
const button = event.currentTarget;
if (button == null)
return false;
// Result
let result = undefined;
if (this.onReturn) {
// Inputs case, no HTMLForm set to value, set the current form
if (inputs) {
result = this.onReturn(button.form);
}
else if (input) {
if (type === 'switch') {
result = this.onReturn(input.checked);
}
else {
const inputValue = DomUtils.getInputValue(input);
if ((inputValue == null || inputValue === '') &&
input.required) {
input.focus();
return false;
}
result = this.onReturn(inputValue);
}
}
}
// Get the value
// returns false to prevent default dismiss
const v = await result;
if (v === false) {
input === null || input === void 0 ? void 0 : input.focus();
return false;
}
if (typeof v === 'string') {
setError(v);
input === null || input === void 0 ? void 0 : input.focus();
return false;
}
this.dismiss();
return true;
};
// Modal
const div = this.createModal(className);
div.innerHTML = `<form><div class="modal-dialog${this.getDialogStyle()}">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body"></div>
</div>
</div></form>`;
const form = div.querySelector('form');
form === null || form === void 0 ? void 0 : form.addEventListener('submit', (event) => {
var _a;
event.preventDefault();
(_a = form.elements.namedItem('okButton')) === null || _a === void 0 ? void 0 : _a.click();
return false;
});
const titleE = div.querySelector('.modal-title');
this.createContent(titleE, this.title);
const bodyE = div.querySelector('.modal-body');
this.createContent(bodyE, this.content);
if (bodyE) {
if (inputs) {
inputs.classList.add('mt-3');
bodyE.append(inputs);
}
else {
if (type === 'switch') {
const switchDiv = document.createElement('div');
switchDiv.className = 'form-check form-switch mt-3';
switchDiv.innerHTML = `<input class="form-check-input" type="checkbox" value="true" id="flexSwitchCheckDefault">`;
input = switchDiv.querySelector('input');
bodyE.append(switchDiv);
}
else if (type === 'slider') {
const sdiv = document.createElement('div');
sdiv.className =
'input-group input-group-sm align-items-center mt-3';
sdiv.innerHTML = `<input class="form-control form-range" type="range" oninput="this.nextSibling.innerHTML = this.value"><label class="input-group-text"></label></div>`;
const sInput = sdiv.querySelector('input');
if (sInput === null || sInput === void 0 ? void 0 : sInput.nextElementSibling)
sInput.nextElementSibling.innerHTML = sInput.value;
input = sInput;
bodyE.append(sdiv);
}
else {
const myInput = document.createElement('input');
myInput.type = type !== null && type !== void 0 ? type : 'text';
myInput.required = true;
myInput.className = 'form-control mt-3';
myInput.addEventListener('change', () => setError(''));
input = myInput;
bodyE.append(myInput);
}
if (input)
Object.assign(input, inputProps);
}
// Error display
errorDiv = document.createElement('div');
errorDiv.className = 'text-danger mt-3';
bodyE.append(errorDiv);
const buttonsE = buttons(this, handleSubmit);
buttonsE.classList.add('modal-footer');
(_b = bodyE.parentElement) === null || _b === void 0 ? void 0 : _b.append(buttonsE);
}
// Setup callback
this.doSetup(div);
return div;
}
getColor(type) {
return 'bg-' + NotificationType[type].toLocaleLowerCase();
}
createMessage(_props, className) {
// Destruct
const { type, content, title, inputProps = {} } = this;
const { closable = true } = inputProps;
// Div
const div = document.createElement('div');
div.className = 'toast';
if (type === NotificationType.Danger ||
type === NotificationType.Error ||
type === NotificationType.Warning) {
div.role = 'alert';
div.ariaLive = 'assertive';
}
else {
div.role = 'status';
div.ariaLive = 'polite';
}
div.innerHTML = `<div class="toast-header">
<div class="rounded me-2 ${this.getColor(type)}" style="width: 20px; height: 20px"></div>
<strong class="toast-title me-auto"></strong>
<small class="toast-tip"></small>
${closable
? `<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>`
: ''}
</div>
<div class="toast-body"></div>`;
const titleE = div.querySelector('.toast-title');
this.createContent(titleE, title);
const bodyE = div.querySelector('.toast-body');
this.createContent(bodyE, content);
// Setup callback
this.doSetup(div);
return div;
}
render(props, className) {
const type = this.type;
if (type === NotificationType.Loading) {
return this.createLoading(props, className);
}
else if (type === NotificationType.Confirm) {
return this.createConfirm(props, className);
}
else if (type === NotificationType.Prompt) {
return this.createPrompt(props, className);
}
else if (type === NotificationType.Error || this.modal) {
return this.createConfirm(props, className);
}
else {
return this.createMessage(props, className);
}
}
}