@servicetitan/table 22.4.5 → 23.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +33 -0
- package/dist/demo/column-hiding/index.d.ts +2 -0
- package/dist/demo/column-hiding/index.d.ts.map +1 -0
- package/dist/demo/column-hiding/index.js +2 -0
- package/dist/demo/column-hiding/index.js.map +1 -0
- package/dist/demo/column-hiding/product.d.ts +27 -0
- package/dist/demo/column-hiding/product.d.ts.map +1 -0
- package/dist/demo/column-hiding/product.js +16 -0
- package/dist/demo/column-hiding/product.js.map +1 -0
- package/dist/demo/column-hiding/products.d.ts +3 -0
- package/dist/demo/column-hiding/products.d.ts.map +1 -0
- package/dist/demo/column-hiding/products.js +127 -0
- package/dist/demo/column-hiding/products.js.map +1 -0
- package/dist/demo/column-hiding/table.d.ts +3 -0
- package/dist/demo/column-hiding/table.d.ts.map +1 -0
- package/dist/demo/column-hiding/table.js +63 -0
- package/dist/demo/column-hiding/table.js.map +1 -0
- package/dist/demo/column-hiding/table.store.d.ts +9 -0
- package/dist/demo/column-hiding/table.store.d.ts.map +1 -0
- package/dist/demo/column-hiding/table.store.js +44 -0
- package/dist/demo/column-hiding/table.store.js.map +1 -0
- package/dist/demo/index.d.ts +1 -0
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +1 -0
- package/dist/demo/index.js.map +1 -1
- package/dist/filters/standard-filter-with-multiselect/filter-cell-ext.d.ts +1 -1
- package/dist/filters/standard-filter-with-multiselect/filter-cell-ext.d.ts.map +1 -1
- package/dist/table-state.d.ts +3 -1
- package/dist/table-state.d.ts.map +1 -1
- package/dist/table-state.js +8 -1
- package/dist/table-state.js.map +1 -1
- package/dist/table.d.ts +3 -1
- package/dist/table.d.ts.map +1 -1
- package/dist/table.js +28 -4
- package/dist/table.js.map +1 -1
- package/package.json +24 -24
- package/src/demo/column-hiding/index.ts +1 -0
- package/src/demo/column-hiding/product.ts +28 -0
- package/src/demo/column-hiding/products.ts +127 -0
- package/src/demo/column-hiding/table.store.ts +26 -0
- package/src/demo/column-hiding/table.tsx +118 -0
- package/src/demo/index.ts +1 -0
- package/src/filters/standard-filter-with-multiselect/filter-cell-ext.tsx +1 -1
- package/src/table-state.ts +18 -2
- package/src/table.stories.tsx +15 -0
- package/src/table.tsx +29 -6
package/src/demo/index.ts
CHANGED
@@ -38,7 +38,7 @@ export interface FilterCellExtProps extends TableColumnMenuFilterCellProps {
|
|
38
38
|
multiselectTagRender?(
|
39
39
|
tagData: MultiSelectTagData,
|
40
40
|
li: ReactElement<HTMLLIElement>
|
41
|
-
): ReactElement<HTMLLIElement
|
41
|
+
): ReactElement<HTMLLIElement>;
|
42
42
|
multiselectListNoDataRender?(element: ReactElement<HTMLDivElement>): ReactNode;
|
43
43
|
}
|
44
44
|
|
package/src/table-state.ts
CHANGED
@@ -86,6 +86,7 @@ interface TableStateConstructorParams<
|
|
86
86
|
getDetailTableState?: (row: T) => TableState<any, any, any, any> | undefined;
|
87
87
|
initialState?: TableStateModel<TId>;
|
88
88
|
alwaysEditable?: boolean;
|
89
|
+
rowIdKey?: string;
|
89
90
|
}
|
90
91
|
|
91
92
|
interface FetchDataParams {
|
@@ -128,6 +129,7 @@ export interface ITableState<T, TId extends IdType = never> {
|
|
128
129
|
|
129
130
|
export class TableState<T, TId extends IdType = never, P = never, PId extends IdType = never> {
|
130
131
|
@observable private innerDataSource: DataSource<T, TId> | null;
|
132
|
+
|
131
133
|
@computed get dataSource() {
|
132
134
|
return this.innerDataSource;
|
133
135
|
}
|
@@ -157,7 +159,8 @@ export class TableState<T, TId extends IdType = never, P = never, PId extends Id
|
|
157
159
|
}
|
158
160
|
}
|
159
161
|
|
160
|
-
@computed
|
162
|
+
@computed
|
163
|
+
private get originalData() {
|
161
164
|
const result: Selectable<T>[] = [];
|
162
165
|
|
163
166
|
this.traverse(this.data, item => {
|
@@ -188,19 +191,25 @@ export class TableState<T, TId extends IdType = never, P = never, PId extends Id
|
|
188
191
|
@observable filteredCount = 0;
|
189
192
|
@observable selectedCount = 0;
|
190
193
|
@observable unselectableCount = 0;
|
194
|
+
|
191
195
|
@computed get unselectedCount() {
|
192
196
|
return this.totalCount - this.selectedCount;
|
193
197
|
}
|
198
|
+
|
194
199
|
@computed get selectableCount() {
|
195
200
|
return this.totalCount - this.unselectableCount;
|
196
201
|
}
|
202
|
+
|
197
203
|
@computed get filteredUnselectableCount() {
|
198
204
|
return this.originalData.filter(this.isRowUnselectable).length;
|
199
205
|
}
|
206
|
+
|
200
207
|
@computed get filteredSelectableCount() {
|
201
208
|
return this.originalData.length - this.filteredUnselectableCount;
|
202
209
|
}
|
203
|
-
|
210
|
+
|
211
|
+
@computed
|
212
|
+
private get totalFilteredSelectableCountPromise() {
|
204
213
|
return fromPromise(
|
205
214
|
new Promise<number>((resolve, reject) => {
|
206
215
|
if (!this.dataSource) {
|
@@ -221,19 +230,23 @@ export class TableState<T, TId extends IdType = never, P = never, PId extends Id
|
|
221
230
|
})
|
222
231
|
);
|
223
232
|
}
|
233
|
+
|
224
234
|
@computed get totalFilteredSelectableCount(): number {
|
225
235
|
return (this.totalFilteredSelectableCountPromise.value as number) || 0;
|
226
236
|
}
|
237
|
+
|
227
238
|
@observable sort: SortDescriptor[] = [];
|
228
239
|
@observable filter: CompositeFilterDescriptor | undefined;
|
229
240
|
|
230
241
|
@observable aggregates: AggregateDescriptor[] = [];
|
231
242
|
|
232
243
|
@observable innerGroup: GroupDescriptor[] = [];
|
244
|
+
|
233
245
|
@computed
|
234
246
|
get group(): GroupDescriptor[] {
|
235
247
|
return addAggregatesToGroups(this.innerGroup, this.aggregates);
|
236
248
|
}
|
249
|
+
|
237
250
|
set group(value: GroupDescriptor[]) {
|
238
251
|
this.innerGroup = value;
|
239
252
|
}
|
@@ -244,10 +257,12 @@ export class TableState<T, TId extends IdType = never, P = never, PId extends Id
|
|
244
257
|
private tablePdfExport: TablePDFExport | null = null;
|
245
258
|
private tableExcelExport: ExcelExport | null = null;
|
246
259
|
|
260
|
+
rowIdKey?: string;
|
247
261
|
alwaysEditable: boolean;
|
248
262
|
|
249
263
|
constructor({
|
250
264
|
dataSource = null,
|
265
|
+
rowIdKey,
|
251
266
|
pageSize,
|
252
267
|
isRowUnselectable = () => false,
|
253
268
|
selectionLimit = Infinity,
|
@@ -263,6 +278,7 @@ export class TableState<T, TId extends IdType = never, P = never, PId extends Id
|
|
263
278
|
this.pageSize = pageSize;
|
264
279
|
this.isRowUnselectable = isRowUnselectable;
|
265
280
|
this.selectionLimit = selectionLimit;
|
281
|
+
this.rowIdKey = rowIdKey;
|
266
282
|
|
267
283
|
this.getFormState = getFormState;
|
268
284
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import {
|
2
|
+
TableExample,
|
3
|
+
TableMasterDetailExample,
|
4
|
+
TableStateCachingExample,
|
5
|
+
TableColumnHidingExample
|
6
|
+
} from '../dist/demo';
|
7
|
+
|
8
|
+
export default {
|
9
|
+
title: 'Table/Demos'
|
10
|
+
};
|
11
|
+
|
12
|
+
export const Table = () => <TableExample />;
|
13
|
+
export const TableMasterDetail = () => <TableMasterDetailExample />;
|
14
|
+
export const TableStateCaching = () => <TableStateCachingExample />;
|
15
|
+
export const TableColumnHiding = () => <TableColumnHidingExample />;
|
package/src/table.tsx
CHANGED
@@ -81,6 +81,7 @@ interface TableColumnProps<
|
|
81
81
|
|
82
82
|
type ExcludedTableProps =
|
83
83
|
| 'data'
|
84
|
+
| 'dataItemKey'
|
84
85
|
| 'editField'
|
85
86
|
| 'filter'
|
86
87
|
| 'onFilterChange'
|
@@ -133,6 +134,8 @@ export class Table<
|
|
133
134
|
/>
|
134
135
|
));
|
135
136
|
|
137
|
+
private customCellMap = new Map<string, FC<TableCellProps<T, TId, P, PId>>>();
|
138
|
+
|
136
139
|
private selectHeaderCell: FC<TableHeaderCellProps> = observer((props: TableHeaderCellProps) => {
|
137
140
|
if (this.props.hideSelectAll || this.tableState.selectionLimit !== Infinity) {
|
138
141
|
return null;
|
@@ -154,14 +157,10 @@ export class Table<
|
|
154
157
|
// TODO: rid of "memoizeOne" after migration on React.FC
|
155
158
|
private withCellTableState = memoizeOne((children: ReactNode) =>
|
156
159
|
this.applyToColumns(children, column => {
|
157
|
-
const { cell: Cell } = column.props;
|
160
|
+
const { cell: Cell, field } = column.props;
|
158
161
|
|
159
162
|
return cloneElement(column, {
|
160
|
-
cell:
|
161
|
-
Cell &&
|
162
|
-
((props: TableCellProps<T, TId, P, PId>) => (
|
163
|
-
<Cell {...props} tableState={this.tableState} />
|
164
|
-
)),
|
163
|
+
cell: this.getOrCreateCellComponentWithTableState(Cell, field),
|
165
164
|
});
|
166
165
|
})
|
167
166
|
);
|
@@ -327,6 +326,7 @@ export class Table<
|
|
327
326
|
<AnvilTable
|
328
327
|
ref={this.ref}
|
329
328
|
{...props}
|
329
|
+
dataItemKey={this.tableState.rowIdKey}
|
330
330
|
data={[...this.tableState.data]}
|
331
331
|
rowRender={this.rowRender}
|
332
332
|
editField="inEdit"
|
@@ -354,6 +354,7 @@ export class Table<
|
|
354
354
|
<TableColumn
|
355
355
|
locked
|
356
356
|
field="selected"
|
357
|
+
id="selected"
|
357
358
|
width="50px"
|
358
359
|
filterable={false}
|
359
360
|
resizable={false}
|
@@ -372,6 +373,28 @@ export class Table<
|
|
372
373
|
</AnvilTable>
|
373
374
|
);
|
374
375
|
};
|
376
|
+
|
377
|
+
private getOrCreateCellComponentWithTableState = (
|
378
|
+
Cell: any,
|
379
|
+
field?: string
|
380
|
+
): FC<TableCellProps<T, TId, P, PId>> | undefined => {
|
381
|
+
if (!Cell) {
|
382
|
+
return undefined;
|
383
|
+
}
|
384
|
+
|
385
|
+
const CellWithTableState: FC<TableCellProps<T, TId, P, PId>> = (
|
386
|
+
props: TableCellProps<T, TId, P, PId>
|
387
|
+
) => <Cell {...props} tableState={this.tableState} />;
|
388
|
+
CellWithTableState.displayName = 'CellWithTableState';
|
389
|
+
|
390
|
+
if (field) {
|
391
|
+
if (this.customCellMap.has(field)) {
|
392
|
+
return this.customCellMap.get(field)!;
|
393
|
+
}
|
394
|
+
this.customCellMap.set(field, CellWithTableState);
|
395
|
+
}
|
396
|
+
return CellWithTableState;
|
397
|
+
};
|
375
398
|
}
|
376
399
|
|
377
400
|
const sanitizeExportFileName = memoizeOne((fileName: string | undefined) =>
|