feat(cloudron): add tirreno package artifacts
- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents - Includes package manifest, Dockerfile, source code, documentation, and build artifacts - Add tirreno-1761840148.tar.gz as a build artifact - Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package - Include all necessary files for the tirreno Cloudron package This adds the complete tirreno Cloudron package artifacts to the repository.
This commit is contained in:
@@ -0,0 +1,466 @@
|
||||
import {Loader} from '../Loader.js?v=2';
|
||||
import {Tooltip} from '../Tooltip.js?v=2';
|
||||
import {fireEvent} from '../utils/Event.js?v=2';
|
||||
import {getQueryParams} from '../utils/DataSource.js?v=2';
|
||||
import {handleAjaxError} from '../utils/ErrorHandler.js?v=2';
|
||||
import {TotalTile} from '../TotalTile.js?v=2';
|
||||
import {renderTotalFrame} from '../DataRenderers.js?v=2';
|
||||
import {
|
||||
MIDLINE_HELLIP,
|
||||
} from '../utils/Constants.js?v=2';
|
||||
|
||||
export class BaseGrid {
|
||||
constructor(gridParams) {
|
||||
this.config = gridParams;
|
||||
|
||||
this.loader = new Loader();
|
||||
this.tooltip = new Tooltip();
|
||||
this.totalTile = new TotalTile();
|
||||
|
||||
this.firstload = true;
|
||||
|
||||
this.renderTotalsLoader = this.renderTotalsLoader.bind(this);
|
||||
|
||||
this.initLoad();
|
||||
|
||||
if (this.config.dateRangeGrid && !this.config.sequential) {
|
||||
const onDateFilterChanged = this.onDateFilterChanged.bind(this);
|
||||
window.addEventListener('dateFilterChanged', onDateFilterChanged, false);
|
||||
}
|
||||
|
||||
if (gridParams.choicesFilterEvents) {
|
||||
const onChoicesFilterChanged = this.onChoicesFilterChanged.bind(this);
|
||||
for (let i = 0; i < gridParams.choicesFilterEvents.length; i++) {
|
||||
window.addEventListener(gridParams.choicesFilterEvents[i], onChoicesFilterChanged, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.config.sequential) {
|
||||
const onSearchFilterChanged = this.onSearchFilterChanged.bind(this);
|
||||
window.addEventListener('searchFilterChanged', onSearchFilterChanged, false);
|
||||
}
|
||||
}
|
||||
|
||||
initLoad() {
|
||||
const me = this;
|
||||
const tableId = this.config.tableId;
|
||||
|
||||
$(document).ready(() => {
|
||||
$.extend($.fn.dataTable.ext.classes, {
|
||||
sStripeEven: '', sStripeOdd: ''
|
||||
});
|
||||
|
||||
$.fn.dataTable.ext.pager.numbers_length = 9;
|
||||
|
||||
$.fn.dataTable.ext.errMode = function() {};
|
||||
$(`#${tableId}`).on('error.dt', me.onError);
|
||||
|
||||
const onBeforeLoad = me.onBeforeLoad.bind(me);
|
||||
$(`#${tableId}`).on('preXhr.dt', onBeforeLoad);
|
||||
|
||||
const onBeforePageChange = me.onBeforePageChange.bind(me);
|
||||
$(`#${tableId}`).on('page.dt', onBeforePageChange);
|
||||
|
||||
const config = me.getDataTableConfig();
|
||||
$(`#${tableId}`).DataTable(config);
|
||||
|
||||
const onTableRowClick = me.onTableRowClick.bind(me);
|
||||
$(`#${tableId} tbody`).on('click', 'tr', onTableRowClick);
|
||||
|
||||
const onDraw = me.onDraw.bind(me);
|
||||
$(`#${tableId}`).on('draw.dt', onDraw);
|
||||
|
||||
$(`#${tableId}`).closest('.dt-container').find('nav').empty();
|
||||
|
||||
document.getElementById(tableId).classList.add('hide-body');
|
||||
|
||||
if (!me.config.sequential) {
|
||||
me.loadData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getDataTableConfig() {
|
||||
const me = this;
|
||||
const url = this.config.url;
|
||||
const columns = this.columns;
|
||||
const columnDefs = this.columnDefs;
|
||||
const isSortable = this.getConfigParam('isSortable');
|
||||
const order = this.orderConfig;
|
||||
|
||||
const config = {
|
||||
ajax: function(data, callback, settings) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
method: 'GET',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function(response, textStatus, jqXHR) {
|
||||
callback(response);
|
||||
me.performAdditional(response, me.config);
|
||||
me.stopAnimation();
|
||||
},
|
||||
error: handleAjaxError,
|
||||
});
|
||||
},
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
deferRender: true,
|
||||
deferLoading: 0,
|
||||
pageLength: 25,
|
||||
autoWidth: false,
|
||||
lengthChange: false,
|
||||
searching: true,
|
||||
ordering: isSortable,
|
||||
info: false,
|
||||
pagingType: 'simple_numbers',
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>',
|
||||
},
|
||||
},
|
||||
|
||||
layout: {
|
||||
topEnd: null,
|
||||
bottomEnd: {
|
||||
paging: {
|
||||
boundaryNumbers: false,
|
||||
type: 'simple_numbers',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
createdRow: function(row, data, dataIndex) {
|
||||
$(row).attr('data-item-id', data.id);
|
||||
},
|
||||
|
||||
drawCallback: function(settings) {
|
||||
me.drawCallback(settings);
|
||||
me.updateTableFooter(this);
|
||||
},
|
||||
|
||||
columnDefs: columnDefs,
|
||||
columns: columns,
|
||||
order: order
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
performAdditional(response, config) {
|
||||
if (!config.calculateTotals) {
|
||||
fireEvent('dateFilterChangedCompleted');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const ids = response.data.map(item => item.id);
|
||||
const token = document.head.querySelector('[name=\'csrf-token\'][content]').content;
|
||||
const dateRange = response.dateRange;
|
||||
|
||||
if (dateRange && ids.length) {
|
||||
const requestData = {
|
||||
token: token,
|
||||
ids: ids,
|
||||
type: config.totals.type,
|
||||
startDate: dateRange.startDate,
|
||||
endDate: dateRange.endDate,
|
||||
};
|
||||
let preparedBase = {};
|
||||
response.data.forEach(rec => {
|
||||
preparedBase[rec.id] = rec;
|
||||
});
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/admin/timeFrameTotal',
|
||||
data: requestData,
|
||||
success: (data) => this.onTotalsSuccess(data, config, preparedBase),
|
||||
error: handleAjaxError,
|
||||
complete: function() {
|
||||
fireEvent('dateFilterChangedCompleted');
|
||||
},
|
||||
});
|
||||
} else {
|
||||
fireEvent('dateFilterChangedCompleted');
|
||||
}
|
||||
|
||||
if (!dateRange && ids.length) {
|
||||
// actualy making fake response from server
|
||||
let data = {totals: {}};
|
||||
let preparedBase = {};
|
||||
const cols = config.totals.columns;
|
||||
response.data.forEach(item => {
|
||||
data.totals[item.id] = {};
|
||||
preparedBase[item.id] = {};
|
||||
cols.forEach(col => {
|
||||
data.totals[item.id][col] = item[col];
|
||||
preparedBase[item.id][col] = item[col];
|
||||
});
|
||||
|
||||
});
|
||||
this.onTotalsSuccess(data, config, preparedBase);
|
||||
}
|
||||
}
|
||||
|
||||
onTotalsSuccess(data, config, base) {
|
||||
const table = $(`#${config.tableId}`).DataTable();
|
||||
const columns = config.totals.columns;
|
||||
|
||||
let idxs = {};
|
||||
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
idxs[columns[i]] = -1;
|
||||
}
|
||||
|
||||
table.settings().init().columns.forEach((col, index) => {
|
||||
columns.forEach(colName => {
|
||||
if (col.data === colName || col.name === colName) {
|
||||
idxs[colName] = index;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
if (Object.values(idxs).includes(-1)) return;
|
||||
|
||||
let rowData;
|
||||
let id;
|
||||
|
||||
table.rows().every(function() {
|
||||
rowData = this.data();
|
||||
id = String(rowData.id);
|
||||
if (id in data.totals) {
|
||||
for (const col in idxs) {
|
||||
$(table.cell(this, idxs[col]).node()).html(renderTotalFrame(base[id][col], data.totals[id][col]));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
drawCallback(settings) {
|
||||
const me = this;
|
||||
|
||||
this.initTooltips();
|
||||
|
||||
//this.stopAnimation();
|
||||
|
||||
const params = {
|
||||
tableId: me.config.tableId
|
||||
};
|
||||
|
||||
if (settings && settings.iDraw > 1) {
|
||||
const total = settings.json.recordsTotal;
|
||||
const tileId = this.config.tileId;
|
||||
const tableId = this.config.tableId;
|
||||
|
||||
this.totalTile.update(tableId, tileId, total);
|
||||
this.updateTableTitle(total);
|
||||
|
||||
fireEvent('tableLoaded', params);
|
||||
}
|
||||
}
|
||||
|
||||
updateTableTitle(value) {
|
||||
const tableId = this.config.tableId;
|
||||
const wrapper = document.getElementById(tableId).closest('.card');
|
||||
|
||||
if (wrapper) {
|
||||
const span = wrapper.querySelector('header span');
|
||||
|
||||
span.textContent = value;
|
||||
}
|
||||
}
|
||||
|
||||
stopAnimation() {
|
||||
this.loader.stop();
|
||||
const el = document.getElementById(`${this.config.tableId}_loader`);
|
||||
if (el) el.remove();
|
||||
|
||||
const table = document.getElementById(this.config.tableId);
|
||||
table.classList.remove('dim-table');
|
||||
}
|
||||
|
||||
updateTableFooter(dataTable) {
|
||||
const tableId = this.config.tableId;
|
||||
const pagerSelector = `#${tableId}_wrapper .dt-paging`;
|
||||
|
||||
const api = dataTable.api();
|
||||
if (api.ajax && typeof api.ajax.json === 'function' && api.ajax.json() === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(`#${tableId}`).closest('.dt-container').find('nav').show();
|
||||
if (api.page.info().pages <= 1) {
|
||||
$(pagerSelector).hide();
|
||||
} else {
|
||||
$(pagerSelector).show();
|
||||
}
|
||||
}
|
||||
|
||||
initTooltips() {
|
||||
const tableId = this.config.tableId;
|
||||
Tooltip.addTooltipsToGridRecords(tableId);
|
||||
Tooltip.addTooltipToSpans();
|
||||
Tooltip.addTooltipToParagraphs();
|
||||
}
|
||||
|
||||
onBeforeLoad(e, settings, data) {
|
||||
if (!this.config.sequential) {
|
||||
this.startLoader();
|
||||
}
|
||||
this.updateTableTitle(MIDLINE_HELLIP);
|
||||
|
||||
fireEvent('dateFilterChangedCaught');
|
||||
|
||||
//TODO: move to events grid? Or not?
|
||||
const params = this.config.getParams();
|
||||
const queryParams = getQueryParams(params);
|
||||
|
||||
for (let key in queryParams) {
|
||||
data[key] = queryParams[key];
|
||||
}
|
||||
|
||||
const token = document.head.querySelector('[name=\'csrf-token\'][content]').content;
|
||||
data.token = token;
|
||||
}
|
||||
|
||||
onDraw(e, settings) {
|
||||
if (this.firstload) {
|
||||
document.getElementById(this.config.tableId).classList.remove('hide-body');
|
||||
this.firstload = false;
|
||||
}
|
||||
}
|
||||
|
||||
onBeforePageChange(e, settings) {
|
||||
const tableId = this.config.tableId;
|
||||
const pagesPath = `#${tableId}_paginate a`;
|
||||
|
||||
[...document.querySelectorAll(pagesPath)].forEach(a => {
|
||||
a.outerHTML =
|
||||
a.outerHTML
|
||||
.replace(/<a/g, '<span')
|
||||
.replace(/<\/a>/g, '</span>');
|
||||
});
|
||||
}
|
||||
|
||||
onTableRowClick(event) {
|
||||
const selection = window.getSelection();
|
||||
if ('Range' === selection.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const row = event.target.closest('tr');
|
||||
const link = row.querySelector('a');
|
||||
|
||||
if (link) {
|
||||
event.preventDefault();
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
window.open(link.href, '_blank');
|
||||
} else {
|
||||
window.location.href = link.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: leave blank and move to the events table
|
||||
addTableRowsEvents() {
|
||||
const tableId = this.config.tableId;
|
||||
const onRowClick = this.onRowClick.bind(this);
|
||||
|
||||
if ($(this.table).DataTable().data().any()) {
|
||||
const rows = document.querySelectorAll(`#${tableId} tbody tr`);
|
||||
rows.forEach(row => row.addEventListener('click', onRowClick, false));
|
||||
}
|
||||
}
|
||||
|
||||
startLoader() {
|
||||
const tableId = this.config.tableId;
|
||||
const loaderPath = `${tableId}_processing`;
|
||||
|
||||
const loaderWrapper = document.getElementById(loaderPath);
|
||||
const el = document.createElement('p');
|
||||
el.className = 'text-loader';
|
||||
loaderWrapper.replaceChildren(el);
|
||||
|
||||
this.loader.start(el);
|
||||
|
||||
loaderWrapper.style.display = null;
|
||||
|
||||
const table = document.getElementById(this.config.tableId);
|
||||
table.classList.add('dim-table');
|
||||
}
|
||||
|
||||
onRowClick(e) {
|
||||
const selection = window.getSelection();
|
||||
if ('Range' === selection.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const row = e.target.closest('tr');
|
||||
const itemId = row.dataset.itemId;
|
||||
const data = {itemId: itemId};
|
||||
|
||||
fireEvent('tableRowClicked', data);
|
||||
}
|
||||
|
||||
onError(e, settings, techNote, message) {
|
||||
if (settings.jqXHR !== undefined && 403 === settings.jqXHR.status) {
|
||||
window.location.href = escape('/');
|
||||
}
|
||||
|
||||
//console.warn('An error has been reported by DataTables: ', message);
|
||||
}
|
||||
|
||||
loadData() {
|
||||
//TODO: create getter for table el: $(me.table).DataTable().ajax.reload()
|
||||
const me = this;
|
||||
$(me.table).DataTable().ajax.reload();
|
||||
}
|
||||
|
||||
onDateFilterChanged() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
onSearchFilterChanged() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
onChoicesFilterChanged() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
getConfigParam(key) {
|
||||
const cfg = this.config;
|
||||
const value = ('undefined' !== typeof cfg[key]) ? cfg[key] : true;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
get orderConfig() {
|
||||
return this.getConfigParam('isSortable') ? [[1, 'desc']] : [];
|
||||
}
|
||||
|
||||
get table() {
|
||||
const tableId = this.config.tableId;
|
||||
const tableEl = document.getElementById(tableId);
|
||||
|
||||
return tableEl;
|
||||
}
|
||||
|
||||
renderTotalsLoader(data, type, record, meta) {
|
||||
const span = document.createElement('span');
|
||||
|
||||
const col_name = meta.settings.aoColumns[meta.col].name;
|
||||
if (this.config.calculateTotals && this.config.totals.columns.includes(col_name)) {
|
||||
span.className = 'loading-table-total';
|
||||
span.textContent = MIDLINE_HELLIP;
|
||||
} else {
|
||||
span.textContent = data;
|
||||
}
|
||||
|
||||
return span;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user