@triptyk/ember-yeti-table 3.0.0 → 3.0.2

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 +102 -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 +633 -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,633 @@
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
+ if (typeof this.args.loadData === 'function') {
332
+ return this.previousResolvedData;
333
+ }
334
+
335
+ return [] as Row[];
336
+ }
337
+
338
+ if (typeof this.args.loadData === 'function') {
339
+ const params = this.computeLoadDataParams();
340
+
341
+ try {
342
+ data = await this.args.loadData(params);
343
+ } catch (e) {
344
+ console.log(e);
345
+
346
+ if (!didCancel(e)) {
347
+ throw e;
348
+ }
349
+ }
350
+ } else if (data && typeof (data as Promise<Row[]>).then === 'function') {
351
+ data = await data;
352
+ }
353
+
354
+ if (this.isDestroyed) {
355
+ return;
356
+ }
357
+
358
+ const resolved = (data as Row[] | undefined) || [];
359
+
360
+ this.previousResolvedData = resolved;
361
+
362
+ return resolved;
363
+ });
364
+
365
+ @use latestData = keepLatest({
366
+ value: () => this.resolvedData.value ?? [],
367
+ when: () => this.resolvedData.isPending,
368
+ });
369
+
370
+ constructor(owner: Owner, args: YetiTableSignature['Args']) {
371
+ super(owner, args);
372
+
373
+ if (typeof this.args.registerApi === 'function') {
374
+ // eslint-disable-next-line ember/no-runloop
375
+ scheduleOnce('actions', null, this.args.registerApi, this.publicApi);
376
+ }
377
+ }
378
+
379
+ processData(data: Row[]): void {
380
+ const columns = this.columns.filter(
381
+ (c) => c.filterable && isPresent(c.prop),
382
+ );
383
+
384
+ const sortableColumns = this.columns.filter((c) => !isEmpty(c.sort));
385
+ const sortings = sortableColumns.map((c) => ({
386
+ prop: c.prop as string,
387
+ direction: c.sort as SortDirection,
388
+ }));
389
+
390
+ const filterFunction = this.args.filterFunction;
391
+ const filterUsing = this.args.filterUsing;
392
+ const filter = this.filter;
393
+
394
+ const processTheData = (): void => {
395
+ let working = filterData(
396
+ data,
397
+ columns,
398
+ filter,
399
+ filterFunction,
400
+ filterUsing,
401
+ );
402
+
403
+ if (sortings.length > 0) {
404
+ working = mergeSort(working, (itemA, itemB) => {
405
+ return this.sortFunction!(
406
+ itemA,
407
+ itemB,
408
+ sortings,
409
+ this.compareFunction,
410
+ );
411
+ });
412
+ }
413
+
414
+ this.processedDataRows = working;
415
+
416
+ if (this.pagination) {
417
+ const { pageStart, pageEnd } = this.paginationData;
418
+ working = working.slice(pageStart - 1, pageEnd);
419
+ }
420
+
421
+ this.processedData = working;
422
+ };
423
+
424
+ if (this.ignoreDataChanges) {
425
+ // eslint-disable-next-line ember/no-runloop
426
+ later(processTheData, 0);
427
+ } else {
428
+ processTheData();
429
+ }
430
+ }
431
+
432
+ computeLoadDataParams(): LoadDataParams {
433
+ const params: LoadDataParams = {
434
+ sortData: this.columns
435
+ .filter((c) => !isEmpty(c.sort))
436
+ .map((c) => ({ prop: c.prop, direction: c.sort })),
437
+ filterData: {
438
+ filter: this.filter,
439
+ filterUsing: this.args.filterUsing,
440
+ columnFilters: this.columns.map((c) => ({
441
+ prop: c.prop,
442
+ filter: c.filter,
443
+ filterUsing: c.filterUsing,
444
+ })),
445
+ },
446
+ };
447
+
448
+ if (this.pagination) {
449
+ params.paginationData = this.paginationData;
450
+ }
451
+
452
+ return params;
453
+ }
454
+
455
+ paginateData(data: Row[]): Row[] {
456
+ if (this.pagination) {
457
+ const { pageStart, pageEnd } = this.paginationData;
458
+ data = data.slice(pageStart - 1, pageEnd);
459
+ }
460
+
461
+ return data;
462
+ }
463
+
464
+ @action
465
+ async reloadData(): Promise<unknown> {
466
+ return await this.resolvedData.retry();
467
+ }
468
+
469
+ @action
470
+ onColumnSort(column: Column, e: MouseEvent): void {
471
+ if (column.isSorted) {
472
+ let direction: SortDirection | null | undefined = column.sort;
473
+ const sortSequence = column.normalizedSortSequence;
474
+ direction = sortSequence[
475
+ (sortSequence.indexOf(direction as string) + 1) % sortSequence.length
476
+ ] as SortDirection;
477
+
478
+ if ((direction as unknown as string) === 'unsorted') {
479
+ direction = null;
480
+ }
481
+ column.sort = direction;
482
+
483
+ if (!e.shiftKey) {
484
+ const columns = this.columns.filter((c) => c !== column);
485
+ columns.forEach((c) => (c.sort = null));
486
+ }
487
+ } else {
488
+ const direction = column.normalizedSortSequence[0] as SortDirection;
489
+ column.sort = direction;
490
+
491
+ if (!e.shiftKey) {
492
+ const columns = this.columns.filter((c) => c !== column);
493
+ columns.forEach((c) => (c.sort = null));
494
+ }
495
+ }
496
+ }
497
+
498
+ @action
499
+ previousPage(): void {
500
+ if (this.pagination) {
501
+ this.pageNumber = Math.max(this.pageNumber - 1, 1);
502
+ }
503
+ }
504
+
505
+ @action
506
+ nextPage(): void {
507
+ if (this.pagination) {
508
+ const { isLastPage } = this.paginationData;
509
+
510
+ if (!isLastPage) {
511
+ this.pageNumber = this.pageNumber + 1;
512
+ }
513
+ }
514
+ }
515
+
516
+ @action
517
+ goToPage(pageNumber: number): void {
518
+ if (this.pagination) {
519
+ const { totalPages } = this.paginationData;
520
+ pageNumber = Math.max(pageNumber, 1);
521
+
522
+ if (totalPages) {
523
+ pageNumber = Math.min(pageNumber, totalPages);
524
+ }
525
+
526
+ this.pageNumber = pageNumber;
527
+ }
528
+ }
529
+
530
+ @action
531
+ changePageSize(pageSize: number | string): void {
532
+ if (this.pagination) {
533
+ this.pageSize = parseInt(String(pageSize));
534
+ }
535
+ }
536
+
537
+ registerColumn(column: Column): void {
538
+ // eslint-disable-next-line ember/no-runloop
539
+ schedule('afterRender', this, function (this: YetiTable) {
540
+ if (typeof this.args.isColumnVisible === 'function') {
541
+ column.visible = this.args.isColumnVisible(column);
542
+ }
543
+
544
+ if (!this.columns.includes(column)) {
545
+ this.columns = [...this.columns, column];
546
+ }
547
+ });
548
+ }
549
+
550
+ unregisterColumn(column: Column): void {
551
+ if (this.columns.includes(column)) {
552
+ this.columns = this.columns.filter((c) => c !== column);
553
+ }
554
+ }
555
+
556
+ <template>
557
+ {{#let
558
+ (hash
559
+ table=(component Table theme=this.mergedTheme parent=this)
560
+ header=(component
561
+ HeaderComponent
562
+ columns=this.columns
563
+ onColumnClick=this.onColumnSort
564
+ sortable=this.sortable
565
+ sortSequence=this.sortSequence
566
+ parent=this
567
+ theme=this.mergedTheme
568
+ )
569
+ thead=(component
570
+ THead
571
+ columns=this.columns
572
+ onColumnClick=this.onColumnSort
573
+ sortable=this.sortable
574
+ sortSequence=this.sortSequence
575
+ theme=this.mergedTheme
576
+ parent=this
577
+ )
578
+ body=(component
579
+ Body
580
+ data=this.processedData
581
+ columns=this.columns
582
+ theme=this.mergedTheme
583
+ parent=this
584
+ )
585
+ tbody=(component
586
+ TBody
587
+ data=this.processedData
588
+ columns=this.columns
589
+ theme=this.mergedTheme
590
+ parent=this
591
+ )
592
+ tfoot=(component
593
+ TFoot columns=this.columns theme=this.mergedTheme parent=this
594
+ )
595
+ pagination=(component
596
+ Pagination
597
+ disabled=this.resolvedData.isPending
598
+ theme=this.mergedTheme
599
+ paginationData=this.paginationData
600
+ paginationActions=(hash
601
+ previousPage=this.previousPage
602
+ nextPage=this.nextPage
603
+ goToPage=this.goToPage
604
+ changePageSize=this.changePageSize
605
+ )
606
+ )
607
+ actions=this.publicApi
608
+ paginationData=this.paginationData
609
+ isLoading=this.resolvedData.isPending
610
+ columns=this.columns
611
+ visibleColumns=this.visibleColumns
612
+ rows=this.normalizedRows
613
+ totalRows=this.normalizedTotalRows
614
+ visibleRows=this.processedData
615
+ theme=this.mergedTheme
616
+ )
617
+ as |api|
618
+ }}
619
+ {{UpdateTotalRows @totalRows context=this}}
620
+ {{UpdateFilter @filter context=this}}
621
+ {{ProcessedData loadData=@loadData context=this}}
622
+
623
+ {{#if this.renderTableElement}}
624
+ <Table @theme={{this.mergedTheme}} @parent={{this}} ...attributes>
625
+ {{yield api}}
626
+ </Table>
627
+ {{else}}
628
+ {{yield api}}
629
+ {{/if}}
630
+
631
+ {{/let}}
632
+ </template>
633
+ }
@@ -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