UNPKG

@etsoo/website

Version:

ETSOO CMS Based NextJs Website Framework

341 lines (340 loc) 14.2 kB
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); } } }