web: sort components into folders, implement pagination for table
This commit is contained in:
		
							
								
								
									
										86
									
								
								web/src/elements/table/Table.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								web/src/elements/table/Table.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | ||||
| import { html, LitElement, property, TemplateResult } from "lit-element"; | ||||
| import { until } from "lit-html/directives/until.js"; | ||||
| import { PBResponse } from "../../api/client"; | ||||
| import { COMMON_STYLES } from "../../common/styles"; | ||||
|  | ||||
| export abstract class Table extends LitElement { | ||||
|     abstract apiEndpoint(page: number): Promise<PBResponse>; | ||||
|     abstract columns(): Array<string>; | ||||
|     abstract row(item: any): Array<string>; | ||||
|  | ||||
|     @property() | ||||
|     data?: PBResponse; | ||||
|  | ||||
|     @property() | ||||
|     page: number = 1; | ||||
|  | ||||
|     static get styles() { | ||||
|         return [COMMON_STYLES]; | ||||
|     } | ||||
|  | ||||
|     public fetch() { | ||||
|         this.apiEndpoint(this.page).then((r) => { | ||||
|             this.data = r; | ||||
|             this.page = r.pagination.current; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private renderRows(): TemplateResult[] | undefined { | ||||
|         if (!this.data) { | ||||
|             return; | ||||
|         } | ||||
|         return this.data.results.map((item) => { | ||||
|             const fullRow = [`<tr role="row">`].concat( | ||||
|                 this.row(item).map((col) => { | ||||
|                     return `<td role="cell">${col}</td>`; | ||||
|                 }) | ||||
|             ); | ||||
|             fullRow.push(`</tr>`); | ||||
|             return html(<any>fullRow); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
|         if (!this.data) { | ||||
|             this.fetch(); | ||||
|             return; | ||||
|         } | ||||
|         return html`<div class="pf-c-toolbar"> | ||||
|                 <div class="pf-c-toolbar__content"> | ||||
|                     <div class="pf-c-toolbar__bulk-select"> | ||||
|                         <slot name="create-button"></slot> | ||||
|                         <button | ||||
|                             @click=${() => { | ||||
|                                 this.fetch(); | ||||
|                             }} | ||||
|                             class="pf-c-button pf-m-primary" | ||||
|                         > | ||||
|                             Refresh | ||||
|                         </button> | ||||
|                     </div> | ||||
|                     <pb-table-pagination | ||||
|                         class="pf-c-toolbar__item pf-m-pagination" | ||||
|                         .table=${this} | ||||
|                     ></pb-table-pagination> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <table class="pf-c-table pf-m-compact pf-m-grid-md"> | ||||
|                 <thead> | ||||
|                     <tr role="row"> | ||||
|                         ${this.columns().map( | ||||
|                             (col) => html`<th role="columnheader" scope="col">${col}</th>` | ||||
|                         )} | ||||
|                     </tr> | ||||
|                 </thead> | ||||
|                 <tbody role="rowgroup"> | ||||
|                     ${this.renderRows()} | ||||
|                 </tbody> | ||||
|             </table> | ||||
|             <div class="pf-c-pagination pf-m-bottom"> | ||||
|                 <pb-table-pagination | ||||
|                     class="pf-c-toolbar__item pf-m-pagination" | ||||
|                     .table=${this} | ||||
|                 ></pb-table-pagination> | ||||
|             </div>`; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										71
									
								
								web/src/elements/table/TablePagination.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								web/src/elements/table/TablePagination.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| import { customElement, html, LitElement, property } from "lit-element"; | ||||
| import { Table } from "./Table"; | ||||
| import { COMMON_STYLES } from "../../common/styles"; | ||||
|  | ||||
| @customElement("pb-table-pagination") | ||||
| export class TablePagination extends LitElement { | ||||
|     @property() | ||||
|     table?: Table; | ||||
|  | ||||
|     static get styles() { | ||||
|         return [COMMON_STYLES]; | ||||
|     } | ||||
|  | ||||
|     previousHandler() { | ||||
|         if (!this.table?.data?.pagination.previous) { | ||||
|             console.debug(`passbook/tables: no previous`); | ||||
|             return; | ||||
|         } | ||||
|         this.table.page = this.table?.data?.pagination.previous; | ||||
|     } | ||||
|  | ||||
|     nextHandler() { | ||||
|         if (!this.table?.data?.pagination.next) { | ||||
|             console.debug(`passbook/tables: no next`); | ||||
|             return; | ||||
|         } | ||||
|         this.table.page = this.table?.data?.pagination.next; | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
|         return html` <div class="pf-c-pagination pf-m-compact pf-m-hidden pf-m-visible-on-md"> | ||||
|             <div class="pf-c-pagination pf-m-compact pf-m-compact pf-m-hidden pf-m-visible-on-md"> | ||||
|                 <div class="pf-c-options-menu"> | ||||
|                     <div class="pf-c-options-menu__toggle pf-m-text pf-m-plain"> | ||||
|                         <span class="pf-c-options-menu__toggle-text"> | ||||
|                             ${this.table?.data?.pagination.start_index} - | ||||
|                             ${this.table?.data?.pagination.end_index} of | ||||
|                             ${this.table?.data?.pagination.count} | ||||
|                         </span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <nav class="pf-c-pagination__nav" aria-label="Pagination"> | ||||
|                     <div class="pf-c-pagination__nav-control pf-m-prev"> | ||||
|                         <button | ||||
|                             class="pf-c-button pf-m-plain" | ||||
|                             @click=${() => { | ||||
|                                 this.previousHandler(); | ||||
|                             }} | ||||
|                             disabled="${this.table?.data?.pagination.previous ? "true" : "false"}" | ||||
|                             aria-label="{% trans 'Go to previous page' %}" | ||||
|                         > | ||||
|                             <i class="fas fa-angle-left" aria-hidden="true"></i> | ||||
|                         </button> | ||||
|                     </div> | ||||
|                     <div class="pf-c-pagination__nav-control pf-m-next"> | ||||
|                         <button | ||||
|                             class="pf-c-button pf-m-plain" | ||||
|                             @click=${() => { | ||||
|                                 this.nextHandler(); | ||||
|                             }} | ||||
|                             disabled="${this.table?.data?.pagination.next ? "true" : "false"}" | ||||
|                             aria-label="{% trans 'Go to next page' %}" | ||||
|                         > | ||||
|                             <i class="fas fa-angle-right" aria-hidden="true"></i> | ||||
|                         </button> | ||||
|                     </div> | ||||
|                 </nav> | ||||
|             </div> | ||||
|         </div>`; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer