0
0
Fork 0
mirror of https://github.com/kevinpapst/kimai2.git synced 2025-01-10 19:47:35 +00:00
kevinpapst_kimai2/assets/js/widgets/KimaiPaginatedBoxWidget.js
Kevin Papst 17a815e5a9
updated frontend builds (#5210)
* do not rely on node_modules path
* bump eslint to v9, run eslint via npm task, remove from build task
* loosen dependencies and update all packages
* rebuild assets with latest frontend packages
* bump webpack encore and dependencies
* bump to latest stable yarn
* explicitly mention dependencies
2024-12-06 14:31:04 +01:00

105 lines
3.8 KiB
JavaScript

/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*!
* [KIMAI] KimaiPaginatedBoxWidget: handles box widgets that have a pagination
*/
import KimaiContextMenu from "./KimaiContextMenu";
export default class KimaiPaginatedBoxWidget {
constructor(boxId) {
this.selector = boxId;
const widget = document.querySelector(this.selector);
this.href = widget.dataset['href'];
if (widget.dataset['reload'] !== undefined) {
this.events = widget.dataset['reload'].split(' ');
const reloadPage = () => {
let url = null;
if (document.querySelector(this.selector).dataset['reloadHref'] !== undefined) {
url = document.querySelector(this.selector).dataset['reloadHref'];
} else {
url = document.querySelector(this.selector + ' ul.pagination li.active a').href;
}
this.loadPage(url);
};
for (const eventName of this.events) {
document.addEventListener(eventName, reloadPage);
}
}
document.body.addEventListener('click', (event) => {
let link = event.target;
// could be an icon
if (!link.matches(this.selector + ' a.pagination-link')) {
link = link.parentNode;
}
if (link.matches(this.selector + ' a.pagination-link')) {
event.preventDefault();
this.loadPage(link.href);
}
});
}
static create(elementId) {
return new KimaiPaginatedBoxWidget(elementId);
}
loadPage(url) {
const selector = this.selector;
// this event will render a spinning loader
document.dispatchEvent(new CustomEvent('kimai.reloadContent', {detail: this.selector}));
// and this event will hide it afterwards
const hideOverlay = () => {
document.dispatchEvent(new Event('kimai.reloadedContent'));
};
window.kimai.getPlugin('fetch').fetch(url)
.then(response => {
response.text().then((text) => {
const temp = document.createElement('div');
temp.innerHTML = text;
// previously the parts .card-header .card-body .card-title .card-footer were replaced
// but the layout allows eg. ".list-group .list-group-flush" instead of .card-body
// so we directly replace the entire HTML
// the HTML needs to be parsed for script tags, which can be included (e.g. paginated chart widget)
document.querySelector(selector).replaceWith(this._makeScriptExecutable(temp.firstElementChild));
KimaiContextMenu.createForDataTable(selector + ' table.dataTable');
hideOverlay();
});
})
.catch(() => {
// this is not yet a plugin, so the alert is not available here
window.kimai.getPlugin('alert').error('Failed loading selected page');
hideOverlay();
});
}
/**
* @param {Element|ChildNode} node
* @returns {Element}
* @private
*/
_makeScriptExecutable(node) {
if (node.tagName !== undefined && node.tagName === 'SCRIPT') {
const script = document.createElement('script');
script.text = node.innerHTML;
node.parentNode.replaceChild(script, node );
} else {
for (const child of node.childNodes) {
this._makeScriptExecutable(child);
}
}
return node;
}
}