import '@material/mwc-linear-progress';
import '@material/mwc-list/mwc-list-item';
import '../../WebComponents/Select';
import {type Cash} from 'cash-dom/dist/cash';
import {
type Children,
type Vnode
} from 'mithril';
import Component from '../Component.jsx';
import Mdi from '../Mdi.jsx';
import TableColumn from './TableColumn.jsx';
import TableFooter from './TableFooter.jsx';
import TableRow from './TableRow.jsx';
export default class DataTable extends Component {
view(vnode) {
return
{this.attrs.has('checkable') && }
{this.tableColumns(vnode.children)}
{this.tableRows(vnode.children)}
{this.tableFooter(vnode.children)}
{this.attrs.has('paginated') &&
{__('Righe per pagina')}
{this.attrs.get('rows-per-page', '10,25,50,75,100').split(',').map(
(value) => {
const rowsPerPage = Number.parseInt(value, 10);
return (
{rowsPerPage}
);
}
)}
{__('1-:chunk di :total', {chunk: 10, total: 100})}
}
;
}
tableColumns(children: Array) {
return this.filterElements(children.flat(), TableColumn);
}
tableRows(children: Array) {
let rows = this.filterElements(children.flat(), TableRow);
if (this.attrs.has('checkable')) {
rows = rows.map((row: Vnode) => (
{row.children}
));
}
return rows;
}
tableFooter(children: Array) {
return this.filterElements(children.flat(), TableFooter);
}
filterElements(elements: Array, tag: Component | string): Array {
const filtered = [];
for (const element: Vnode of elements) {
if (element.tag === tag) {
filtered.push(element);
}
}
return filtered;
}
oncreate(vnode) {
super.oncreate(vnode);
$(this.element).find('thead th[sortable], thead th[sortable] mwc-icon-button-toggle').on('click', this.onColumnClicked.bind(this));
}
showProgress() {
$(this.element)
.addClass('mdc-data-table--in-progress')
.find('.mdc-data-table__progress-indicator mwc-linear-progress')
.get(0)
.open();
}
hideProgress() {
$(this.element)
.removeClass('mdc-data-table--in-progress')
.find('.mdc-data-table__progress-indicator mwc-linear-progress')
.get(0)
.open();
}
onColumnClicked(event: Event) {
this.showProgress();
const column: Cash = $(event.target).closest('th');
const ascendingClass = 'mdc-data-table__header-cell--sorted';
const descendingClass = 'mdc-data-table__header-cell--sorted-descending';
// If it's already sorted change direction
if (column.hasClass(ascendingClass)) {
column.toggleClass(descendingClass);
}
// Clean previously sorted info and arrows
const columns = $(this.element).find('thead th');
columns.removeClass(ascendingClass);
columns.find('mwc-icon-button-toggle').hide();
// Add ony one header to sort
column.addClass(ascendingClass);
// Check if need descending sorting
const isDescending = column.hasClass(descendingClass);
// Do sorting
this.sortTable(column.index() + 1, isDescending, column.attr('type') === 'numeric');
}
sortTable(columnIndex: number, isDescending: boolean, isNumeric: boolean) {
const sorted = [...$(this.element).find(`tr td:nth-child(${columnIndex})`)].sort((a: HTMLElement, b: HTMLElement) => {
let aValue = a.textContent;
let bValue = b.textContent;
if (isNumeric) {
aValue = Number.parseFloat(aValue);
bValue = Number.parseFloat(bValue);
}
if (!isDescending) {
const temporary = aValue;
aValue = bValue;
bValue = temporary;
}
if (typeof aValue === 'string') {
return aValue.localeCompare(bValue);
}
return aValue < bValue ? -1 : (aValue > bValue ? 1 : 0);
});
for (const cell of sorted) {
const row = $(cell).parent();
row.appendTo(row.parent());
}
}
}