@servicetitan/table 22.4.5 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/demo/column-hiding/index.d.ts +2 -0
  3. package/dist/demo/column-hiding/index.d.ts.map +1 -0
  4. package/dist/demo/column-hiding/index.js +2 -0
  5. package/dist/demo/column-hiding/index.js.map +1 -0
  6. package/dist/demo/column-hiding/product.d.ts +27 -0
  7. package/dist/demo/column-hiding/product.d.ts.map +1 -0
  8. package/dist/demo/column-hiding/product.js +16 -0
  9. package/dist/demo/column-hiding/product.js.map +1 -0
  10. package/dist/demo/column-hiding/products.d.ts +3 -0
  11. package/dist/demo/column-hiding/products.d.ts.map +1 -0
  12. package/dist/demo/column-hiding/products.js +127 -0
  13. package/dist/demo/column-hiding/products.js.map +1 -0
  14. package/dist/demo/column-hiding/table.d.ts +3 -0
  15. package/dist/demo/column-hiding/table.d.ts.map +1 -0
  16. package/dist/demo/column-hiding/table.js +63 -0
  17. package/dist/demo/column-hiding/table.js.map +1 -0
  18. package/dist/demo/column-hiding/table.store.d.ts +9 -0
  19. package/dist/demo/column-hiding/table.store.d.ts.map +1 -0
  20. package/dist/demo/column-hiding/table.store.js +44 -0
  21. package/dist/demo/column-hiding/table.store.js.map +1 -0
  22. package/dist/demo/index.d.ts +1 -0
  23. package/dist/demo/index.d.ts.map +1 -1
  24. package/dist/demo/index.js +1 -0
  25. package/dist/demo/index.js.map +1 -1
  26. package/dist/filters/standard-filter-with-multiselect/filter-cell-ext.d.ts +1 -1
  27. package/dist/filters/standard-filter-with-multiselect/filter-cell-ext.d.ts.map +1 -1
  28. package/dist/table-state.d.ts +3 -1
  29. package/dist/table-state.d.ts.map +1 -1
  30. package/dist/table-state.js +8 -1
  31. package/dist/table-state.js.map +1 -1
  32. package/dist/table.d.ts +3 -1
  33. package/dist/table.d.ts.map +1 -1
  34. package/dist/table.js +28 -4
  35. package/dist/table.js.map +1 -1
  36. package/package.json +24 -24
  37. package/src/demo/column-hiding/index.ts +1 -0
  38. package/src/demo/column-hiding/product.ts +28 -0
  39. package/src/demo/column-hiding/products.ts +127 -0
  40. package/src/demo/column-hiding/table.store.ts +26 -0
  41. package/src/demo/column-hiding/table.tsx +118 -0
  42. package/src/demo/index.ts +1 -0
  43. package/src/filters/standard-filter-with-multiselect/filter-cell-ext.tsx +1 -1
  44. package/src/table-state.ts +18 -2
  45. package/src/table.stories.tsx +15 -0
  46. package/src/table.tsx +29 -6
package/src/demo/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './overview';
2
2
  export * from './master-detail';
3
3
  export * from './state-caching';
4
+ export * from './column-hiding';
@@ -38,7 +38,7 @@ export interface FilterCellExtProps extends TableColumnMenuFilterCellProps {
38
38
  multiselectTagRender?(
39
39
  tagData: MultiSelectTagData,
40
40
  li: ReactElement<HTMLLIElement>
41
- ): ReactElement<HTMLLIElement> | null;
41
+ ): ReactElement<HTMLLIElement>;
42
42
  multiselectListNoDataRender?(element: ReactElement<HTMLDivElement>): ReactNode;
43
43
  }
44
44
 
@@ -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 private get originalData() {
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
- @computed private get totalFilteredSelectableCountPromise() {
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) =>