@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.
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) =>