@reginaldo-marinho/rucula-js
Version:
Crie telas em Minutos! 🚀
1,319 lines (1,296 loc) • 128 kB
JavaScript
let cookie = (() => {
return {
read: function (name) {
var cookies = document.cookie.split('; ');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].split('=');
if (cookie[0] === name) {
return decodeURIComponent(cookie[1]);
}
}
return null;
}
};
})();
({
RESET_BACKGROUND: "reset-background",
RESET_BACKGROUND_EVENT: new Event("reset-background"),
BEFORE_SEND_OBJECT_HTTP: "before-send-object-http",
EVENT_BEFORE_SEND_OBJECT_HTTP: new Event("before-send-object-http"),
AFTER_SEND_OBJECT_HTTP: "after-send-object-http",
EVENT_AFTER_SEND_OBJECT_HTTP: new Event("after-send-object-http"),
SEND_OBJECT_HTTP_OK: "send-object-http-ok",
EVENT_SEND_OBJECT_HTTP_OK: new Event("send-object-http-ok"),
SEND_OBJECT_HTTP_ERROR: "send-object-http-error",
EVENT_SEND_OBJECT_HTTP_ERROR: new Event("send-object-http-error")
});
const constPrefixEventField = {
BEFORE: 'before',
INPUT: 'input',
AFTER: 'after',
};
const constTypeInput = {
TEXT: "text",
NUMBER: "number",
BOOLEAN: "bool",
DATE: "date",
CURRENCY: "currency",
SELECT: "select",
CHECKBOX: "checkbox",
TEXT_AREA: "textarea",
RADIO: "radio",
PASS: "password"
};
const constGroupFormat = {
DOWN: "down",
LEFT: "left",
RIGTH: "right"
};
const constTypeFrame = {
BLOCK: "block",
LINE: "line"
};
const constIdBaseWindow = {
NEW: "r-a-new",
CLOSE_GRID: "close-grid",
RELOAD: "r-a-reload",
ERASE_WINDOW: "erase-window",
ALTER_THEME: "alter-theme",
MAXIMIZE_WINDOW: "maximize-window",
MAXIMIZE_GRID: "maximize-grid",
ACTIONS_WINDOW: "r-actiond-window",
GLOBALIZATION: "r-globalization",
OLLI_GLOBALIZATION: "r-globalization-list",
ENVIROMENT: "r-enviroment",
OLLI_ENVIROMENT: "r-enviroment-list",
FORM_RUCULA_JS: "form-rucula-js",
BUTTONS_MENU_VERTICAL: "r-a-menu-vertical",
BUTTONS_MENU_VERTICAL_MOBILE: "r-a-menu-vertical-mobile",
BUTTON_MENU_VERTICAL_MOBILE_CLOSE: "r-a-mobile-close",
BUTTONS_MENU_VERTICAL_LIST: "r-a-menu-vertical-list",
TITLE: "r-window-title",
FAVORITE: "r-favorite",
CHAT: "r-chat",
USER: "r-user",
FRAME_INFO: "r-frame-INFO",
};
const contextMenu = {
INPUT: 'context-menu-input'
};
const constAttrInput = {
ATTR_TYPE: "ruc-type"
};
const constTargetButtonCrudDefault = {
SAVE: "r-a-save",
ALTER: "r-a-alter",
DELETE: "r-a-delete"
};
const constInputClass = {
FOCUS_IN_INPUT_WITH_DEPENDENCY: 'r-i-focus-dependency'
};
const constFrameLineActions = {
ADD: 'f-l-action-add',
REMOVE: 'f-l-action-remove'
};
const constYesNo = {
NO: false,
YES: true
};
const constPagination = {
ROW_NUMBER: "r-pagination-row-number",
FIND: "r-find",
FIRST: "r-pagination-first",
LAST: "r-pagination-last",
PREVIOUS: "r-pagination-previous",
NEXT: "r-pagination-next"
};
class WindowBaseDOM {
P;
ruculaWindow = document.createElement("div");
globalWindow;
constructor(prefix, config) {
this.P = prefix;
this.globalWindow = config.globalWindow;
if (config.type === 'header') {
config.openLeftGrid = false;
}
this.create(config);
}
create(config) {
config.type ??= 'crud';
this.cleanGlobalWindow();
this.ruculaWindow.classList.add("r-w");
this.ruculaWindow.classList.add(`${this.P}r-w`);
const actions = this.leftGrid(config.type);
this.ruculaWindow.appendChild(actions);
config.globalWindow?.appendChild(this.ruculaWindow);
this.createMold(config.type);
this.alterTheme();
this.eraseForm();
this.openActionswindow();
this.actionCrudpreventDefault();
this.widthAndHeigth();
this.maximizeForm();
this.openCloseForm();
this.closeLeftGrid(config.openLeftGrid);
this.createNameWindow(config.windowName);
this.userProfile();
this.message();
}
widthAndHeigth() {
let offsetTop = Number(this.ruculaWindow.offsetTop);
let height = Number(window.innerHeight);
this.ruculaWindow.style.height = `${height - offsetTop}px`;
}
createNameWindow(name) {
let window = this.ruculaWindow.querySelector(".r-w-t");
if (window) {
window.innerHTML = name;
}
}
cleanGlobalWindow() {
for (let index = 0; index < this.globalWindow.childNodes.length; index++) {
this.globalWindow.childNodes[index].remove();
}
}
openCloseForm() {
let rNew = this.ruculaWindow.querySelector(`#${this.P}${constIdBaseWindow.NEW}`);
let itemContainer = document.querySelectorAll(`.${this.P}js-open-close-container`);
rNew.addEventListener("click", () => {
itemContainer.forEach(item => {
item.classList.toggle("r-display-none");
indicateBoxFrameOpend(rNew, item);
});
function indicateBoxFrameOpend(rNew, item) {
var isBoxFrame = item.classList.contains("box-frame");
var isBoxFrameOpened = item.classList.contains("r-display-none");
if (isBoxFrame && isBoxFrameOpened == false) {
rNew.classList.add("r-box-frame-opened");
}
if (isBoxFrame && isBoxFrameOpened) {
rNew.classList.remove("r-box-frame-opened");
}
}
});
let rCloseGrid = this.ruculaWindow.querySelector(`#${this.P}${constIdBaseWindow.CLOSE_GRID}`);
rCloseGrid?.addEventListener("click", () => {
let div = document.querySelector(`.${this.P}r-f`);
div.classList.toggle('r-mobile');
let leftGrid = document.getElementById(`${this.P}r-left-block`);
leftGrid.classList.toggle('r-display-block');
});
}
leftGrid(type) {
const actions = document.createElement("div");
actions.className = "r-left-block";
actions.id = `${this.P}r-left-block`;
const ACTIONS = `
<div class="r-box-show" id="${this.P}r-box-show">
</div>
<div class="r-act" id="${this.P}actions">
<div class="r-act-opt r-head" id="${this.P}w-title">
<button id="${this.P}${constIdBaseWindow.NEW}" class="r-a-b r-btn-new-cancel-close r-desktop-web"><i class="bi bi-plus-lg"></i></button>
<button id="${this.P}${constIdBaseWindow.CLOSE_GRID}" class="r-a-b r-btn-new-cancel-close r-mobile"><i class="bi bi-x-lg"></i></button>
<div class="r-w-t">
</div>
<button id="${this.P}r-a-many" class="r-a-b"><i class="bi bi-list"></i></button>
</div>
${type == 'crud' ? this.grid() : ''}
</div>`;
actions.innerHTML = ACTIONS;
return actions.cloneNode(true);
}
grid() {
return `
<div class="r-left-block-grid" id="${this.P}w-grid">
<form class="searh-items-grid" id="${this.P}${constPagination.FIND}" autocomplete=off>
<input name="r-find-value" type="text"/>
<button><i class="bi bi-search"></i></button>
</form>
<div class="r-act-grid-body">
</div>
<div class="r-act-grid-footer" id="${this.P}r-act-grid-footer">
<div>
<span>N. Linha</span>
<select id="${this.P}${constPagination.ROW_NUMBER}" name="len-page">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="1000">1000</option>
</select>
</div>
<div>
<button id="${this.P}${constPagination.FIRST}" class="r-a-b"><i class="bi bi-arrow-up"></i></button>
<button id="${this.P}${constPagination.LAST}" class="r-a-b"><i class="bi bi-arrow-down"></i></button>
<button id="${this.P}${constPagination.PREVIOUS}" class="r-a-b"><i class="bi bi-arrow-left"></i></button>
<button id="${this.P}${constPagination.NEXT}" class="r-a-b"><i class="bi bi-arrow-right"></i></button>
</div>
</div>
</div>`;
}
createMold(type) {
var body = '';
switch (type) {
case 'crud':
body = this.bodyForm();
break;
case 'grid':
body = this.grid();
break;
case 'header':
body = '';
break;
default:
body = this.bodyForm();
break;
}
const contentForm = document.createElement("div");
const CREATE_OR_EDIT = `<div class="container-r-f box-home ${this.P}js-open-close-container">
<div class="r-act-opt r-head" id="${this.P}w-title">
</div>
<div class="r-f-items r-f-home">
<div class="r-f-home-round">
<i id="${this.P}r-f-home-icon"class="bi" ></i>
</div>
<h3 id="${this.P}r-f-home-title"></h3>
</div>
</div>
<div class="${this.P}r-f container-r-f box-frame r-display-none ${this.P}js-open-close-container">
<div class="r-facede-action top">
<div class="r-head r-read-new r-facede-action top">
<div style="z-index: 10;">
<button id="${this.P}${constIdBaseWindow.ACTIONS_WINDOW}" class="r-a-b r-actions-window"><i class="bi bi-nut"></i></button>
<div class="r-display-inline-block r-actions-window r-actions-window-itens">
<div class="r-display-inline-block">
<button id="${this.P}${constIdBaseWindow.MAXIMIZE_WINDOW}" class="r-a-b open-box-frame"><i class="bi bi-arrows"></i></button>
<button id="${this.P}${constIdBaseWindow.MAXIMIZE_GRID}" class="r-a-b open-grid r-mobile"><i class="bi bi-grid-3x3-gap-fill"></i></button>
<button id="${this.P}${constIdBaseWindow.ALTER_THEME}" class="r-a-b "><i class="bi bi-circle-half"></i></button>
</div>
<div class="actions-view">
<button id="${this.P}${constIdBaseWindow.GLOBALIZATION}" class="r-a-b">
<i class="bi bi-globe-americas"></i>
<ol id="${this.P}${constIdBaseWindow.OLLI_GLOBALIZATION}" class="${constIdBaseWindow.OLLI_GLOBALIZATION} list-vertical-buttons list-vertical-buttons-pp-left r-display-none">
</ol>
</button>
<button id="${this.P}${constIdBaseWindow.ENVIROMENT}" class="r-a-b">
<div class="desc-environment"><i class="bi bi-fire"></i> <span class="description"></span> </div>
<ol id="${this.P}${constIdBaseWindow.OLLI_ENVIROMENT}" class="${constIdBaseWindow.OLLI_ENVIROMENT} list-vertical-buttons list-vertical-buttons-pp-left r-display-none">
</ol>
</button>
</div>
</div>
</div>
<div class="r-display-inline-block">
<button id="${this.P}${constIdBaseWindow.CHAT}" class="r-a-b"><i class="bi bi-chat-dots"></i></button>
<button id="${this.P}${constIdBaseWindow.USER}" class="r-a-b"><i class="bi bi-person-circle"></i></button>
</div>
</div>
</div>
<div class="r-w-body">
${body}
</div>
<div class="r-facede-action bottom">
</div>
</div>
`;
contentForm.innerHTML = CREATE_OR_EDIT;
this.ruculaWindow.appendChild(contentForm.childNodes[0]);
this.ruculaWindow.appendChild(contentForm.childNodes[1]);
}
bodyForm() {
return `<form class="r-window-work" autocomplete="off">
<div class="r-head r-read-edit r-facede-action-crud" id="${this.P}r-facede-action-crud">
<h3 id="${this.P}${constIdBaseWindow.FRAME_INFO}">
</h3>
<div id="${this.P}action-crud">
<button id="${this.P}r-a-save" class="r-a-b r-a-b-disable managed"><i class="bi bi-box-arrow-in-down"></i></button>
<button id="${this.P}r-a-alter" class="r-a-b r-a-b-disable managed"><i class="bi bi-pen"></i></button>
<button id="${this.P}r-a-delete" class="r-a-b r-a-b-disable managed"><i class="bi bi-trash"></i></button>
<button id="${this.P}r-a-reload" class="r-a-b r-a-b-disable"><i class="bi bi-arrow-repeat"></i></button>
<button id="${this.P}erase-window" class="r-a-b"><i class="bi bi-eraser"></i></button>
<button id="${this.P}r-a-menu-vertical" class="r-a-b r-desktop-web"><i class="bi bi-arrows"></i></button>
<button id="${this.P}r-a-menu-vertical-mobile" class="r-a-b r-mobile"><i class="bi bi-arrows"></i></button>
</div>
</div>
<div class="r-f-work r-f-items" id="${this.P}${constIdBaseWindow.FORM_RUCULA_JS}">
</div>
</form>
<div class="r-vertical-actions">
<ol id=${this.P}${constIdBaseWindow.BUTTONS_MENU_VERTICAL_LIST} class="">
<li class="r-display-none r-mobile" id="${this.P}${constIdBaseWindow.BUTTON_MENU_VERTICAL_MOBILE_CLOSE}">
<button class="r-b-i" type="button"><i class="bi bi-x-lg"> </i></button>
</li>
</ol>
</div>`;
}
closeLeftGrid(grid) {
if (grid == false) {
let rf = this.globalWindow.querySelector(`.${this.P}r-f.r-display-none`);
if (rf != null) {
let buttonNew = this.globalWindow.querySelector(`#${this.P}${constIdBaseWindow.NEW}`);
buttonNew.click();
}
let actions = this.globalWindow.querySelector(`#${this.P}actions`);
actions?.remove();
let maximizeWindow = this.globalWindow.querySelector(`#${this.P}${constIdBaseWindow.MAXIMIZE_WINDOW}`);
maximizeWindow?.remove();
}
}
maximizeForm() {
let buttonMaximizeWindow = document.getElementById(`${this.P}${constIdBaseWindow.MAXIMIZE_WINDOW}`);
buttonMaximizeWindow?.addEventListener('click', () => {
let actions = document.getElementById(`${this.P}actions`);
actions?.classList.toggle("r-close-grid");
});
let buttonMaximizeGrid = document.getElementById(`${this.P}${constIdBaseWindow.MAXIMIZE_GRID}`);
buttonMaximizeGrid?.addEventListener('click', () => {
let actions = document.getElementById(`${this.P}r-left-block`);
actions?.classList.toggle("r-display-block");
let formFrames = document.querySelector(`.${this.P}r-f`);
formFrames.classList.toggle("r-mobile");
});
}
eraseForm() {
const eraseWindow = `${this.P}${constIdBaseWindow.ERASE_WINDOW}`;
let evt = new Event(eraseWindow);
document.getElementById(eraseWindow)?.addEventListener('click', () => {
this.globalWindow.dispatchEvent(evt);
});
}
actionCrudpreventDefault() {
let facedeActionCrud = document.getElementById(`${this.P}r-facede-action-crud`);
facedeActionCrud?.addEventListener('click', (e) => e.preventDefault());
}
openActionswindow() {
let actions = document.getElementById(`${this.P}${constIdBaseWindow.ACTIONS_WINDOW}`);
actions?.addEventListener('click', (e) => {
actions?.nextElementSibling?.classList.toggle('r-actions-window-active');
actions?.nextElementSibling?.classList.toggle('r-actions-window');
});
}
alterTheme() {
let rw = document.querySelector(`.${this.P}r-w`);
let actions = document.getElementById(`${this.P}${constIdBaseWindow.ALTER_THEME}`);
let theme = cookie.read('theme');
if (theme == 'dark') {
rw?.classList.add('dark-theme');
}
actions?.addEventListener('click', (e) => {
rw?.classList.toggle('dark-theme');
if (rw?.classList.contains('dark-theme')) {
document.cookie = "theme=dark";
}
else {
document.cookie = "theme=light";
}
});
}
userProfile() {
const user = `${this.P}${constIdBaseWindow.USER}`;
let evt = new Event(user);
document.getElementById(user)?.addEventListener('click', () => {
this.globalWindow.dispatchEvent(evt);
});
}
message() {
const chat = `${this.P}${constIdBaseWindow.CHAT}`;
let evt = new Event(chat);
document.getElementById(chat)?.addEventListener('click', () => {
this.globalWindow.dispatchEvent(evt);
});
}
getPrincipalElementRucula() {
return document.getElementById(`${this.P}${constIdBaseWindow.FORM_RUCULA_JS}`);
}
}
let ruculaGlobal = (() => {
let configuration;
function checkLocalizations(localizations) {
if (localizations.length == 0) {
throw new Error("🌿 localization must be informed");
}
}
function checkEnvironments(environments) {
if (environments.length == 0) {
alert('não há ambientes no momento');
throw new Error("🌿 environment must be informed");
}
}
return {
initGlobalConfiguration: function (config) {
configuration = config;
ruculaGlobal.setEnviroment();
ruculaGlobal.setLocalization();
},
setLocalization: function (locales = 0) {
checkLocalizations(configuration.localizations);
if (typeof locales === "number") {
configuration.chosenLocalization = configuration.localizations[0];
return;
}
let loc = configuration.localizations.find(c => c.locales === locales);
if (loc == undefined || loc == null) {
throw new Error("🌿 localization not found");
}
configuration.chosenLocalization = loc;
},
setEnviroment: function (enviroment = 0) {
checkEnvironments(configuration.environments);
if (typeof enviroment === "number") {
configuration.chosenEnvironment = configuration.environments[0];
return;
}
let env = configuration.environments.find(c => c.env === enviroment);
if (env == undefined || env == null) {
var manualEnviroment = prompt('Ambiente não existe, considere outras alternativas!', configuration.environments[0].env);
if (manualEnviroment == null) {
throw new Error("🌿 environment not found");
}
ruculaGlobal.setEnviroment(manualEnviroment);
}
configuration.chosenEnvironment = env;
},
getEnvironment: function () {
return configuration.chosenEnvironment;
},
getLocalization: function () {
return configuration.chosenLocalization;
},
getConfigurationGlobal: function () {
return configuration;
}
};
})();
class URLRucula {
_URL;
managmentObject;
constructor(managmentObject, URL = {}) {
if (URL.absolute == null)
URL.absolute = '';
if (URL.relative == null)
URL.relative = '';
if (URL.params == null)
URL.params = '';
this._URL = URL;
this.managmentObject = managmentObject;
}
getURL() {
let url = '';
if (this._URL == undefined) {
return this.domain();
}
if (this._URL.absolute.length > 0) {
url = this.path(this._URL.absolute);
}
else {
url = this.domain();
}
if (this._URL.relative.length > 0) {
let path = this.path(this._URL.relative);
url = `${url}/${path}`;
}
let params = '';
if (this._URL.params.length > 0) {
params = this.path(this._URL.params);
url = `${url}?${params}`;
return url;
}
if (url == '') {
return this.domain();
}
return url;
}
domain() {
let enviroment = ruculaGlobal.getEnvironment();
if (enviroment.port) {
return `${enviroment.hostname}:${enviroment.port}`;
}
return `${enviroment.hostname}`;
}
path(path) {
path = this.createWithParams(path);
path = this.createWithoutParams(path);
return path;
}
createWithParams(path) {
var regex = /([^&]+=)({([^}&]+)})/g;
var matches = path.matchAll(regex);
for (const match of matches) {
var propertValue = match[3];
var value = this.managmentObject?.getPropert(propertValue);
path = path.replace(match[0], `${match[1]}${value}`);
}
return path;
}
createWithoutParams(path) {
var regex = /\/{([^}&]+)}/gm;
var matches = path.matchAll(regex);
for (const match of matches) {
var propertValue = match[1];
var value = this.managmentObject?.getPropert(propertValue);
path = path.replace(match[0], `/${value}`);
}
return path;
}
}
class EventButton {
field;
managmentObject;
P;
constructor(field, managmentObject, P) {
this.field = field;
this.managmentObject = managmentObject;
this.P = P;
}
eventButton(ruculaForm, pathController, buttons) {
let rucula = ruculaForm;
buttons?.filter(b => b.type === "button")
.forEach((button) => {
let element = document?.getElementById(`${this.P}${button.target}`);
let object = {
detail: {
url: '',
body: {}
}
};
let dependency = {
detail: {}
};
let eventButton = new CustomEvent(`${this.P}${button.target}`, object);
let eventButtonDependency = new CustomEvent(`${this.P}${button.target}.dependency`, dependency);
element?.addEventListener("click", () => {
if (button.URL) {
let url = new URLRucula(this.managmentObject, button.URL);
object.detail.url = url.getURL();
}
let optionObjectReturn = button?.body;
let defaultsButton = [
this.P + constTargetButtonCrudDefault.SAVE,
this.P + constTargetButtonCrudDefault.ALTER,
this.P + constTargetButtonCrudDefault.DELETE,
];
if (optionObjectReturn == undefined && defaultsButton.indexOf(button.target) > -1) {
rucula.dispatchEvent(eventButton);
return;
}
let dependencyCount = this.managmentObject.tableDependency.dependenciesCount();
if (dependencyCount > 0) {
this.field.focusFieldsWithDependency();
rucula.dispatchEvent(eventButtonDependency);
return;
}
if (optionObjectReturn === '') {
object.detail.body = this.managmentObject.objectSeparate();
}
if (optionObjectReturn === '.') {
object.detail.body = this.managmentObject.objectFull();
}
if (optionObjectReturn && String(optionObjectReturn).length > 1) {
object.detail.body = this.managmentObject.objectUnique(optionObjectReturn);
}
rucula.dispatchEvent(eventButton);
});
});
}
openCloseRightListButtonsActions() {
const buttonOpenClose = document.getElementById(`${this.P}r-a-menu-vertical`);
const buttonMobileClose = document.getElementById(`${this.P}${constIdBaseWindow.BUTTON_MENU_VERTICAL_MOBILE_CLOSE}`);
const buttonOpenClosemobile = document.getElementById(`${this.P}${constIdBaseWindow.BUTTONS_MENU_VERTICAL_MOBILE}`);
const divRightListButtonsActions = document.querySelector(`.r-vertical-actions`);
buttonOpenClose?.addEventListener("click", () => {
divRightListButtonsActions?.classList.toggle("r-display-none");
});
buttonOpenClosemobile?.addEventListener("click", () => {
divRightListButtonsActions?.classList.toggle("r-display-block");
});
buttonMobileClose?.addEventListener("click", () => {
divRightListButtonsActions?.classList.toggle("r-display-block");
});
}
}
let configWindow = (() => {
let windows = new Map();
return {
set: (window, P) => {
let mappedwindow = windows.get(P);
if (mappedwindow) {
return;
}
windows.set(P, window);
},
get: (P) => {
return windows.get(P);
},
frame: {
get: (identity, P) => {
let window = windows.get(P);
let frame = window.frames.find(c => c.identity == identity);
return frame;
}
}
};
})();
let defaultValues = (() => {
const configFrameDefault = {
TYPE_FRAME: constTypeFrame.BLOCK,
VERTICAL: true,
REQUERID: true
};
const configInputDefault = {
TYPE: constTypeInput.TEXT,
REQUERID_TRUE: true,
REQUERID_FALSE: false,
DISABLE: false
};
function setDefaultFrame(frame) {
frame.type ??= configFrameDefault.TYPE_FRAME;
frame.vertical ??= configFrameDefault.VERTICAL;
frame.requerid ??= configFrameDefault.REQUERID;
}
function setDefaultInput(field) {
field.type ??= configInputDefault.TYPE;
field.disable ??= configInputDefault.DISABLE;
field.requerid ??= configInputDefault.REQUERID_FALSE;
}
return {
setDefault: (window) => {
if (!window) {
return;
}
window.grid ??= true;
window.gridFooter ??= true;
window.gridSearch ??= true;
window.frames.forEach(frame => {
setDefaultFrame(frame);
frame.fields?.forEach(field => {
setDefaultInput(field);
});
});
}
};
})();
class LayoutFrame {
P;
constructor(P) {
this.P = P;
}
configureLayout(window, principalElementRucula) {
if (window.layout.items === undefined) {
return;
}
let rowLength = window.layout.items.length;
let colLength = window.layout.items[0].length;
window.layout.tamplateColumns = colLength;
window.layout.tamplateRow = rowLength;
var tamplateColumns = window.layout.tamplateColumns;
principalElementRucula.style.gridTemplateColumns = `repeat(${tamplateColumns},1fr)`;
principalElementRucula.style.gridTemplateRows = 'max-content';
for (let row = 1; row <= rowLength; row++) {
for (let col = 1; col <= colLength; col++) {
let item = window.frames.find(c => c.alias == window.layout.items[row - 1][col - 1]);
if (item == undefined) {
continue;
}
if (item.layout === undefined) {
item.layout = { row: { start: -1, end: -1 }, col: { start: -1, end: -1 } };
}
if (item.layout.row.start === -1) {
item.layout.row.start = row;
}
if (item.layout.col.start === -1) {
item.layout.col.start = col;
}
item.layout.row.end = row + 1;
item.layout.col.end = col + 1;
}
}
}
}
class DOMButtonsCheck {
buttonCreate;
buttonAlter;
buttonDelete;
buttonsPlus;
olButtonsPlus;
P;
crud;
constructor(P, crud) {
this.P = P;
this.crud = crud;
}
buttonCrudDefault() {
this.buttonCreate = document.getElementById(`${this.P}${constTargetButtonCrudDefault.SAVE}`);
this.buttonAlter = document.getElementById(`${this.P}${constTargetButtonCrudDefault.ALTER}`);
this.buttonDelete = document.getElementById(`${this.P}${constTargetButtonCrudDefault.DELETE}`);
}
SpecificRightButtons() {
this.buttonsPlus = document.getElementById(`${this.P}${constIdBaseWindow.BUTTONS_MENU_VERTICAL}`);
this.olButtonsPlus = document.getElementById(`${this.P}${constIdBaseWindow.BUTTONS_MENU_VERTICAL_LIST}`);
if (this.olButtonsPlus.querySelectorAll("button,a").length == 0) {
this.buttonsPlus.remove();
this.olButtonsPlus.remove();
}
}
clickCreate() {
this.buttonCreate.click();
}
clickAlter() {
this.buttonAlter.click();
}
clickDelete() {
this.buttonDelete.click();
}
removeCreate() {
this.buttonCreate.remove();
}
removeAlter() {
this.buttonAlter.remove();
}
removeDelete() {
this.buttonDelete.remove();
}
removeUnusedButtons() {
this.buttonCrudDefault();
this.SpecificRightButtons();
if (this.crud == "" || this.crud == undefined) {
this.buttonCreate.remove();
this.buttonAlter.remove();
this.buttonDelete.remove();
return;
}
let options = "crud";
for (let index = 0; index < this.crud.length; index++) {
let indexof = options.indexOf(this.crud[index]);
options = options.replace(options[indexof], "");
}
if (options.length < 1 || (options.length == 1 && options[0] == "r")) {
return;
}
for (let index = 0; index < options.length; index++) {
if (options[index] == "c") {
this.buttonCreate.remove();
}
if (options[index] == "u") {
this.buttonAlter.remove();
}
if (options[index] == "d") {
this.buttonDelete.remove();
}
}
}
}
class LoaderManagment {
loaderBkp = document.createElement('div');
loaderElement = document.createElement('div');
boxShow;
P;
constructor(P) {
this.P = P;
this.loaderElement.classList.add('r-loader');
this.loaderElement.classList.add(`${this.P}js-r-loader`);
this.loaderElement.classList.add('r-item-center');
}
enable() {
this.boxShow = document.getElementById(`${this.P}r-box-show`);
this.boxShow?.classList.add('r-box-show-center');
this.boxShow?.appendChild(this.loaderElement);
}
disable() {
let loader = document.querySelector(`.${this.P}js-r-loader`);
this.loaderBkp.appendChild(loader);
this.boxShow?.classList.remove('r-box-show-center');
}
}
class Popup {
prefix;
constructor(prefix) {
this.prefix = prefix;
}
boxShow;
boxShowAppendChield(element) {
this.boxShow = document.getElementById(`${this.prefix}r-box-show`);
this.boxShow?.appendChild(element);
this.boxShow?.classList.add('r-box-show-center');
}
messageElement(config) {
let message = document.createElement('div');
message.classList.add('r-message');
message.innerHTML = `
<div class="r-message-header">
<div class="r-message-header-icon">
<i class="bi ${config.icon}"></i>
</div>
<div class="r-message-header-title">
${config.title}
</div>
</div>
<div class="r-message-content">
<div class="r-message-content-text">
${config.text}
</div>
</div>
<div class="r-message-footer">
${config.footer}
</div>`;
if (config?.disableadHeader) {
let header = message.querySelector('.r-message-header');
header?.remove();
}
if (config?.disableadFooter) {
let footer = message.querySelector('.r-message-footer');
footer?.remove();
}
if (config?.htmlBody) {
let messageContent = message.querySelector('.r-message-content');
messageContent?.appendChild(config?.htmlBody);
}
return message;
}
closeTimeout(div, timeout, callback) {
setTimeout(() => {
div.remove();
this.close();
if (callback) {
callback();
}
}, timeout);
}
closeOKOrCancel(callback, div, callbackInTimeout = false) {
if (callbackInTimeout) {
callback(constYesNo.NO);
}
let ok = div.querySelector('button.ok');
let cancel = div.querySelector('button.cancel');
ok?.addEventListener('click', () => {
div.remove();
this.close();
if (callback) {
callback(constYesNo.YES);
}
});
cancel?.addEventListener('click', () => {
div.remove();
this.close();
if (callback) {
callback(constYesNo.NO);
}
});
}
close() {
this.boxShow.classList.remove('r-box-show-center');
}
info(config, callback) {
let info = this.messageElement({
icon: "bi-info-circle color-darkgrey",
title: "Informação",
text: config.text,
footer: `<div class="r-message-footer">
<div class="cancel-ok">
<button class="ok">OK</button>
</div>
</div>`,
disableadFooter: config.disableadFooter,
disableadHeader: config.disableadHeader,
htmlBody: config.htmlBody
});
if (config?.timeout) {
this.closeTimeout(info, config.timeout, callback);
}
this.closeOKOrCancel(callback, info);
this.boxShowAppendChield(info);
}
sucess(config, callback) {
let sucess = this.messageElement({
icon: "bi-check2-circle color-green",
title: "Sucesso",
text: config.text,
footer: `<div class="r-message-footer">
<div class="cancel-ok">
<button class="ok">OK</button>
</div>
</div>`,
disableadFooter: config.disableadFooter
});
this.closeOKOrCancel(callback, sucess);
if (config.timeout) {
this.closeTimeout(sucess, config.timeout);
}
this.boxShowAppendChield(sucess);
}
warning(config, callback) {
let warning = this.messageElement({
icon: "bi-exclamation-triangle color-orange",
title: "Atenção",
text: config.text,
footer: `<div class="r-message-footer">
<div class="cancel-ok">
<button class="ok">OK</button>
<button class="cancel">Cancel</button>
</div>
</div>`,
disableadFooter: config.disableadFooter
});
this.closeOKOrCancel(callback, warning);
if (config.timeout) {
this.closeTimeout(warning, config.timeout);
}
this.boxShowAppendChield(warning);
}
error(config, callback) {
let warning = this.messageElement({
icon: "bi-x-circle color-red",
title: "Erro",
text: config.text,
footer: `<div class="r-message-footer">
<div class="cancel-ok">
<button class="ok">OK</button>
</div>
</div>`,
disableadFooter: config.disableadFooter
});
this.closeOKOrCancel(callback, warning);
if (config.timeout) {
this.closeTimeout(warning, config.timeout);
}
this.boxShowAppendChield(warning);
}
}
class RuculaLogs {
managmentObject;
constructor(managmentObject) {
this.managmentObject = managmentObject;
}
dependencies() {
return this.managmentObject.tableDependency.getDependenciesNotResolded();
}
object() {
return this.managmentObject.objectFull();
}
}
class EventManagment {
managmentObject;
p;
elementRoot;
constructor(p, managmentObject, elementRoot) {
this.p = p;
this.managmentObject = managmentObject;
this.elementRoot = elementRoot;
}
getFieldDetails(event) {
let identity = event.detail.identity;
return {
identity: identity.element.getAttribute('identity'),
name: identity.name,
row: identity.row,
value: this.managmentObject.getPropert(identity.name),
targetPathWithRow: (targetPath) => {
return `${targetPath}.${identity.row}`;
}
};
}
on(event, callback, query) {
let rucula = this.elementRoot;
if (query == undefined) {
rucula.addEventListener(`${this.p}${event}`, (e) => callback(e));
return;
}
let itens = rucula.querySelectorAll(query);
itens.forEach((item) => {
item.addEventListener(event, (e) => callback(e));
});
}
}
class FrameElement {
managmentObject;
field;
frameEvent;
button;
fieldMenuContext;
inputValueSnapshot = [];
constructor(managmentObject, field, frameEvent, button, fieldMenuContext) {
this.managmentObject = managmentObject;
this.field = field;
this.frameEvent = frameEvent;
this.button = button;
this.fieldMenuContext = fieldMenuContext;
}
createbase(frame) {
const div = document.createElement('div');
div.style.gridColumnStart = `${frame.layout.col.start}`;
div.style.gridColumnEnd = `${frame.layout.col.end}`;
div.style.gridRowStart = `${frame.layout.row.start}`;
div.style.gridRowEnd = `${frame.layout.row.end}`;
if (frame.type == constTypeFrame.BLOCK) {
div.classList.add("r-q-b");
}
if (frame.type == constTypeFrame.LINE) {
div.classList.add('r-q-l');
}
div.setAttribute('identity', frame.identity);
const h3 = document.createElement('h3');
h3.textContent = frame.name;
h3.classList.add('r-t-f');
div.appendChild(h3);
if (frame?.style?.width)
div.style.width = frame.style.width;
if (frame?.style?.height)
div.style.height = frame.style.height;
return div;
}
setValuesDefined(frame, htmlElement) {
frame.fields?.forEach(field => {
let input = htmlElement.querySelector(field.identity);
if (input) {
this.managmentObject.setValueContextIdentity(field.identity, field.type, input.value);
}
});
}
revertToInit() {
for (let index = 0; index < this.inputValueSnapshot.length; index++) {
this.inputValueSnapshot[index].element.value = this.inputValueSnapshot[index].value;
}
}
}
class FrameElementBlock extends FrameElement {
constructor(managmentObject, field, frameEvent, button, fieldMenuContext) {
super(managmentObject, field, frameEvent, button, fieldMenuContext);
}
create(frame) {
const frameElement = this.createbase(frame);
const div = document.createElement("div");
div.classList.add("r-q-i");
if (frame.vertical) {
div.style.flexDirection = "column";
}
frame.fields?.forEach(field => {
if (field?.button) {
let buttonElement = this.button.createButtonOrLink(field.button);
let groupElement = this.field.createGroupOfButton(buttonElement);
div.appendChild(groupElement);
return;
}
let fieldElement = this.field.create(field);
let groupElement = this.field.createGroupOfInput(field, fieldElement);
div.appendChild(groupElement);
this.fieldMenuContext.infoSet({
identity: field.identity,
field: field
});
this.inputValueSnapshot.push({
element: fieldElement,
value: fieldElement.value
});
});
this.setValuesDefined(frame, div);
frameElement.appendChild(div);
if (frame.requerid == false) {
this.managmentObject.tableDependency.moveNotResolvedToImbernate(frame.alias);
this.frameEvent.managedFrame(div);
this.frameEvent.cleanRequeridDependency(div);
}
return frameElement;
}
}
let keyEvent = new Array();
function KeyEventClear() {
keyEvent = [];
}
function KeyEventAdd(key) {
if (keyEvent.filter(c => c == key).length == 0) {
keyEvent.push(key);
}
keyEvent.sort();
}
function KeyEventGetIndex(index) {
return keyEvent[index];
}
function convertValueType(value, type) {
type = GetType(type);
if (isBoolean()) {
return convertToBoolean();
}
if (isNumeric()) {
return convertToNumeric();
}
return value;
function isNumeric() {
return type == constTypeInput.CURRENCY ||
type == constTypeInput.NUMBER;
}
function isBoolean() {
return type == constTypeInput.BOOLEAN;
}
function convertToNumeric() {
return Number(value);
}
function convertToBoolean() {
if (value == "true") {
return true;
}
else {
return false;
}
}
function GetType(type) {
if (type.length == 2) {
return type[1];
}
return type;
}
}
function alignItem(field, item) {
if (field.type == constTypeInput.TEXT || field.type == undefined || field.type[0] == constTypeInput.SELECT) {
item.classList.add('r-t-align-left');
}
if (field.type == constTypeInput.NUMBER || field.type == constTypeInput.CURRENCY) {
item.classList.add('r-t-align-right');
}
if (field.type[0] == constTypeInput.CHECKBOX) {
item.classList.add('r-t-align-center');
}
}
class FameLineTable {
managmentObject;
field;
frameEvent;
frameElementLine;
callbackSetValuesDefined;
fieldMenuContext;
P;
constructor(managmentObject, field, frameElementLine, frameEvent, callbackSetValuesDefined, fieldMenuContext, P) {
this.managmentObject = managmentObject;
this.field = field;
this.frameEvent = frameEvent;
this.frameElementLine = frameElementLine;
this.callbackSetValuesDefined = callbackSetValuesDefined;
this.fieldMenuContext = fieldMenuContext;
this.P = P;
}
getCellActions(tr) {
return tr.querySelector('td');
}
createHeader(frame) {
let trColumns = document.createElement('tr');
let trTitle = document.createElement('tr');
let thTitle = document.createElement('th');
trTitle.appendChild(thTitle);
thTitle.style.textAlign = 'start';
thTitle.classList.add('title');
let thead = document.createElement('thead');
thead.appendChild(trTitle);
thead.appendChild(trColumns);
const actions = document.createElement('th');
trColumns.appendChild(actions);
frame.fields?.forEach(field => {
const th = document.createElement('th');
th.textContent = field.description;
if (field.requerid == true) {
th.textContent = th.textContent;
th.append(this.field.createSpanLabelIsRequerid().cloneNode(true));
}
alignItem(field, th);
trColumns.appendChild(th);
});
let columnsLength = trColumns.querySelectorAll('th');
thTitle.setAttribute('colspan', String(columnsLength.length));
return thead;
}
createRowDetail(frame, inputSnapshot) {
let tr = document.createElement('tr');
const tdActions = document.createElement('td');
tdActions.setAttribute('ruc-action', '');
tr.appendChild(tdActions);
if (frame.fields) {
this.frameElementLine.addActionsInCell(tr, frame.fields[0].identity);
}
frame.fields?.forEach((field) => {
const td = document.createElement('td');
const elementInput = this.field.create(field);
td.appendChild(elementInput);
var alignInInput = elementInput.getAttribute('type') != "checkbox";
if (alignInInput) {
alignItem(field, elementInput);
}
if (alignInInput == false) {
alignItem(field, td);
}
tr.appendChild(td);
this.fieldMenuContext.infoSet({
identity: field.identity,
field: field
});
if (inputSnapshot) {
inputSnapshot.push({
element: elementInput,
value: elementInput.value
});
}
});
let rowCount = this.managmentObject.count(frame.identity);
this.callbackSetValuesDefined(frame, tr);
if (frame.requerid == false && rowCount == 1) {
this.frameEvent.managedFrame(tr);
this.frameEvent.cleanRequeridDependency(tr);
this.managmentObject.tableDependency.moveNotResolvedToImbernate(frame.identity);
}
if (frame.requerid == false && rowCount > 1) {
this.managmentObject.tableDependency.moveImbernateToNotResolved(frame.identity);
}
return tr;
}
createNewRowDetail(identityObject) {
let frame = configWindow.frame.get(identityObject, this.P);
this.managmentObject.addLine(frame);
const row = this.createRowDetail(frame);
row.querySelector("input")?.focus();
this.frameElementLine.eventKeyDownKeyUpLineFrame(row);
return row;
}
deleteRowDetail(currentLineElement, inputTargetEvent) {
let nextSibling = currentLineElement.nextSibling;
let previousSibling = currentLineElement.previousSibling;
let Tbody = currentLineElement.parentNode;
let rowElement = currentLineElement;
currentLineElement = rowElement;
let identityInputTartget = inputTargetEvent.getAttribute("identity");
let fragmentObject = this.managmentObject.getFragmentForIdentity(identityInputTartget);
let field = this.managmentObject.fragment.fields_getForIdentity(identityInputTartget);
let frame = configWindow.frame.get(field.config.fragmentObjectIdentity, this.P);
moveActions(fragmentObject.config.fragmentObjectIdentity, this.getCellActions);
let count = this.managmentObject.count(frame.identity);
let actions = currentLineElement.querySelector('td div');
currentLineElement.remove();
this.managmentObject.removeLine(frame.identity, field.config.line);
this.managmentObject.removeFragmentsLine(frame.identity, field.config.line);
if (count <= 1) {
let newLine = this.createNewRowDetail(frame.identity);
let tdActions = this.getCellActions(newLine);
tdActions?.appendChild(actions);
Tbody.appendChild(newLine);
newLine?.querySelector("input")?.focus();
}
function moveActions(fragmentObject, getCellActionsCallback) {
let actions = document.getElementById(fragmentObject);
if (previousSibling) {
previousSibling?.querySelector("input")?.focus();
let tdActions = getCellActionsCallback(previousSibling);
tdActions?.appendChild(actions);
return;
}
if (nextSibling) {
nextSibling?.querySelector("input")?.focus();
let tdActions = getCellActionsCallback(nextSibling);
tdActions?.appendChild(actions);
}
}
}
}
class FrameElementLine extends FrameElement {
fameLineTable;
constructor(managmentObject, field, frameEvent, button, fieldMenuContext, P) {
super(managmentObject, field, frameEvent, button, fieldMenuContext);
this.fameLineTable = new FameLineTable(managmentObject, field, this, frameEvent, this.setValuesDefined, fieldMenuContext, P);
}
createTDActions(identity) {
const