@triptyk/ember-yeti-table 3.0.0 → 3.0.1

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 (130) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +9 -115
  3. package/declarations/components/yeti-table/body.d.ts +32 -0
  4. package/declarations/components/yeti-table/body.d.ts.map +1 -0
  5. package/declarations/components/yeti-table/header.d.ts +33 -0
  6. package/declarations/components/yeti-table/header.d.ts.map +1 -0
  7. package/declarations/components/yeti-table/pagination.d.ts +40 -0
  8. package/declarations/components/yeti-table/pagination.d.ts.map +1 -0
  9. package/declarations/components/yeti-table/table.d.ts +21 -0
  10. package/declarations/components/yeti-table/table.d.ts.map +1 -0
  11. package/declarations/components/yeti-table/tbody/row/cell.d.ts +44 -0
  12. package/declarations/components/yeti-table/tbody/row/cell.d.ts.map +1 -0
  13. package/declarations/components/yeti-table/tbody/row.d.ts +37 -0
  14. package/declarations/components/yeti-table/tbody/row.d.ts.map +1 -0
  15. package/declarations/components/yeti-table/tbody.d.ts +29 -0
  16. package/declarations/components/yeti-table/tbody.d.ts.map +1 -0
  17. package/declarations/components/yeti-table/tfoot/row/cell.d.ts +40 -0
  18. package/declarations/components/yeti-table/tfoot/row/cell.d.ts.map +1 -0
  19. package/declarations/components/yeti-table/tfoot/row.d.ts +37 -0
  20. package/declarations/components/yeti-table/tfoot/row.d.ts.map +1 -0
  21. package/declarations/components/yeti-table/tfoot.d.ts +27 -0
  22. package/declarations/components/yeti-table/tfoot.d.ts.map +1 -0
  23. package/declarations/components/yeti-table/thead/row/cell.d.ts +54 -0
  24. package/declarations/components/yeti-table/thead/row/cell.d.ts.map +1 -0
  25. package/declarations/components/yeti-table/thead/row/column.d.ts +69 -0
  26. package/declarations/components/yeti-table/thead/row/column.d.ts.map +1 -0
  27. package/declarations/components/yeti-table/thead/row.d.ts +55 -0
  28. package/declarations/components/yeti-table/thead/row.d.ts.map +1 -0
  29. package/declarations/components/yeti-table/thead.d.ts +34 -0
  30. package/declarations/components/yeti-table/thead.d.ts.map +1 -0
  31. package/declarations/components/yeti-table.d.ts +107 -0
  32. package/declarations/components/yeti-table.d.ts.map +1 -0
  33. package/declarations/index.d.ts +1 -0
  34. package/declarations/index.d.ts.map +1 -0
  35. package/declarations/template-registry.d.ts +1 -0
  36. package/declarations/template-registry.d.ts.map +1 -0
  37. package/declarations/themes/default-theme.d.ts +3 -27
  38. package/declarations/themes/default-theme.d.ts.map +1 -1
  39. package/declarations/types.d.ts +82 -0
  40. package/declarations/types.d.ts.map +1 -0
  41. package/declarations/utils/create-regex.d.ts +1 -1
  42. package/declarations/utils/create-regex.d.ts.map +1 -1
  43. package/declarations/utils/filtering-utils.d.ts +2 -4
  44. package/declarations/utils/filtering-utils.d.ts.map +1 -1
  45. package/declarations/utils/sorting-utils.d.ts +6 -15
  46. package/declarations/utils/sorting-utils.d.ts.map +1 -1
  47. package/dist/components/yeti-table/body.js +19 -14
  48. package/dist/components/yeti-table/body.js.map +1 -1
  49. package/dist/components/yeti-table/header.js +10 -10
  50. package/dist/components/yeti-table/header.js.map +1 -1
  51. package/dist/components/yeti-table/pagination.js +14 -44
  52. package/dist/components/yeti-table/pagination.js.map +1 -1
  53. package/dist/components/yeti-table/table.js +1 -23
  54. package/dist/components/yeti-table/table.js.map +1 -1
  55. package/dist/components/yeti-table/tbody/row/cell.js +12 -12
  56. package/dist/components/yeti-table/tbody/row/cell.js.map +1 -1
  57. package/dist/components/yeti-table/tbody/row.js +15 -21
  58. package/dist/components/yeti-table/tbody/row.js.map +1 -1
  59. package/dist/components/yeti-table/tbody.js +1 -0
  60. package/dist/components/yeti-table/tbody.js.map +1 -1
  61. package/dist/components/yeti-table/tfoot/row/cell.js +9 -9
  62. package/dist/components/yeti-table/tfoot/row/cell.js.map +1 -1
  63. package/dist/components/yeti-table/tfoot/row.js +11 -11
  64. package/dist/components/yeti-table/tfoot/row.js.map +1 -1
  65. package/dist/components/yeti-table/tfoot.js +1 -0
  66. package/dist/components/yeti-table/tfoot.js.map +1 -1
  67. package/dist/components/yeti-table/thead/row/cell.js +11 -8
  68. package/dist/components/yeti-table/thead/row/cell.js.map +1 -1
  69. package/dist/components/yeti-table/thead/row/column.js +27 -128
  70. package/dist/components/yeti-table/thead/row/column.js.map +1 -1
  71. package/dist/components/yeti-table/thead/row.js +15 -15
  72. package/dist/components/yeti-table/thead/row.js.map +1 -1
  73. package/dist/components/yeti-table/thead.js +3 -22
  74. package/dist/components/yeti-table/thead.js.map +1 -1
  75. package/dist/components/yeti-table.js +99 -303
  76. package/dist/components/yeti-table.js.map +1 -1
  77. package/dist/index.js +2 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/template-registry.js +2 -0
  80. package/dist/template-registry.js.map +1 -0
  81. package/dist/themes/default-theme.js +3 -2
  82. package/dist/themes/default-theme.js.map +1 -1
  83. package/dist/types.js +2 -0
  84. package/dist/types.js.map +1 -0
  85. package/dist/utils/create-regex.js +6 -6
  86. package/dist/utils/create-regex.js.map +1 -1
  87. package/dist/utils/filtering-utils.js +20 -8
  88. package/dist/utils/filtering-utils.js.map +1 -1
  89. package/dist/utils/sorting-utils.js +13 -18
  90. package/dist/utils/sorting-utils.js.map +1 -1
  91. package/package.json +37 -16
  92. package/src/components/yeti-table/{body.gjs → body.gts} +49 -45
  93. package/src/components/yeti-table/header.gts +67 -0
  94. package/src/components/yeti-table/pagination.gts +118 -0
  95. package/src/components/yeti-table/table.gts +27 -0
  96. package/src/components/yeti-table/tbody/row/{cell.gjs → cell.gts} +38 -19
  97. package/src/components/yeti-table/tbody/row.gts +76 -0
  98. package/src/components/yeti-table/tbody.gts +53 -0
  99. package/src/components/yeti-table/tfoot/row/cell.gts +64 -0
  100. package/src/components/yeti-table/tfoot/row.gts +59 -0
  101. package/src/components/yeti-table/tfoot.gts +41 -0
  102. package/src/components/yeti-table/thead/row/{cell.gjs → cell.gts} +36 -13
  103. package/src/components/yeti-table/thead/row/column.gts +177 -0
  104. package/src/components/yeti-table/thead/row.gts +105 -0
  105. package/src/components/yeti-table/thead.gts +65 -0
  106. package/src/components/yeti-table.gts +629 -0
  107. package/src/template-registry.ts +10 -0
  108. package/src/themes/{default-theme.js → default-theme.ts} +5 -1
  109. package/src/types.ts +94 -0
  110. package/src/utils/{create-regex.js → create-regex.ts} +10 -10
  111. package/src/utils/filtering-utils.ts +91 -0
  112. package/src/utils/{sorting-utils.js → sorting-utils.ts} +35 -26
  113. package/dist/_app_/themes/default-theme.js +0 -1
  114. package/dist/_app_/utils/create-regex.js +0 -1
  115. package/dist/_app_/utils/filtering-utils.js +0 -1
  116. package/dist/_app_/utils/sorting-utils.js +0 -1
  117. package/src/components/yeti-table/header.gjs +0 -54
  118. package/src/components/yeti-table/pagination.gjs +0 -155
  119. package/src/components/yeti-table/table.gjs +0 -34
  120. package/src/components/yeti-table/tbody/row.gjs +0 -89
  121. package/src/components/yeti-table/tbody.gjs +0 -55
  122. package/src/components/yeti-table/tfoot/row/cell.gjs +0 -45
  123. package/src/components/yeti-table/tfoot/row.gjs +0 -44
  124. package/src/components/yeti-table/tfoot.gjs +0 -33
  125. package/src/components/yeti-table/thead/row/column.gjs +0 -260
  126. package/src/components/yeti-table/thead/row.gjs +0 -71
  127. package/src/components/yeti-table/thead.gjs +0 -45
  128. package/src/components/yeti-table.gjs +0 -780
  129. package/src/utils/filtering-utils.js +0 -75
  130. /package/src/{.gitkeep → index.ts} +0 -0
