import '@material/mwc-dialog'; import '@material/mwc-fab'; import '@material/mwc-snackbar'; import type {TextFieldInputMode, TextFieldType} from '@material/mwc-textfield/mwc-textfield-base'; import collect from 'collect.js'; import {snakeCase} from 'lodash/string'; import {Children} from 'mithril'; import {Model} from '../../Models'; import {showSnackbar} from '../../utils'; import DataTable from '../DataTable/DataTable.jsx'; import TableBody from '../DataTable/TableBody.jsx'; import TableCell from '../DataTable/TableCell.jsx'; import TableHead from '../DataTable/TableHead.jsx'; import TableHeadCell from '../DataTable/TableHeadCell.jsx'; import TableHeadRow from '../DataTable/TableHeadRow.jsx'; import TableRow from '../DataTable/TableRow.jsx'; import {Cell, LayoutGrid, Row} from '../Grid'; import Mdi from '../Mdi.jsx'; import Page from '../Page.jsx'; export type ColumnT = { id?: string, title: string, type?: 'checkbox' | 'numeric' } export type FieldT = { id?: string, value?: string, type?: TextFieldType, label?: string, placeholder?: string, prefix?: string, suffix?: string, icon?: string, iconTrailing?: string, disabled?: boolean, charCounter?: boolean, outlined?: boolean, helper?: string, helperPersistent?: boolean | string, required?: boolean, minLength?: number, maxLength?: number, validationMessage?: string, pattern?: string, min?: number | string, max?: number | string, size?: number | null, step?: number | null, autoValidate?: boolean, validity?: ValidityState, willValidate?: boolean, validityTransform?: (value: string, nativeValidity: ValidityState) => Partial | null, validateOnInitialRender?: boolean, name?: string, inputMode?: TextFieldInputMode, readOnly?: boolean, autocapitalize: 'on' | 'off' | 'sentences' | 'none' | 'words' | 'characters', endAligned?: boolean, ... }; export type SectionT = FieldT[] | { id?: string, heading?: string, columns?: number, fields: FieldT[] | { [string]: FieldT } }; /** * @abstract */ export default class RecordsPage extends Page { columns: { [string]: [string] | ColumnT } | ColumnT[]; rows: string[][] = []; sections: { [string]: SectionT } | SectionT[]; dialogs: Children[]; model: Model; saveModelWithSnakeCase: boolean = true; async oninit(vnode) { // eslint-disable-next-line no-param-reassign vnode.state.data = await this.model.all(); if (vnode.state.data) { this.rows.push(vnode.state.data.all); } else { m.redraw(); } } tableColumns(): Children { return collect(this.columns) .map( (column: ColumnT | string, id: string) => ( {typeof column === 'string' ? column : column.title} ) ) .toArray(); } tableRows(): Children { if (this.rows.length === 0) { return ( {this.__('Non sono presenti dati')} ); } return this.rows.map((row, index) => ( {row.map((cell, index_) => {cell})} )); } recordDialog() { return (
{(() => { const sections = collect(this.sections); return sections.map((section, index) => ( <>

{section.heading}

{(() => { const fields = collect(section.fields); return fields.map((field, fieldIndex) => ( )) .toArray(); })()}
{index !== sections.keys() .last() &&
} )) .toArray(); })()}
{this.__('Conferma')} {this.__('Annulla')}
); } view(vnode) { return ( <>

{this.title}

{this.tableColumns()} {this.tableRows()} {this.recordDialog()} {this.dialogs} ); } oncreate(vnode) { super.oncreate(vnode); $('mwc-fab#add-record') .on('click', (clickEvent) => { const dialog = $(clickEvent.delegateTarget) .next('mwc-dialog#add-record-dialog'); dialog.find('form') .attr('method', 'PUT') .off() .on('submit', async (event) => { event.preventDefault(); const fd = new FormData(event.delegateTarget); if (this.saveModelWithSnakeCase) { for (const [key, value] of fd.entries()) { fd.set(snakeCase(key), value); fd.delete(key); } } // noinspection JSUnresolvedFunction const instance = await this.model.create(fd); if (instance.id) { this.rows.push(instance.all()); m.redraw(); await showSnackbar(this.__('Record creato'), 2.5); } }); dialog.find('mwc-textfield') .val(''); dialog.get(0) .show(); }); } }