feat: Aggiunta paginazione custom

This commit is contained in:
Maicol Battistini 2023-07-11 12:50:02 +02:00
parent eaf6884609
commit b808fa50f0
No known key found for this signature in database
3 changed files with 84 additions and 21 deletions

View File

@ -1,5 +1,6 @@
import '@maicol07/material-web-additions/data-table/data-table.js';
import {DataTable as MdDataTable} from '@maicol07/material-web-additions/data-table/lib/data-table';
import {
mdiChevronLeft,
mdiChevronRight,
@ -15,19 +16,19 @@ import {
Attributes,
Component
} from 'mithril-utilities';
import {KebabCase} from 'type-fest';
export interface DataTableAttributes extends Attributes {
inProgress?: boolean;
paginated?: boolean;
currentPageSize?: number;
pageSizesLabel?: string;
paginationTotalLabel?: string;
type MdDataTableAttributes = {
[K in keyof MdDataTable as KebabCase<K>]: MdDataTable[K];
};
export interface DataTableAttributes extends Attributes, Partial<MdDataTableAttributes> {
}
export default class DataTable<A extends DataTableAttributes = DataTableAttributes> extends Component<A> {
view(vnode: Vnode<A>) {
return (
<md-data-table pageSizesLabel={__('Righe per pagina:')} paginationTotalLabel={__(':firstRow-:lastRow di :totalRows')} {...vnode.attrs}>
<md-data-table page-sizes-label={__('Righe per pagina:')} pagination-total-label={__(':firstRow-:lastRow di :totalRows')} {...vnode.attrs}>
{this.contents(vnode)}
<MdIcon icon={mdiPageFirst} slot="pagination-first-button-icon"/>
<MdIcon icon={mdiChevronLeft} slot="pagination-previous-button-icon"/>

View File

@ -5,6 +5,7 @@ import '@maicol07/material-web-additions/data-table/data-table-row.js';
import {
DataTable as MdDataTable,
PaginateDetail,
RowSelectionChangedDetail
} from '@maicol07/material-web-additions/data-table/lib/data-table';
import {DataTableCell} from '@maicol07/material-web-additions/data-table/lib/data-table-cell';
@ -31,18 +32,14 @@ export interface RecordsTableAttributes<M extends Model<any, any>> extends DataT
cols: Collection<Children> | Collection<RecordsTableColumnAttributes> | Collection<Children | RecordsTableColumnAttributes>;
records: Map<string, M>;
readonly?: boolean;
selectable?: boolean;
onTableRowClick?(recordId: string, event: MouseEvent): void;
onDeleteRecordButtonClick?(recordId: string, event: MouseEvent): void;
onDeleteSelectedRecordsButtonClick?(recordsIds: string[], event: MouseEvent): void;
onRowSelectionChanged?(selectedRecordsIds: string[], event: CustomEventInit<RowSelectionChangedDetail>): void;
onPageChange?(event: CustomEventInit<PaginateDetail>): void;
valueModifier?(value: any, attribute: string, record: M): any;
selectable?: boolean;
}
export default class RecordsTable<M extends Model<any, any>, A extends RecordsTableAttributes<M> = RecordsTableAttributes<M>> extends DataTable<A> {
@ -51,9 +48,12 @@ export default class RecordsTable<M extends Model<any, any>, A extends RecordsTa
oninit(vnode: Vnode<A, this>) {
super.oninit(vnode);
this.setDefaultAttributes(vnode);
}
vnode.attrs.paginated ??= true;
vnode.attrs.currentPageSize ??= 10;
onbeforeupdate(vnode: VnodeDOM<A, this>) {
super.onbeforeupdate(vnode);
this.setDefaultAttributes(vnode);
}
onupdate(vnode: VnodeDOM<A, this>) {
@ -67,6 +67,12 @@ export default class RecordsTable<M extends Model<any, any>, A extends RecordsTa
}
}
setDefaultAttributes(vnode: Vnode<A, this>) {
vnode.attrs.paginated ??= true;
vnode.attrs['current-page-size'] ??= 10;
vnode.attrs['custom-pagination'] ??= true;
}
contents(vnode: Vnode<A>) {
return [
this.tableColumns(vnode).values<Children>().all(),
@ -199,7 +205,8 @@ export default class RecordsTable<M extends Model<any, any>, A extends RecordsTa
oncreate(vnode: VnodeDOM<A, this>) {
super.oncreate(vnode);
this.element.addEventListener('rowSelectionChanged', this.onRowSelectionChanged.bind(this, vnode));
this.element.addEventListener('row-selection-changed', this.onRowSelectionChanged.bind(this, vnode));
this.element.addEventListener('paginate', this.onTablePaginate.bind(this, vnode));
}
protected onRowSelectionChanged(vnode: Vnode<A>, event: CustomEventInit<RowSelectionChangedDetail>) {
@ -224,6 +231,10 @@ export default class RecordsTable<M extends Model<any, any>, A extends RecordsTa
vnode.attrs.onTableRowClick?.(recordId, event);
}
protected onTablePaginate(vnode: Vnode<A>, event: CustomEventInit<PaginateDetail>) {
vnode.attrs.onPageChange?.(event);
}
protected onDeleteRecordButtonClicked(vnode: Vnode<A>, record: M, event: MouseEvent) {
event.stopPropagation();
vnode.attrs.onDeleteRecordButtonClick?.(record.getId()!, event);

View File

@ -6,6 +6,7 @@ import '@material/web/fab/fab.js';
import '@material/web/iconbutton/standard-icon-button.js';
import {router} from '@maicol07/inertia-mithril';
import {PaginateDetail} from '@maicol07/material-web-additions/data-table/lib/data-table';
import {
FilterTextFieldInputEventDetail,
SortButtonClickedEventDetail
@ -34,6 +35,21 @@ import {match} from 'ts-pattern';
import {Match} from 'ts-pattern/dist/types/Match';
import type {Class} from 'type-fest';
export interface Meta {
current_page: number;
from: number;
last_page: number;
path: string;
per_page: number;
to: number;
total: number;
}
export interface JSONAPIResponse {
meta: Meta;
}
type RecordDialogVnode<M extends Model<any, any>, D extends RecordDialog<M>> = Vnode<RecordDialogAttributes<M>, D>;
type DeleteRecordDialogVnode<M extends Model<any, any>, D extends DeleteRecordDialog<M>> = Vnode<DeleteRecordDialogAttributes<M>, D>;
@ -63,6 +79,11 @@ export default abstract class RecordsPage<
protected currentPageSize = 50;
protected pageSizes = [10, 25, 50, 100];
protected currentPage = 1;
protected lastPage = 1;
protected firstRowOfPage = 1;
protected totalRecords = 0;
protected lastRowOfPage = this.totalRecords;
protected filters: Map<string, string> = new Map();
protected sort: Map<string, SortDirection> = new Map([['id', SortDirection.ASC]]);
@ -72,6 +93,8 @@ export default abstract class RecordsPage<
oninit(vnode: Vnode<PageAttributes, this>) {
super.oninit(vnode);
// @ts-ignore
this.modelType.pageSize = this.currentPageSize;
// Redraw on a first load to call onbeforeupdate
m.redraw();
}
@ -93,7 +116,13 @@ export default abstract class RecordsPage<
// Fix Restify when filtering relations
query = query.option('related', query.getQuery().getInclude().join(','));
const response = await query.get();
const response = await query.get(this.currentPage);
const rawResponse = response.getHttpClientResponse().getData() as JSONAPIResponse;
this.lastPage = rawResponse.meta.last_page;
this.firstRowOfPage = rawResponse.meta.from;
this.lastRowOfPage = rawResponse.meta.to;
this.currentPageSize = rawResponse.meta.per_page;
this.totalRecords = rawResponse.meta.total;
const data = response.getData();
this.records.clear();
@ -187,14 +216,18 @@ export default abstract class RecordsPage<
records={this.records}
paginated
selectable
currentPageSize={this.currentPageSize}
pageSizes={JSON.stringify(this.pageSizes)}
cols={this.tableColumns()}
inProgress={this.isTableLoading}
in-progress={this.isTableLoading}
readonly={this.readonlyRecords}
current-first-row={this.firstRowOfPage}
current-last-row={this.lastRowOfPage}
current-page-size={this.currentPageSize}
page-sizes={JSON.stringify(this.pageSizes)}
total-rows={this.totalRecords}
onTableRowClick={this.onTableRowClick.bind(this)}
onDeleteRecordButtonClick={this.onDeleteRecordButtonClicked.bind(this)}
onDeleteSelectedRecordsButtonClick={this.onDeleteSelectedRecordsButtonClicked.bind(this)}
readonly={this.readonlyRecords}
onPageChange={this.onTablePageChange.bind(this)}
valueModifier={(value: unknown, attribute: string, record: M) => this.cellValueModifier(value, attribute, record)
.otherwise(() => value)}/>
);
@ -267,6 +300,24 @@ export default abstract class RecordsPage<
this.openDeleteRecordsDialog(recordsIds.map((recordId) => this.records.get(recordId)!));
}
onTablePageChange(event: CustomEvent<PaginateDetail>) {
const {pageSize, action} = event.detail;
this.currentPageSize = pageSize;
const currentPage = this.currentPage;
match(action)
.with('first', () => (this.currentPage = 1))
.with('previous', () => (this.currentPage--))
.with('next', () => (this.currentPage++))
.with('last', () => (this.currentPage = this.lastPage))
.with('current', () => {})
.run();
console.log('onTablePageChange', event.detail);
if (currentPage !== this.currentPage) {
this.refreshRecords = true;
m.redraw();
}
}
onupdate(vnode: VnodeDOM<PageAttributes, this>) {
super.onupdate(vnode);