@@ -0,0 +1,629 @@
1
+ import { getOwner } from '@ember/application';
2
+ import { action, notifyPropertyChange } from '@ember/object';
3
+ import { later, schedule, scheduleOnce } from '@ember/runloop';
4
+ import { isEmpty, isPresent } from '@ember/utils';
5
+ import Component from '@glimmer/component';
6
+ import { cached, tracked } from '@glimmer/tracking';
7
+ import Helper from '@ember/component/helper';
8
+ import type Owner from '@ember/owner';
9
+
10
+ import merge from 'deepmerge';
11
+ import { use } from 'ember-resources';
12
+ import { trackedFunction } from 'reactiveweb/function';
13
+ import { keepLatest } from 'reactiveweb/keep-latest';
14
+ import { dedupeTracked, localCopy } from 'tracked-toolbox';
15
+
16
+ import { hash } from '@ember/helper';
17
+
18
+ import DEFAULT_THEME from '../themes/default-theme.ts';
19
+ import filterData from '../utils/filtering-utils.ts';
20
+ import {
21
+ compareValues,
22
+ mergeSort,
23
+ sortMultiple,
24
+ } from '../utils/sorting-utils.ts';
25
+
26
+ import Table from './yeti-table/table.gts';
27
+ import HeaderComponent from './yeti-table/header.gts';
28
+ import THead from './yeti-table/thead.gts';
29
+ import Body from './yeti-table/body.gts';
30
+ import TBody from './yeti-table/tbody.gts';
31
+ import TFoot from './yeti-table/tfoot.gts';
32
+ import Pagination from './yeti-table/pagination.gts';
33
+ import type Column from './yeti-table/thead/row/column.gts';
34
+ import type {
35
+ LoadDataParams,
36
+ PaginationData,
37
+ Row,
38
+ RowFilterFunction,
39
+ SortDirection,
40
+ Theme,
41
+ } from '../types.ts';
42
+ import type { Comparator } from '../utils/sorting-utils.ts';
43
+ import type { WithBoundArgs } from '@glint/template';
44
+
45
+ const TASK_CANCELATION_NAME = 'TaskCancelation';
46
+ const didCancel = function (e: unknown): boolean {
47
+ return !!e && (e as { name?: string }).name === TASK_CANCELATION_NAME;
48
+ };
49
+
50
+ function getConfigWithDefault<T>(key: string, defaultValue: T): () => T {
51
+ return function (this: YetiTable): T {
52
+ return (this.config[key] as T | undefined) ?? defaultValue;
53
+ };
54
+ }
55
+
56
+ interface HelperNamed {
57
+ context: YetiTable;
58
+ }
59
+
60
+ interface UpdateTotalRowsSignature {
61
+ Args: { Positional: [number | undefined]; Named: HelperNamed };
62
+ Return: '';
63
+ }
64
+
65
+ class UpdateTotalRows extends Helper<UpdateTotalRowsSignature> {
66
+ compute(positional: [number | undefined], { context }: HelperNamed): '' {
67
+ context.totalRows = positional[0];
68
+ notifyPropertyChange(context, 'normalizedTotalRows');
69
+ notifyPropertyChange(context, 'paginationData');
70
+ return '';
71
+ }
72
+ }
73
+
74
+ interface UpdateFilterSignature {
75
+ Args: { Positional: [string | undefined]; Named: HelperNamed };
76
+ Return: '';
77
+ }
78
+
79
+ class UpdateFilter extends Helper<UpdateFilterSignature> {
80
+ compute(positional: [string | undefined], { context }: HelperNamed): '' {
81
+ context.filter = positional[0] || '';
82
+ return '';
83
+ }
84
+ }
85
+
86
+ interface ProcessedDataSignature {
87
+ Args: {
88
+ Positional: [];
89
+ Named: {
90
+ loadData?: YetiTable['args']['loadData'];
91
+ context: YetiTable;
92
+ };
93
+ };
94
+ Return: '';
95
+ }
96
+
97
+ class ProcessedData extends Helper<ProcessedDataSignature> {
98
+ compute(
99
+ _positional: [],
100
+ {
101
+ loadData,
102
+ context,
103
+ }: {
104
+ loadData?: YetiTable['args']['loadData'];
105
+ context: YetiTable;
106
+ },
107
+ ): '' {
108
+ const data = context.latestData ?? [];
109
+
110
+ if (!loadData) {
111
+ context.processData(data);
112
+ } else {
113
+ context.processedData = data;
114
+ }
115
+ return '';
116
+ }
117
+ }
118
+
119
+ export type YetiTableLoadData = (
120
+ params: LoadDataParams,
121
+ ) => Row[] | Promise<Row[]>;
122
+
123
+ export interface YetiTableSignature {
124
+ Element: HTMLElement;
125
+ Args: {
126
+ data?: Row[] | Promise<Row[]>;
127
+ loadData?: YetiTableLoadData;
128
+ theme?: Partial<Theme>;
129
+ pagination?: boolean;
130
+ pageSize?: number;
131
+ pageNumber?: number;
132
+ totalRows?: number;
133
+ filter?: string;
134
+ filterFunction?: RowFilterFunction;
135
+ filterUsing?: unknown;
136
+ sortable?: boolean;
137
+ sortFunction?: (
138
+ itemA: Row,
139
+ itemB: Row,
140
+ sorts: { prop: string; direction: SortDirection }[],
141
+ compareFn: Comparator,
142
+ ) => number;
143
+ compareFunction?: Comparator;
144
+ sortSequence?: SortDirection[] | string;
145
+ ignoreDataChanges?: boolean;
146
+ renderTableElement?: boolean;
147
+ isColumnVisible?: (column: Column) => boolean;
148
+ registerApi?: (api: YetiTable['publicApi']) => void;
149
+ };
150
+ Blocks: {
151
+ default: [
152
+ {
153
+ table: WithBoundArgs<typeof Table, 'theme' | 'parent'>;
154
+ header: WithBoundArgs<
155
+ typeof HeaderComponent,
156
+ | 'columns'
157
+ | 'onColumnClick'
158
+ | 'sortable'
159
+ | 'sortSequence'
160
+ | 'parent'
161
+ | 'theme'
162
+ >;
163
+ thead: WithBoundArgs<
164
+ typeof THead,
165
+ | 'columns'
166
+ | 'onColumnClick'
167
+ | 'sortable'
168
+ | 'sortSequence'
169
+ | 'theme'
170
+ | 'parent'
171
+ >;
172
+ body: WithBoundArgs<typeof Body, 'data' | 'columns' | 'theme'>;
173
+ tbody: WithBoundArgs<typeof TBody, 'data' | 'columns' | 'theme'>;
174
+ tfoot: WithBoundArgs<typeof TFoot, 'columns' | 'theme' | 'parent'>;
175
+ pagination: WithBoundArgs<
176
+ typeof Pagination,
177
+ 'disabled' | 'theme' | 'paginationData' | 'paginationActions'
178
+ >;
179
+ actions: YetiTable['publicApi'];
180
+ paginationData: PaginationData;
181
+ isLoading: boolean;
182
+ columns: Column[];
183
+ visibleColumns: Column[];
184
+ rows: Row[] | undefined;
185
+ totalRows: number;
186
+ visibleRows: Row[] | undefined;
187
+ theme: Theme;
188
+ },
189
+ ];
190
+ };
191
+ }
192
+
193
+ export default class YetiTable extends Component<YetiTableSignature> {
194
+ publicApi = {
195
+ previousPage: () => this.previousPage(),
196
+ nextPage: () => this.nextPage(),
197
+ goToPage: (n: number) => this.goToPage(n),
198
+ changePageSize: (n: number | string) => this.changePageSize(n),
199
+ reloadData: () => this.reloadData(),
200
+ };
201
+
202
+ @localCopy('args.pagination', getConfigWithDefault('pagination', false))
203
+ pagination!: boolean;
204
+
205
+ @localCopy('args.pageSize', getConfigWithDefault('pageSize', 15))
206
+ pageSize!: number;
207
+
208
+ @localCopy('args.pageNumber', 1)
209
+ pageNumber!: number;
210
+
211
+ totalRows: number | undefined;
212
+
213
+ @dedupeTracked
214
+ filter = '';
215
+
216
+ @localCopy('args.sortable', getConfigWithDefault('sortable', true))
217
+ sortable!: boolean;
218
+
219
+ @localCopy('args.sortFunction', () => sortMultiple)
220
+ sortFunction!: YetiTableSignature['Args']['sortFunction'];
221
+
222
+ @localCopy('args.compareFunction', () => compareValues)
223
+ compareFunction!: Comparator;
224
+
225
+ @localCopy(
226
+ 'args.sortSequence',
227
+ getConfigWithDefault('sortSequence', ['asc', 'desc']),
228
+ )
229
+ sortSequence!: SortDirection[] | string;
230
+
231
+ @localCopy(
232
+ 'args.ignoreDataChanges',
233
+ getConfigWithDefault('ignoreDataChanges', false),
234
+ )
235
+ ignoreDataChanges!: boolean;
236
+
237
+ @localCopy('args.renderTableElement', true)
238
+ renderTableElement!: boolean;
239
+
240
+ @cached
241
+ get mergedTheme(): Theme {
242
+ const configTheme = (this.config.theme as Partial<Theme>) || {};
243
+ const localTheme = this.args.theme || {};
244
+ return merge.all([DEFAULT_THEME, configTheme, localTheme]) as Theme;
245
+ }
246
+
247
+ @cached
248
+ get visibleColumns(): Column[] {
249
+ return this.columns.filter((c) => c.visible === true);
250
+ }
251
+
252
+ config: Record<string, unknown> =
253
+ (
254
+ (
255
+ getOwner(this) as {
256
+ resolveRegistration?: (name: string) => unknown;
257
+ } | null
258
+ )?.resolveRegistration?.('config:environment') as
259
+ | Record<string, Record<string, unknown>>
260
+ | undefined
261
+ )?.['ember-yeti-table'] || {};
262
+
263
+ get normalizedTotalRows(): number {
264
+ if (!this.args.loadData) {
265
+ return this.processedDataRows?.length || 0;
266
+ } else {
267
+ if (this.totalRows === undefined) {
268
+ return this.previousResolvedData.length || 0;
269
+ } else {
270
+ return this.totalRows;
271
+ }
272
+ }
273
+ }
274
+
275
+ get normalizedRows(): Row[] | undefined {
276
+ if (!this.args.loadData) {
277
+ return this.processedDataRows;
278
+ } else {
279
+ return this.processedData;
280
+ }
281
+ }
282
+
283
+ get paginationData(): PaginationData {
284
+ const pageSize = this.pageSize;
285
+ let pageNumber = this.pageNumber;
286
+ const totalRows = this.normalizedTotalRows;
287
+ let isLastPage: boolean | undefined;
288
+ let totalPages: number | undefined;
289
+
290
+ if (totalRows) {
291
+ totalPages = Math.ceil(totalRows / pageSize);
292
+ pageNumber = Math.min(pageNumber, totalPages);
293
+ isLastPage = pageNumber === totalPages;
294
+ }
295
+
296
+ const isFirstPage = pageNumber === 1;
297
+ const pageStart = (pageNumber - 1) * pageSize + 1;
298
+ let pageEnd = pageStart + pageSize - 1;
299
+
300
+ if (totalRows) {
301
+ pageEnd = Math.min(pageEnd, totalRows);
302
+ }
303
+
304
+ return {
305
+ pageSize,
306
+ pageNumber,
307
+ pageStart,
308
+ pageEnd,
309
+ isFirstPage,
310
+ isLastPage,
311
+ totalRows,
312
+ totalPages,
313
+ };
314
+ }
315
+
316
+ @tracked
317
+ columns: Column[] = [];
318
+
319
+ previousResolvedData: Row[] = [];
320
+
321
+ @tracked
322
+ processedData: Row[] | undefined;
323
+
324
+ @tracked
325
+ processedDataRows: Row[] | undefined;
326
+
327
+ resolvedData = trackedFunction(this, async () => {
328
+ let data: Row[] | Promise<Row[]> | undefined = this.args.data;
329
+
330
+ if (this.columns.length == 0) {
331
+ return [] as Row[];
332
+ }
333
+
334
+ if (typeof this.args.loadData === 'function') {
335
+ const params = this.computeLoadDataParams();
336
+
337
+ try {
338
+ data = await this.args.loadData(params);
339
+ } catch (e) {
340
+ console.log(e);
341
+
342
+ if (!didCancel(e)) {
343
+ throw e;
344
+ }
345
+ }
346
+ } else if (data && typeof (data as Promise<Row[]>).then === 'function') {
347
+ data = await data;
348
+ }
349
+
350
+ if (this.isDestroyed) {
351
+ return;
352
+ }
353
+
354
+ const resolved = (data as Row[] | undefined) || [];
355
+
356
+ this.previousResolvedData = resolved;
357
+
358
+ return resolved;
359
+ });
360
+
361
+ @use latestData = keepLatest({
362
+ value: () => this.resolvedData.value ?? [],
363
+ when: () => this.resolvedData.isPending,
364
+ });
365
+
366
+ constructor(owner: Owner, args: YetiTableSignature['Args']) {
367
+ super(owner, args);
368
+
369
+ if (typeof this.args.registerApi === 'function') {
370
+ // eslint-disable-next-line ember/no-runloop
371
+ scheduleOnce('actions', null, this.args.registerApi, this.publicApi);
372
+ }
373
+ }
374
+
375
+ processData(data: Row[]): void {
376
+ const columns = this.columns.filter(
377
+ (c) => c.filterable && isPresent(c.prop),
378
+ );
379
+
380
+ const sortableColumns = this.columns.filter((c) => !isEmpty(c.sort));
381
+ const sortings = sortableColumns.map((c) => ({
382
+ prop: c.prop as string,
383
+ direction: c.sort as SortDirection,
384
+ }));
385
+
386
+ const filterFunction = this.args.filterFunction;
387
+ const filterUsing = this.args.filterUsing;
388
+ const filter = this.filter;
389
+
390
+ const processTheData = (): void => {
391
+ let working = filterData(
392
+ data,
393
+ columns,
394
+ filter,
395
+ filterFunction,
396
+ filterUsing,
397
+ );
398
+
399
+ if (sortings.length > 0) {
400
+ working = mergeSort(working, (itemA, itemB) => {
401
+ return this.sortFunction!(
402
+ itemA,
403
+ itemB,
404
+ sortings,
405
+ this.compareFunction,
406
+ );
407
+ });
408
+ }
409
+
410
+ this.processedDataRows = working;
411
+
412
+ if (this.pagination) {
413
+ const { pageStart, pageEnd } = this.paginationData;
414
+ working = working.slice(pageStart - 1, pageEnd);
415
+ }
416
+
417
+ this.processedData = working;
418
+ };
419
+
420
+ if (this.ignoreDataChanges) {
421
+ // eslint-disable-next-line ember/no-runloop
422
+ later(processTheData, 0);
423
+ } else {
424
+ processTheData();
425
+ }
426
+ }
427
+
428
+ computeLoadDataParams(): LoadDataParams {
429
+ const params: LoadDataParams = {
430
+ sortData: this.columns
431
+ .filter((c) => !isEmpty(c.sort))
432
+ .map((c) => ({ prop: c.prop, direction: c.sort })),
433
+ filterData: {
434
+ filter: this.filter,
435
+ filterUsing: this.args.filterUsing,
436
+ columnFilters: this.columns.map((c) => ({
437
+ prop: c.prop,
438
+ filter: c.filter,
439
+ filterUsing: c.filterUsing,
440
+ })),
441
+ },
442
+ };
443
+
444
+ if (this.pagination) {
445
+ params.paginationData = this.paginationData;
446
+ }
447
+
448
+ return params;
449
+ }
450
+
451
+ paginateData(data: Row[]): Row[] {
452
+ if (this.pagination) {
453
+ const { pageStart, pageEnd } = this.paginationData;
454
+ data = data.slice(pageStart - 1, pageEnd);
455
+ }
456
+
457
+ return data;
458
+ }
459
+
460
+ @action
461
+ async reloadData(): Promise<unknown> {
462
+ return await this.resolvedData.retry();
463
+ }
464
+
465
+ @action
466
+ onColumnSort(column: Column, e: MouseEvent): void {
467
+ if (column.isSorted) {
468
+ let direction: SortDirection | null | undefined = column.sort;
469
+ const sortSequence = column.normalizedSortSequence;
470
+ direction = sortSequence[
471
+ (sortSequence.indexOf(direction as string) + 1) % sortSequence.length
472
+ ] as SortDirection;
473
+
474
+ if ((direction as unknown as string) === 'unsorted') {
475
+ direction = null;
476
+ }
477
+ column.sort = direction;
478
+
479
+ if (!e.shiftKey) {
480
+ const columns = this.columns.filter((c) => c !== column);
481
+ columns.forEach((c) => (c.sort = null));
482
+ }
483
+ } else {
484
+ const direction = column.normalizedSortSequence[0] as SortDirection;
485
+ column.sort = direction;
486
+
487
+ if (!e.shiftKey) {
488
+ const columns = this.columns.filter((c) => c !== column);
489
+ columns.forEach((c) => (c.sort = null));
490
+ }
491
+ }
492
+ }
493
+
494
+ @action
495
+ previousPage(): void {
496
+ if (this.pagination) {
497
+ this.pageNumber = Math.max(this.pageNumber - 1, 1);
498
+ }
499
+ }
500
+
501
+ @action
502
+ nextPage(): void {
503
+ if (this.pagination) {
504
+ const { isLastPage } = this.paginationData;
505
+
506
+ if (!isLastPage) {
507
+ this.pageNumber = this.pageNumber + 1;
508
+ }
509
+ }
510
+ }
511
+
512
+ @action
513
+ goToPage(pageNumber: number): void {
514
+ if (this.pagination) {
515
+ const { totalPages } = this.paginationData;
516
+ pageNumber = Math.max(pageNumber, 1);
517
+
518
+ if (totalPages) {
519
+ pageNumber = Math.min(pageNumber, totalPages);
520
+ }
521
+
522
+ this.pageNumber = pageNumber;
523
+ }
524
+ }
525
+
526
+ @action
527
+ changePageSize(pageSize: number | string): void {
528
+ if (this.pagination) {
529
+ this.pageSize = parseInt(String(pageSize));
530
+ }
531
+ }
532
+
533
+ registerColumn(column: Column): void {
534
+ // eslint-disable-next-line ember/no-runloop
535
+ schedule('afterRender', this, function (this: YetiTable) {
536
+ if (typeof this.args.isColumnVisible === 'function') {
537
+ column.visible = this.args.isColumnVisible(column);
538
+ }
539
+
540
+ if (!this.columns.includes(column)) {
541
+ this.columns = [...this.columns, column];
542
+ }
543
+ });
544
+ }
545
+
546
+ unregisterColumn(column: Column): void {
547
+ if (this.columns.includes(column)) {
548
+ this.columns = this.columns.filter((c) => c !== column);
549
+ }
550
+ }
551
+
552
+ <template>
553
+ {{#let
554
+ (hash
555
+ table=(component Table theme=this.mergedTheme parent=this)
556
+ header=(component
557
+ HeaderComponent
558
+ columns=this.columns
559
+ onColumnClick=this.onColumnSort
560
+ sortable=this.sortable
561
+ sortSequence=this.sortSequence
562
+ parent=this
563
+ theme=this.mergedTheme
564
+ )
565
+ thead=(component
566
+ THead
567
+ columns=this.columns
568
+ onColumnClick=this.onColumnSort
569
+ sortable=this.sortable
570
+ sortSequence=this.sortSequence
571
+ theme=this.mergedTheme
572
+ parent=this
573
+ )
574
+ body=(component
575
+ Body
576
+ data=this.processedData
577
+ columns=this.columns
578
+ theme=this.mergedTheme
579
+ parent=this
580
+ )
581
+ tbody=(component
582
+ TBody
583
+ data=this.processedData
584
+ columns=this.columns
585
+ theme=this.mergedTheme
586
+ parent=this
587
+ )
588
+ tfoot=(component
589
+ TFoot columns=this.columns theme=this.mergedTheme parent=this
590
+ )
591
+ pagination=(component
592
+ Pagination
593
+ disabled=this.resolvedData.isPending
594
+ theme=this.mergedTheme
595
+ paginationData=this.paginationData
596
+ paginationActions=(hash
597
+ previousPage=this.previousPage
598
+ nextPage=this.nextPage
599
+ goToPage=this.goToPage
600
+ changePageSize=this.changePageSize
601
+ )
602
+ )
603
+ actions=this.publicApi
604
+ paginationData=this.paginationData
605
+ isLoading=this.resolvedData.isPending
606
+ columns=this.columns
607
+ visibleColumns=this.visibleColumns
608
+ rows=this.normalizedRows
609
+ totalRows=this.normalizedTotalRows
610
+ visibleRows=this.processedData
611
+ theme=this.mergedTheme
612
+ )
613
+ as |api|
614
+ }}
615
+ {{UpdateTotalRows @totalRows context=this}}
616
+ {{UpdateFilter @filter context=this}}
617
+ {{ProcessedData loadData=@loadData context=this}}
618
+
619
+ {{#if this.renderTableElement}}
620
+ <Table @theme={{this.mergedTheme}} @parent={{this}} ...attributes>
621
+ {{yield api}}
622
+ </Table>
623
+ {{else}}
624
+ {{yield api}}
625
+ {{/if}}
626
+
627
+ {{/let}}
628
+ </template>
629
+ }
@@ -0,0 +1,10 @@
1
+ // Easily allow apps, which are not yet using strict mode templates, to consume your Glint types, by importing this file.
2
+ // Add all your components, helpers and modifiers to the template registry here, so apps don't have to do this.
3
+ // See https://typed-ember.gitbook.io/glint/environments/ember/authoring-addons
4
+
5
+ // import type MyComponent from './components/my-component';
6
+
7
+ // Uncomment this once entries have been added! 👇
8
+ // export default interface Registry {
9
+ // MyComponent: typeof MyComponent
10
+ // }
@@ -1,5 +1,7 @@
1
1
  // BEGIN-SNIPPET default-theme.js
2
- export default {
2
+ import type { Theme } from '../types.ts';
3
+
4
+ const defaultTheme: Theme = {
3
5
  // applied to the <table> element
4
6
  table: 'yeti-table',
5
7
  // applied to any <tr>, wether it is from the header, body or footer
@@ -50,4 +52,6 @@ export default {
50
52
  previous: 'yeti-table-pagination-controls-previous',
51
53
  },
52
54
  };
55
+
56
+ export default defaultTheme;
53
57
  // END-SNIPPET