@@ -2,35 +2,23 @@ import { LitElement, css, html } from "lit";
22import { property , state } from "lit/decorators.js" ;
33import { styles } from "../../core/Manager/src/styles" ;
44import {
5+ TableChildren ,
56 TableDataTransform ,
67 TableGroupData ,
8+ TableLoadFunction ,
9+ TableRow ,
710 TableRowData ,
811 TableRowTemplate ,
12+ ColumnData ,
913} from "./src" ;
1014import { evalCondition , getQuery } from "../../core/utils" ;
1115import { loadingSkeleton } from "./src/loading-skeleton" ;
1216import { processingBar } from "./src/processing-bar" ;
1317
14- /**
15- * Represents a column in the table.
16- *
17- * @property name - The name of the column.
18- * @property width - The width of the column.
19- */
20- export interface ColumnData {
21- /** The name of the column. */
22- name : string ;
23-
24- /** The width of the column. */
25- width : string ;
26-
27- forceDataTransform ?: boolean ;
28- }
29-
3018/**
3119 * A custom table web component for BIM applications. HTML tag: bim-table
3220 */
33- export class Table extends LitElement {
21+ export class Table < T extends TableRowData = TableRowData > extends LitElement {
3422 /**
3523 * CSS styles for the component.
3624 */
@@ -76,10 +64,8 @@ export class Table extends LitElement {
7664 ` ,
7765 ] ;
7866
79- private _columnsChange = new Event ( "columnschange" ) ;
80-
8167 @state ( )
82- private _filteredData : TableGroupData [ ] = [ ] ;
68+ private _filteredData : TableGroupData < T > [ ] = [ ] ;
8369
8470 /**
8571 * A boolean property that determines whether the table headers are hidden.
@@ -108,7 +94,7 @@ export class Table extends LitElement {
10894 @property ( { type : String , attribute : "min-col-width" , reflect : true } )
10995 minColWidth = "4rem" ;
11096
111- private _columns : ColumnData [ ] = [ ] ;
97+ private _columns : ColumnData < T > [ ] = [ ] ;
11298
11399 /**
114100 * Sets the columns for the table.
@@ -130,33 +116,33 @@ export class Table extends LitElement {
130116 * ```
131117 */
132118 @property ( { type : Array , attribute : false } )
133- set columns ( value : ( string | ColumnData ) [ ] ) {
134- const columns : ColumnData [ ] = [ ] ;
119+ set columns ( value : ( keyof T | ColumnData < T > ) [ ] ) {
120+ const columns : ColumnData < T > [ ] = [ ] ;
135121 for ( const header of value ) {
136122 const column =
137123 typeof header === "string"
138124 ? { name : header , width : `minmax(${ this . minColWidth } , 1fr)` }
139- : header ;
125+ : ( header as ColumnData < T > ) ;
140126 columns . push ( column ) ;
141127 }
142128 this . _columns = columns ;
143129 this . computeMissingColumns ( this . data ) ;
144- this . dispatchEvent ( this . _columnsChange ) ;
130+ this . dispatchEvent ( new Event ( "columnschange" ) ) ;
145131 }
146132
147- get columns ( ) : ColumnData [ ] {
133+ get columns ( ) : ColumnData < T > [ ] {
148134 return this . _columns ;
149135 }
150136
151137 private get _headerRowData ( ) {
152- const data : TableRowData = { } ;
138+ const data : Partial < T > = { } ;
153139 for ( const column of this . columns ) {
154- if ( typeof column === "string" ) {
155- data [ column ] = column ;
156- } else {
157- const { name } = column ;
158- data [ name ] = name ;
159- }
140+ // if (typeof column === "string") {
141+ // data[column] = column;
142+ // } else {
143+ const { name } = column ;
144+ ( data [ name ] as any ) = String ( name ) ;
145+ // }
160146 }
161147 return data ;
162148 }
@@ -212,7 +198,7 @@ export class Table extends LitElement {
212198 return this . _queryString ;
213199 }
214200
215- private _data : TableGroupData [ ] = [ ] ;
201+ private _data : TableGroupData < T > [ ] = [ ] ;
216202
217203 /**
218204 * Sets the data for the table.
@@ -232,7 +218,7 @@ export class Table extends LitElement {
232218 * ```
233219 */
234220 @property ( { type : Array , attribute : false } )
235- set data ( value : TableGroupData [ ] ) {
221+ set data ( value : TableGroupData < T > [ ] ) {
236222 this . _data = value ;
237223 this . updateFilteredData ( ) ;
238224 const computed = this . computeMissingColumns ( value ) ;
@@ -302,13 +288,13 @@ export class Table extends LitElement {
302288 *
303289 * @defaultValue An empty object.
304290 */
305- dataTransform : TableDataTransform = { } ;
291+ dataTransform : TableDataTransform < T > = { } ;
306292
307293 @property ( { type : Boolean , reflect : true , attribute : "selectable-rows" } )
308294 selectableRows = false ;
309295
310296 @property ( { attribute : false } )
311- selection : Set < TableRowData > = new Set ( ) ;
297+ selection : Set < Partial < T > > = new Set ( ) ;
312298
313299 @property ( { type : Boolean , attribute : "no-indentation" , reflect : true } )
314300 noIndentation = false ;
@@ -323,8 +309,6 @@ export class Table extends LitElement {
323309
324310 private _hiddenColumns : string [ ] = [ ] ;
325311
326- loadingErrorElement : HTMLElement | null = null ;
327-
328312 set hiddenColumns ( value : string [ ] ) {
329313 this . _hiddenColumns = value ;
330314 setTimeout ( ( ) => {
@@ -364,7 +348,7 @@ export class Table extends LitElement {
364348 }
365349 }
366350
367- private computeMissingColumns ( row : TableGroupData [ ] ) : boolean {
351+ private computeMissingColumns ( row : TableGroupData < T > [ ] ) : boolean {
368352 let computed = false ;
369353 for ( const data of row ) {
370354 const { children, data : rowData } = data ;
@@ -456,17 +440,19 @@ export class Table extends LitElement {
456440 return this . generateText ( "tab" ) ;
457441 }
458442
459- applyDataTransform ( data : TableRowData ) {
460- const declaration : TableRowTemplate = { } ;
443+ applyDataTransform ( data : Partial < T > ) {
444+ const declaration : TableRowTemplate < T > = { } ;
461445 for ( const key of Object . keys ( this . dataTransform ) ) {
462446 const columnConfig = this . columns . find ( ( column ) => column . name === key ) ;
463447 if ( ! ( columnConfig && columnConfig . forceDataTransform ) ) continue ;
464- if ( ! ( key in data ) ) data [ key ] = "" ;
448+ // TODO: Review data[key] as any. Is weird.
449+ if ( ! ( key in data ) ) ( data [ key ] as any ) = "" ;
465450 }
466- for ( const key in data ) {
451+ const _data = data as T ;
452+ for ( const key in _data ) {
467453 const rowDeclaration = this . dataTransform [ key ] ;
468454 if ( rowDeclaration ) {
469- declaration [ key ] = rowDeclaration ( data [ key ] , data ) ;
455+ declaration [ key ] = rowDeclaration ( _data [ key ] , data ) ;
470456 } else {
471457 declaration [ key ] = data [ key ] ;
472458 }
@@ -513,7 +499,7 @@ export class Table extends LitElement {
513499 }
514500
515501 getRowIndentation (
516- target : TableRowData ,
502+ target : Partial < T > ,
517503 tableGroups = this . value ,
518504 level = 0 ,
519505 ) : number | null {
@@ -532,7 +518,7 @@ export class Table extends LitElement {
532518 }
533519
534520 getGroupIndentation (
535- target : TableGroupData ,
521+ target : TableGroupData < T > ,
536522 tableGroups = this . value ,
537523 level = 0 ,
538524 ) : number | null {
@@ -563,7 +549,7 @@ export class Table extends LitElement {
563549 /**
564550 * The function to be executed when loading async data using Table.loadData
565551 */
566- loadFunction ?: ( ) => Promise < TableGroupData [ ] > ;
552+ loadFunction ?: TableLoadFunction < T > ;
567553
568554 /**
569555 * Asynchronously loads data into the table based on Table.loadFunction.
@@ -592,12 +578,17 @@ export class Table extends LitElement {
592578 } catch ( error : any ) {
593579 this . loading = false ;
594580 if ( this . _filteredData . length !== 0 ) return false ; // Do nothing in case the table already had values
581+ const errorSlot = this . querySelector ( "[slot='error-loading']" ) ;
582+ const errorMessageElement = errorSlot ?. querySelector (
583+ "[data-table-element='error-message']" ,
584+ ) ;
595585 if (
596586 error instanceof Error &&
597- this . loadingErrorElement &&
587+ errorMessageElement &&
598588 error . message . trim ( ) !== ""
599- )
600- this . loadingErrorElement . textContent = error . message ;
589+ ) {
590+ errorMessageElement . textContent = error . message ;
591+ }
601592 this . _errorLoading = true ;
602593 return false ;
603594 }
@@ -614,19 +605,22 @@ export class Table extends LitElement {
614605 * If the function returns `true`, the data row will be included in the filtered results.
615606 * If the function returns `false`, the data row will be excluded from the filtered results.
616607 */
617- filterFunction ?: ( queryString : string , data : TableGroupData ) => boolean ;
608+ filterFunction ?: ( queryString : string , data : TableGroupData < T > ) => boolean ;
618609
619610 private _stringFilterFunction = (
620611 queryString : string ,
621- data : TableGroupData ,
612+ data : TableGroupData < T > ,
622613 ) => {
623614 const valueMatch = Object . values ( data . data ) . some ( ( val ) => {
624615 return String ( val ) . toLowerCase ( ) . includes ( queryString . toLowerCase ( ) ) ;
625616 } ) ;
626617 return valueMatch ;
627618 } ;
628619
629- private _queryFilterFunction = ( queryString : string , row : TableGroupData ) => {
620+ private _queryFilterFunction = (
621+ queryString : string ,
622+ row : TableGroupData < T > ,
623+ ) => {
630624 let valueFoundInData = false ;
631625 const query = getQuery ( queryString ) ?? [ ] ;
632626 for ( const search of query ) {
@@ -641,11 +635,11 @@ export class Table extends LitElement {
641635 key = _key ;
642636 const keys = Object . keys ( row . data ) . filter ( ( key ) => key . includes ( _key ) ) ;
643637 const tests = keys . map ( ( key ) =>
644- evalCondition ( row . data [ key ] , condition , value ) ,
638+ evalCondition ( row . data [ key ] ! , condition , value ) ,
645639 ) ;
646640 valueFoundInData = tests . some ( ( test ) => test ) ;
647641 } else {
648- valueFoundInData = evalCondition ( row . data [ key ] , condition , value ) ;
642+ valueFoundInData = evalCondition ( row . data [ key ] ! , condition , value ) ;
649643 }
650644 if ( ! valueFoundInData ) break ;
651645 }
@@ -656,13 +650,13 @@ export class Table extends LitElement {
656650 queryString : string ,
657651 filterFunction = this . filterFunction ?? this . _stringFilterFunction ,
658652 data = this . data ,
659- ) : TableGroupData [ ] {
660- const results : TableGroupData [ ] = [ ] ;
653+ ) : TableGroupData < T > [ ] {
654+ const results : TableGroupData < T > [ ] = [ ] ;
661655 for ( const row of data ) {
662656 const valueMatch = filterFunction ( queryString , row ) ;
663657 if ( valueMatch ) {
664658 if ( this . preserveStructureOnFilter ) {
665- const rowToAdd : TableGroupData = { data : row . data } ;
659+ const rowToAdd : TableGroupData < T > = { data : row . data } ;
666660 if ( row . children ) {
667661 const childResults = this . filter (
668662 queryString ,
@@ -716,7 +710,8 @@ export class Table extends LitElement {
716710 return html `< slot name ="missing-data "> </ slot > ` ;
717711 }
718712
719- const header = document . createElement ( "bim-table-row" ) ;
713+ // @ts -ignore
714+ const header = document . createElement ( "bim-table-row" ) as TableRow < T > ;
720715 header . table = this ;
721716 header . isHeader = true ;
722717 header . data = this . _headerRowData ;
@@ -725,7 +720,10 @@ export class Table extends LitElement {
725720 header . style . top = "0" ;
726721 header . style . zIndex = "5" ;
727722
728- const children = document . createElement ( "bim-table-children" ) ;
723+ // @ts -ignore
724+ const children = document . createElement (
725+ "bim-table-children" ,
726+ ) as TableChildren < T > ;
729727 children . table = this ;
730728 children . data = this . value ;
731729 children . style . gridArea = "Body" ;
0 commit comments