@vaadin/hilla-react-crud 24.7.0-alpha9 → 24.7.0-beta1

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 (151) hide show
  1. package/autocrud-dialog.d.ts +0 -1
  2. package/autocrud-dialog.js +9 -23
  3. package/autocrud-dialog.js.map +1 -7
  4. package/autocrud-feature.d.ts +0 -1
  5. package/autocrud-feature.js +5 -8
  6. package/autocrud-feature.js.map +1 -7
  7. package/autocrud.d.ts +2 -64
  8. package/autocrud.js +43 -92
  9. package/autocrud.js.map +1 -7
  10. package/autocrud.obj.js +1 -6
  11. package/autoform-feature.d.ts +0 -1
  12. package/autoform-feature.js +5 -8
  13. package/autoform-feature.js.map +1 -7
  14. package/autoform-field.d.ts +0 -90
  15. package/autoform-field.js +87 -95
  16. package/autoform-field.js.map +1 -7
  17. package/autoform.d.ts +0 -190
  18. package/autoform.js +126 -184
  19. package/autoform.js.map +1 -7
  20. package/autoform.obj.js +1 -6
  21. package/autogrid-column-context.d.ts +1 -2
  22. package/autogrid-column-context.js +4 -8
  23. package/autogrid-column-context.js.map +1 -7
  24. package/autogrid-columns.d.ts +0 -1
  25. package/autogrid-columns.js +83 -99
  26. package/autogrid-columns.js.map +1 -7
  27. package/autogrid-feature.d.ts +0 -1
  28. package/autogrid-feature.js +5 -8
  29. package/autogrid-feature.js.map +1 -7
  30. package/autogrid-renderers.d.ts +0 -1
  31. package/autogrid-renderers.js +71 -80
  32. package/autogrid-renderers.js.map +1 -7
  33. package/autogrid.d.ts +1 -103
  34. package/autogrid.js +176 -234
  35. package/autogrid.js.map +1 -7
  36. package/autogrid.obj.js +1 -6
  37. package/crud.d.ts +7 -10
  38. package/data-provider.d.ts +37 -6
  39. package/data-provider.js +186 -121
  40. package/data-provider.js.map +1 -7
  41. package/header-filter.d.ts +1 -30
  42. package/header-filter.js +137 -244
  43. package/header-filter.js.map +1 -7
  44. package/header-sorter.d.ts +0 -1
  45. package/header-sorter.js +16 -27
  46. package/header-sorter.js.map +1 -7
  47. package/i18n.d.ts +0 -1
  48. package/i18n.js +2 -5
  49. package/i18n.js.map +1 -7
  50. package/index.d.ts +1 -2
  51. package/index.js +12 -16
  52. package/index.js.map +1 -7
  53. package/locale.d.ts +0 -1
  54. package/locale.js +100 -107
  55. package/locale.js.map +1 -7
  56. package/media-query.d.ts +0 -1
  57. package/media-query.js +12 -15
  58. package/media-query.js.map +1 -7
  59. package/model-info.d.ts +0 -1
  60. package/model-info.js +126 -127
  61. package/model-info.js.map +1 -7
  62. package/package.json +9 -33
  63. package/types/com/vaadin/hilla/crud/filter/AndFilter.d.ts +3 -4
  64. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts +0 -1
  65. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js +6 -9
  66. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js.map +1 -7
  67. package/types/com/vaadin/hilla/crud/filter/Filter.d.ts +1 -2
  68. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts +0 -1
  69. package/types/com/vaadin/hilla/crud/filter/FilterModel.js +3 -6
  70. package/types/com/vaadin/hilla/crud/filter/FilterModel.js.map +1 -7
  71. package/types/com/vaadin/hilla/crud/filter/FilterUnion.d.ts +4 -2
  72. package/types/com/vaadin/hilla/crud/filter/OrFilter.d.ts +3 -4
  73. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts +0 -1
  74. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js +6 -9
  75. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js.map +1 -7
  76. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts +0 -1
  77. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js +9 -12
  78. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js.map +1 -7
  79. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts +0 -1
  80. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js +4 -7
  81. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js.map +1 -7
  82. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter.d.ts +4 -5
  83. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts +0 -1
  84. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js +12 -15
  85. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js.map +1 -7
  86. package/types/com/vaadin/hilla/mappedtypes/Order.d.ts +3 -4
  87. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts +0 -1
  88. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js +15 -18
  89. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js.map +1 -7
  90. package/types/com/vaadin/hilla/mappedtypes/Pageable.d.ts +1 -2
  91. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts +0 -1
  92. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js +12 -15
  93. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js.map +1 -7
  94. package/types/com/vaadin/hilla/mappedtypes/Sort.d.ts +1 -2
  95. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts +0 -1
  96. package/types/com/vaadin/hilla/mappedtypes/SortModel.js +6 -9
  97. package/types/com/vaadin/hilla/mappedtypes/SortModel.js.map +1 -7
  98. package/types/org/springframework/data/domain/Sort/Direction.d.ts +0 -1
  99. package/types/org/springframework/data/domain/Sort/Direction.js +7 -10
  100. package/types/org/springframework/data/domain/Sort/Direction.js.map +1 -7
  101. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts +0 -1
  102. package/types/org/springframework/data/domain/Sort/DirectionModel.js +4 -7
  103. package/types/org/springframework/data/domain/Sort/DirectionModel.js.map +1 -7
  104. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts +0 -1
  105. package/types/org/springframework/data/domain/Sort/NullHandling.js +8 -11
  106. package/types/org/springframework/data/domain/Sort/NullHandling.js.map +1 -7
  107. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts +0 -1
  108. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js +4 -7
  109. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js.map +1 -7
  110. package/types.d.ts +6 -9
  111. package/types.js +2 -0
  112. package/types.js.map +1 -0
  113. package/util.d.ts +1 -2
  114. package/util.js +42 -47
  115. package/util.js.map +1 -7
  116. package/autocrud-dialog.d.ts.map +0 -1
  117. package/autocrud-feature.d.ts.map +0 -1
  118. package/autocrud.d.ts.map +0 -1
  119. package/autocrud.obj.js.map +0 -7
  120. package/autoform-feature.d.ts.map +0 -1
  121. package/autoform-field.d.ts.map +0 -1
  122. package/autoform.d.ts.map +0 -1
  123. package/autoform.obj.js.map +0 -7
  124. package/autogrid-column-context.d.ts.map +0 -1
  125. package/autogrid-columns.d.ts.map +0 -1
  126. package/autogrid-feature.d.ts.map +0 -1
  127. package/autogrid-renderers.d.ts.map +0 -1
  128. package/autogrid.d.ts.map +0 -1
  129. package/autogrid.obj.js.map +0 -7
  130. package/data-provider.d.ts.map +0 -1
  131. package/header-filter.d.ts.map +0 -1
  132. package/header-sorter.d.ts.map +0 -1
  133. package/i18n.d.ts.map +0 -1
  134. package/index.d.ts.map +0 -1
  135. package/locale.d.ts.map +0 -1
  136. package/media-query.d.ts.map +0 -1
  137. package/model-info.d.ts.map +0 -1
  138. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts.map +0 -1
  139. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts.map +0 -1
  140. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts.map +0 -1
  141. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts.map +0 -1
  142. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts.map +0 -1
  143. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts.map +0 -1
  144. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts.map +0 -1
  145. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts.map +0 -1
  146. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts.map +0 -1
  147. package/types/org/springframework/data/domain/Sort/Direction.d.ts.map +0 -1
  148. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts.map +0 -1
  149. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts.map +0 -1
  150. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts.map +0 -1
  151. package/util.d.ts.map +0 -1
package/data-provider.js CHANGED
@@ -1,135 +1,200 @@
1
- import { useMemo, useState } from "react";
2
- import Direction from "./types/org/springframework/data/domain/Sort/Direction";
3
- import NullHandling from "./types/org/springframework/data/domain/Sort/NullHandling";
1
+ import { useMemo, useState } from 'react';
2
+ import Direction from './types/org/springframework/data/domain/Sort/Direction.js';
3
+ import NullHandling from './types/org/springframework/data/domain/Sort/NullHandling.js';
4
4
  function createSort(params) {
5
- return {
6
- orders: params.sortOrders.filter((order) => order.direction != null).map((order) => ({
7
- property: order.path,
8
- direction: order.direction === "asc" ? Direction.ASC : Direction.DESC,
9
- ignoreCase: false,
10
- nullHandling: NullHandling.NATIVE
11
- }))
12
- };
5
+ return {
6
+ orders: params.sortOrders
7
+ .filter((order) => order.direction != null)
8
+ .map((order) => ({
9
+ property: order.path,
10
+ direction: order.direction === 'asc' ? Direction.ASC : Direction.DESC,
11
+ ignoreCase: false,
12
+ nullHandling: NullHandling.NATIVE,
13
+ })),
14
+ };
13
15
  }
14
- function isCountService(service) {
15
- return !!service.count;
16
+ export function isCountService(service) {
17
+ return !!service.count;
16
18
  }
17
- class DataProvider {
18
- service;
19
- loadTotalCount;
20
- afterLoadCallback;
21
- filter;
22
- totalCount;
23
- filteredCount;
24
- constructor(service, options = {}) {
25
- this.service = service;
26
- this.filter = options.initialFilter;
27
- this.loadTotalCount = options.loadTotalCount;
28
- this.afterLoadCallback = options.afterLoad;
29
- this.load = this.load.bind(this);
30
- }
31
- reset() {
32
- this.totalCount = void 0;
33
- this.filteredCount = void 0;
34
- }
35
- setFilter(filter) {
36
- this.reset();
37
- this.filter = filter;
38
- }
39
- async load(params, callback) {
40
- const page = await this.fetchPage(params);
41
- this.filteredCount = await this.fetchFilteredCount(page);
42
- if (this.loadTotalCount) {
43
- this.totalCount = await this.fetchTotalCount(page);
44
- }
45
- callback(page.items, this.filteredCount);
46
- if (this.afterLoadCallback) {
47
- this.afterLoadCallback({
48
- totalCount: this.totalCount,
49
- filteredCount: this.filteredCount
50
- });
51
- }
52
- }
53
- async fetchPage(params) {
54
- const sort = createSort(params);
55
- const pageNumber = params.page;
56
- const { pageSize } = params;
57
- const pageRequest = {
58
- pageNumber,
59
- pageSize,
60
- sort
61
- };
62
- const items = await this.service.list(pageRequest, this.filter);
63
- return { items, pageRequest };
64
- }
19
+ export class DataProvider {
20
+ service;
21
+ loadTotalCount;
22
+ afterLoadCallback;
23
+ filter;
24
+ totalCount;
25
+ filteredCount;
26
+ constructor(service, options = {}) {
27
+ this.service = service;
28
+ this.filter = options.initialFilter;
29
+ this.loadTotalCount = options.loadTotalCount;
30
+ this.afterLoadCallback = options.afterLoad;
31
+ this.load = this.load.bind(this);
32
+ }
33
+ reset() {
34
+ this.totalCount = undefined;
35
+ this.filteredCount = undefined;
36
+ }
37
+ setFilter(filter) {
38
+ this.reset();
39
+ this.filter = filter;
40
+ }
41
+ async load(params, callback) {
42
+ const page = await this.fetchPage(params);
43
+ this.filteredCount = await this.fetchFilteredCount(page);
44
+ if (this.loadTotalCount) {
45
+ this.totalCount = await this.fetchTotalCount(page);
46
+ }
47
+ callback(page.items, this.filteredCount);
48
+ if (this.afterLoadCallback) {
49
+ this.afterLoadCallback({
50
+ totalCount: this.totalCount,
51
+ filteredCount: this.filteredCount,
52
+ });
53
+ }
54
+ }
55
+ async fetchPage(params) {
56
+ const sort = createSort(params);
57
+ const pageNumber = params.page;
58
+ const { pageSize } = params;
59
+ const pageRequest = {
60
+ pageNumber,
61
+ pageSize,
62
+ sort,
63
+ };
64
+ const items = await this.service.list(pageRequest, this.filter);
65
+ return { items, pageRequest };
66
+ }
65
67
  }
66
- class InfiniteDataProvider extends DataProvider {
67
- // cannot be static, otherwise it does not implement superclass
68
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
69
- fetchTotalCount() {
70
- return void 0;
71
- }
72
- fetchFilteredCount(page) {
68
+ export class AbstractComboBoxDataProvider {
69
+ list;
70
+ loadTotalCount;
71
+ sort;
72
+ totalCount;
73
+ filteredCount;
74
+ constructor(list, sort) {
75
+ this.list = list;
76
+ this.sort = sort;
77
+ }
78
+ reset() {
79
+ this.totalCount = undefined;
80
+ this.filteredCount = undefined;
81
+ }
82
+ load(params, callback) {
83
+ this.fetchPage(params)
84
+ .then(async (page) => {
85
+ this.filteredCount = await this.fetchFilteredCount(page);
86
+ if (this.loadTotalCount) {
87
+ this.totalCount = await this.fetchTotalCount(page);
88
+ }
89
+ callback(page.items, this.filteredCount);
90
+ })
91
+ .catch((error) => {
92
+ throw error;
93
+ });
94
+ }
95
+ async fetchPage(params) {
96
+ const pageNumber = params.page;
97
+ const { pageSize } = params;
98
+ const pageRequest = {
99
+ pageNumber,
100
+ pageSize,
101
+ sort: this.sort ?? { orders: [] },
102
+ };
103
+ const items = await this.list(pageRequest, params.filter);
104
+ return { items, pageRequest };
105
+ }
106
+ }
107
+ function determineInfiniteScrollingSize(page, lastKnownSize) {
73
108
  const { items, pageRequest } = page;
74
109
  const { pageNumber, pageSize } = pageRequest;
75
110
  let infiniteScrollingSize;
76
111
  if (items.length === pageSize) {
77
- infiniteScrollingSize = (pageNumber + 1) * pageSize + 1;
78
- if (this.filteredCount !== void 0 && infiniteScrollingSize < this.filteredCount) {
79
- infiniteScrollingSize = this.filteredCount;
80
- }
81
- } else {
82
- infiniteScrollingSize = pageNumber * pageSize + items.length;
112
+ infiniteScrollingSize = (pageNumber + 1) * pageSize + 1;
113
+ if (lastKnownSize !== undefined && infiniteScrollingSize < lastKnownSize) {
114
+ infiniteScrollingSize = lastKnownSize;
115
+ }
116
+ }
117
+ else {
118
+ infiniteScrollingSize = pageNumber * pageSize + items.length;
83
119
  }
84
120
  return infiniteScrollingSize;
85
- }
86
121
  }
87
- class FixedSizeDataProvider extends DataProvider {
88
- constructor(service, options = {}) {
89
- if (!isCountService(service)) {
90
- throw new Error("The provided service does not implement the CountService interface.");
91
- }
92
- super(service, options);
93
- }
94
- async fetchTotalCount() {
95
- if (this.totalCount !== void 0) {
96
- return this.totalCount;
97
- }
98
- return this.service.count(void 0);
99
- }
100
- async fetchFilteredCount() {
101
- if (this.filteredCount !== void 0) {
102
- return this.filteredCount;
103
- }
104
- return this.service.count(this.filter);
105
- }
122
+ export class InfiniteDataProvider extends DataProvider {
123
+ fetchTotalCount() {
124
+ return undefined;
125
+ }
126
+ fetchFilteredCount(page) {
127
+ return determineInfiniteScrollingSize(page, this.filteredCount);
128
+ }
129
+ }
130
+ export class InfiniteComboBoxDataProvider extends AbstractComboBoxDataProvider {
131
+ fetchTotalCount() {
132
+ return undefined;
133
+ }
134
+ fetchFilteredCount(page) {
135
+ return determineInfiniteScrollingSize(page, this.filteredCount);
136
+ }
137
+ }
138
+ export class FixedSizeDataProvider extends DataProvider {
139
+ constructor(service, options = {}) {
140
+ if (!isCountService(service)) {
141
+ throw new Error('The provided service does not implement the CountService interface.');
142
+ }
143
+ super(service, options);
144
+ }
145
+ async fetchTotalCount() {
146
+ if (this.totalCount !== undefined) {
147
+ return this.totalCount;
148
+ }
149
+ return this.service.count(undefined);
150
+ }
151
+ async fetchFilteredCount() {
152
+ if (this.filteredCount !== undefined) {
153
+ return this.filteredCount;
154
+ }
155
+ return this.service.count(this.filter);
156
+ }
157
+ }
158
+ export function createDataProvider(service, options = {}) {
159
+ if (isCountService(service)) {
160
+ return new FixedSizeDataProvider(service, options);
161
+ }
162
+ return new InfiniteDataProvider(service, options);
163
+ }
164
+ export function useDataProvider(service, filter) {
165
+ const [refreshCounter, setRefreshCounter] = useState(0);
166
+ const dataProvider = useMemo(() => createDataProvider(service, { initialFilter: filter }), [service]);
167
+ dataProvider.setFilter(filter);
168
+ const dataProviderFn = useMemo(() => dataProvider.load.bind(dataProvider), [dataProvider, filter, refreshCounter]);
169
+ return {
170
+ dataProvider: dataProviderFn,
171
+ refresh: () => {
172
+ dataProvider.reset();
173
+ setRefreshCounter(refreshCounter + 1);
174
+ },
175
+ };
176
+ }
177
+ export function useGridDataProvider(fetch, dependencies) {
178
+ const result = useDataProvider(useMemo(() => ({
179
+ list: async (pageable) => fetch(pageable),
180
+ }), dependencies ?? []));
181
+ const dataProvider = result.dataProvider;
182
+ dataProvider.refresh = result.refresh;
183
+ return dataProvider;
106
184
  }
107
- function createDataProvider(service, options = {}) {
108
- if (isCountService(service)) {
109
- return new FixedSizeDataProvider(service, options);
110
- }
111
- return new InfiniteDataProvider(service, options);
185
+ function createComboBoxDataProvider(list, sort) {
186
+ return new InfiniteComboBoxDataProvider(list, sort);
112
187
  }
113
- function useDataProvider(service, filter) {
114
- const [refreshCounter, setRefreshCounter] = useState(0);
115
- const dataProvider = useMemo(() => createDataProvider(service, { initialFilter: filter }), [service]);
116
- dataProvider.setFilter(filter);
117
- const dataProviderFn = useMemo(() => dataProvider.load.bind(dataProvider), [dataProvider, filter, refreshCounter]);
118
- return {
119
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
120
- dataProvider: dataProviderFn,
121
- refresh: () => {
122
- dataProvider.reset();
123
- setRefreshCounter(refreshCounter + 1);
124
- }
125
- };
188
+ export function useComboBoxDataProvider(fetch, options, dependencies) {
189
+ const [refreshCounter, setRefreshCounter] = useState(0);
190
+ const dataProvider = useMemo(() => createComboBoxDataProvider(fetch, options?.sort), [options?.sort, ...(dependencies ?? [])]);
191
+ return useMemo(() => {
192
+ const dataProviderWithRefresh = (...args) => dataProvider.load(...args);
193
+ dataProviderWithRefresh.refresh = () => {
194
+ dataProvider.reset();
195
+ setRefreshCounter(refreshCounter + 1);
196
+ };
197
+ return dataProviderWithRefresh;
198
+ }, [dataProvider, refreshCounter]);
126
199
  }
127
- export {
128
- DataProvider,
129
- FixedSizeDataProvider,
130
- InfiniteDataProvider,
131
- createDataProvider,
132
- isCountService,
133
- useDataProvider
134
- };
135
- //# sourceMappingURL=data-provider.js.map
200
+ //# sourceMappingURL=data-provider.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/data-provider.ts"],
4
- "sourcesContent": ["import type { GridDataProviderCallback, GridDataProviderParams } from '@vaadin/react-components/Grid';\nimport type { GridDataProvider } from '@vaadin/react-components/Grid';\nimport { useMemo, useState } from 'react';\nimport type { CountService, ListService } from './crud';\nimport type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion';\nimport type Sort from './types/com/vaadin/hilla/mappedtypes/Sort';\nimport Direction from './types/org/springframework/data/domain/Sort/Direction';\nimport NullHandling from './types/org/springframework/data/domain/Sort/NullHandling';\n\ntype MaybeCountService<TItem> = Partial<CountService<TItem>>;\ntype ListAndMaybeCountService<TItem> = ListService<TItem> & MaybeCountService<TItem>;\ntype ListAndCountService<TItem> = CountService<TItem> & ListService<TItem>;\n\ntype PageRequest = {\n pageNumber: number;\n pageSize: number;\n sort: Sort;\n};\n\ntype DataPage<TItem> = {\n items: TItem[];\n pageRequest: PageRequest;\n};\n\nexport type ItemCounts = {\n totalCount?: number;\n filteredCount?: number;\n};\n\ntype AfterLoadCallback = (result: ItemCounts) => void;\n\ntype DataProviderOptions = {\n initialFilter?: FilterUnion;\n loadTotalCount?: boolean;\n afterLoad?: AfterLoadCallback;\n};\n\nfunction createSort<TItem>(params: GridDataProviderParams<TItem>): Sort {\n return {\n orders: params.sortOrders\n .filter((order) => order.direction != null)\n .map((order) => ({\n property: order.path,\n direction: order.direction === 'asc' ? Direction.ASC : Direction.DESC,\n ignoreCase: false,\n nullHandling: NullHandling.NATIVE,\n })),\n };\n}\n\nexport function isCountService<TItem>(service: ListAndMaybeCountService<TItem>): service is ListAndCountService<TItem> {\n return !!service.count;\n}\n\nexport abstract class DataProvider<TItem> {\n protected readonly service: ListAndMaybeCountService<TItem>;\n protected readonly loadTotalCount?: boolean;\n protected readonly afterLoadCallback?: AfterLoadCallback;\n\n protected filter: FilterUnion | undefined;\n protected totalCount: number | undefined;\n protected filteredCount: number | undefined;\n\n constructor(service: ListAndMaybeCountService<TItem>, options: DataProviderOptions = {}) {\n this.service = service;\n this.filter = options.initialFilter;\n this.loadTotalCount = options.loadTotalCount;\n this.afterLoadCallback = options.afterLoad;\n\n this.load = this.load.bind(this);\n }\n\n reset(): void {\n this.totalCount = undefined;\n this.filteredCount = undefined;\n }\n\n setFilter(filter: FilterUnion | undefined): void {\n this.reset();\n this.filter = filter;\n }\n\n async load(params: GridDataProviderParams<TItem>, callback: GridDataProviderCallback<TItem>): Promise<void> {\n // Fetch page and filtered count\n const page = await this.fetchPage(params);\n this.filteredCount = await this.fetchFilteredCount(page);\n // Only fetch total count if it's specific in options\n if (this.loadTotalCount) {\n this.totalCount = await this.fetchTotalCount(page);\n }\n\n // Pass results to grid\n callback(page.items, this.filteredCount);\n\n // Pass results to callback\n if (this.afterLoadCallback) {\n this.afterLoadCallback({\n totalCount: this.totalCount,\n filteredCount: this.filteredCount,\n });\n }\n }\n\n protected async fetchPage(params: GridDataProviderParams<TItem>): Promise<DataPage<TItem>> {\n const sort = createSort(params);\n const pageNumber = params.page;\n const { pageSize } = params;\n const pageRequest = {\n pageNumber,\n pageSize,\n sort,\n };\n const items = await this.service.list(pageRequest, this.filter);\n\n return { items, pageRequest };\n }\n\n protected abstract fetchTotalCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n\n protected abstract fetchFilteredCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n}\n\nexport class InfiniteDataProvider<TItem> extends DataProvider<TItem> {\n // cannot be static, otherwise it does not implement superclass\n // eslint-disable-next-line @typescript-eslint/class-methods-use-this\n protected fetchTotalCount(): undefined {\n return undefined;\n }\n\n protected fetchFilteredCount(page: DataPage<TItem>): number | undefined {\n const { items, pageRequest } = page;\n const { pageNumber, pageSize } = pageRequest;\n let infiniteScrollingSize;\n\n if (items.length === pageSize) {\n infiniteScrollingSize = (pageNumber + 1) * pageSize + 1;\n if (this.filteredCount !== undefined && infiniteScrollingSize < this.filteredCount) {\n // Only allow size to grow here to avoid shrinking the size when scrolled down and sorting\n infiniteScrollingSize = this.filteredCount;\n }\n } else {\n infiniteScrollingSize = pageNumber * pageSize + items.length;\n }\n\n return infiniteScrollingSize;\n }\n}\n\nexport class FixedSizeDataProvider<TItem> extends DataProvider<TItem> {\n declare service: ListAndCountService<TItem>;\n\n constructor(service: ListAndMaybeCountService<TItem>, options: DataProviderOptions = {}) {\n if (!isCountService(service)) {\n throw new Error('The provided service does not implement the CountService interface.');\n }\n super(service, options);\n }\n\n protected async fetchTotalCount(): Promise<number | undefined> {\n // Use cached count if it's already known\n if (this.totalCount !== undefined) {\n return this.totalCount;\n }\n return this.service.count(undefined);\n }\n\n protected async fetchFilteredCount(): Promise<number | undefined> {\n // Use cached count if it's already known\n if (this.filteredCount !== undefined) {\n return this.filteredCount;\n }\n return this.service.count(this.filter);\n }\n}\n\nexport function createDataProvider<TItem>(\n service: ListAndMaybeCountService<TItem>,\n options: DataProviderOptions = {},\n): DataProvider<TItem> {\n if (isCountService(service)) {\n return new FixedSizeDataProvider(service, options);\n }\n return new InfiniteDataProvider(service, options);\n}\n\ntype UseDataProviderResult<TItem> = Readonly<{\n dataProvider: GridDataProvider<TItem>;\n refresh(): void;\n}>;\n\nexport function useDataProvider<TItem>(\n service: ListAndMaybeCountService<TItem>,\n filter?: FilterUnion,\n): UseDataProviderResult<TItem> {\n const [refreshCounter, setRefreshCounter] = useState(0);\n const dataProvider = useMemo(() => createDataProvider(service, { initialFilter: filter }), [service]);\n\n // Update filter in data provider\n dataProvider.setFilter(filter);\n\n // Create a new data provider function reference when the filter changes or the refresh counter is incremented.\n // This effectively forces the grid to reload\n const dataProviderFn = useMemo(() => dataProvider.load.bind(dataProvider), [dataProvider, filter, refreshCounter]);\n\n return {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n dataProvider: dataProviderFn,\n refresh: () => {\n dataProvider.reset();\n setRefreshCounter(refreshCounter + 1);\n },\n };\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
1
+ {"version":3,"file":"data-provider.js","sourceRoot":"","sources":["src/data-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ComboBoxDataProvider,\n ComboBoxDataProviderCallback,\n ComboBoxDataProviderParams,\n} from '@vaadin/react-components';\nimport type { GridDataProvider, GridDataProviderCallback, GridDataProviderParams } from '@vaadin/react-components/Grid';\nimport { useMemo, useState, type DependencyList } from 'react';\nimport type { CountService, ListService } from './crud.js';\nimport type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion.js';\nimport type Pageable from './types/com/vaadin/hilla/mappedtypes/Pageable.js';\nimport type Sort from './types/com/vaadin/hilla/mappedtypes/Sort.js';\nimport Direction from './types/org/springframework/data/domain/Sort/Direction.js';\nimport NullHandling from './types/org/springframework/data/domain/Sort/NullHandling.js';\n\ntype MaybeCountService<TItem> = Partial<CountService<TItem>>;\ntype ListAndMaybeCountService<TItem> = ListService<TItem> & MaybeCountService<TItem>;\ntype ListAndCountService<TItem> = CountService<TItem> & ListService<TItem>;\n\ntype PageRequest = {\n pageNumber: number;\n pageSize: number;\n sort: Sort;\n};\n\ntype DataPage<TItem> = {\n items: TItem[];\n pageRequest: PageRequest;\n};\n\nexport type ItemCounts = {\n totalCount?: number;\n filteredCount?: number;\n};\n\ntype AfterLoadCallback = (result: ItemCounts) => void;\n\ntype DataProviderOptions = {\n initialFilter?: FilterUnion;\n loadTotalCount?: boolean;\n afterLoad?: AfterLoadCallback;\n};\n\nfunction createSort<TItem>(params: GridDataProviderParams<TItem>): Sort {\n return {\n orders: params.sortOrders\n .filter((order) => order.direction != null)\n .map((order) => ({\n property: order.path,\n direction: order.direction === 'asc' ? Direction.ASC : Direction.DESC,\n ignoreCase: false,\n nullHandling: NullHandling.NATIVE,\n })),\n };\n}\n\nexport function isCountService<TItem>(service: ListAndMaybeCountService<TItem>): service is ListAndCountService<TItem> {\n return !!service.count;\n}\n\nexport abstract class DataProvider<TItem> {\n protected readonly service: ListAndMaybeCountService<TItem>;\n protected readonly loadTotalCount?: boolean;\n protected readonly afterLoadCallback?: AfterLoadCallback;\n\n protected filter: FilterUnion | undefined;\n protected totalCount: number | undefined;\n protected filteredCount: number | undefined;\n\n constructor(service: ListAndMaybeCountService<TItem>, options: DataProviderOptions = {}) {\n this.service = service;\n this.filter = options.initialFilter;\n this.loadTotalCount = options.loadTotalCount;\n this.afterLoadCallback = options.afterLoad;\n\n this.load = this.load.bind(this);\n }\n\n reset(): void {\n this.totalCount = undefined;\n this.filteredCount = undefined;\n }\n\n setFilter(filter: FilterUnion | undefined): void {\n this.reset();\n this.filter = filter;\n }\n\n async load(params: GridDataProviderParams<TItem>, callback: GridDataProviderCallback<TItem>): Promise<void> {\n // Fetch page and filtered count\n const page = await this.fetchPage(params);\n this.filteredCount = await this.fetchFilteredCount(page);\n // Only fetch total count if it's specific in options\n if (this.loadTotalCount) {\n this.totalCount = await this.fetchTotalCount(page);\n }\n\n // Pass results to grid\n callback(page.items, this.filteredCount);\n\n // Pass results to callback\n if (this.afterLoadCallback) {\n this.afterLoadCallback({\n totalCount: this.totalCount,\n filteredCount: this.filteredCount,\n });\n }\n }\n\n protected async fetchPage(params: GridDataProviderParams<TItem>): Promise<DataPage<TItem>> {\n const sort = createSort(params);\n const pageNumber = params.page;\n const { pageSize } = params;\n const pageRequest = {\n pageNumber,\n pageSize,\n sort,\n };\n const items = await this.service.list(pageRequest, this.filter);\n\n return { items, pageRequest };\n }\n\n protected abstract fetchTotalCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n\n protected abstract fetchFilteredCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n}\n\nexport abstract class AbstractComboBoxDataProvider<TItem> {\n protected readonly list: ComboBoxFetchMethod<TItem>;\n protected readonly loadTotalCount?: boolean;\n\n protected sort: Sort | undefined;\n protected totalCount: number | undefined;\n protected filteredCount: number | undefined;\n\n constructor(list: ComboBoxFetchMethod<TItem>, sort: Sort | undefined) {\n this.list = list;\n this.sort = sort;\n }\n\n reset(): void {\n this.totalCount = undefined;\n this.filteredCount = undefined;\n }\n\n load(params: ComboBoxDataProviderParams, callback: ComboBoxDataProviderCallback<TItem>): void {\n this.fetchPage(params)\n .then(async (page) => {\n this.filteredCount = await this.fetchFilteredCount(page);\n // Only fetch total count if it's specific in options\n if (this.loadTotalCount) {\n this.totalCount = await this.fetchTotalCount(page);\n }\n\n // Pass results to the combobox\n callback(page.items, this.filteredCount);\n })\n .catch((error: unknown) => {\n throw error;\n });\n }\n\n protected async fetchPage(params: ComboBoxDataProviderParams): Promise<DataPage<TItem>> {\n const pageNumber = params.page;\n const { pageSize } = params;\n const pageRequest: Pageable = {\n pageNumber,\n pageSize,\n sort: this.sort ?? { orders: [] },\n };\n const items = await this.list(pageRequest, params.filter);\n\n return { items, pageRequest };\n }\n\n protected abstract fetchTotalCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n\n protected abstract fetchFilteredCount(page: DataPage<TItem>): Promise<number | undefined> | number | undefined;\n}\n\nfunction determineInfiniteScrollingSize(page: DataPage<unknown>, lastKnownSize?: number): number {\n const { items, pageRequest } = page;\n const { pageNumber, pageSize } = pageRequest;\n let infiniteScrollingSize;\n\n if (items.length === pageSize) {\n infiniteScrollingSize = (pageNumber + 1) * pageSize + 1;\n if (lastKnownSize !== undefined && infiniteScrollingSize < lastKnownSize) {\n // Only allow size to grow here to avoid shrinking the size when scrolled down and sorting\n infiniteScrollingSize = lastKnownSize;\n }\n } else {\n infiniteScrollingSize = pageNumber * pageSize + items.length;\n }\n\n return infiniteScrollingSize;\n}\n\nexport class InfiniteDataProvider<TItem> extends DataProvider<TItem> {\n // cannot be static, otherwise it does not implement superclass\n // eslint-disable-next-line @typescript-eslint/class-methods-use-this\n protected fetchTotalCount(): undefined {\n return undefined;\n }\n\n protected fetchFilteredCount(page: DataPage<TItem>): number | undefined {\n return determineInfiniteScrollingSize(page, this.filteredCount);\n }\n}\nexport class InfiniteComboBoxDataProvider<TItem> extends AbstractComboBoxDataProvider<TItem> {\n // cannot be static, otherwise it does not implement superclass\n // eslint-disable-next-line @typescript-eslint/class-methods-use-this\n protected fetchTotalCount(): undefined {\n return undefined;\n }\n\n protected fetchFilteredCount(page: DataPage<TItem>): number | undefined {\n return determineInfiniteScrollingSize(page, this.filteredCount);\n }\n}\n\nexport class FixedSizeDataProvider<TItem> extends DataProvider<TItem> {\n declare service: ListAndCountService<TItem>;\n\n constructor(service: ListAndMaybeCountService<TItem>, options: DataProviderOptions = {}) {\n if (!isCountService(service)) {\n throw new Error('The provided service does not implement the CountService interface.');\n }\n super(service, options);\n }\n\n protected async fetchTotalCount(): Promise<number | undefined> {\n // Use cached count if it's already known\n if (this.totalCount !== undefined) {\n return this.totalCount;\n }\n return this.service.count(undefined);\n }\n\n protected async fetchFilteredCount(): Promise<number | undefined> {\n // Use cached count if it's already known\n if (this.filteredCount !== undefined) {\n return this.filteredCount;\n }\n return this.service.count(this.filter);\n }\n}\n\nexport function createDataProvider<TItem>(\n service: ListAndMaybeCountService<TItem>,\n options: DataProviderOptions = {},\n): DataProvider<TItem> {\n if (isCountService(service)) {\n return new FixedSizeDataProvider(service, options);\n }\n return new InfiniteDataProvider(service, options);\n}\n\ntype UseDataProviderResult<TItem> = Readonly<{\n dataProvider: GridDataProvider<TItem>;\n refresh(): void;\n}>;\n\nexport function useDataProvider<TItem>(\n service: ListAndMaybeCountService<TItem>,\n filter?: FilterUnion,\n): UseDataProviderResult<TItem> {\n const [refreshCounter, setRefreshCounter] = useState(0);\n const dataProvider = useMemo(() => createDataProvider(service, { initialFilter: filter }), [service]);\n\n // Update filter in data provider\n dataProvider.setFilter(filter);\n\n // Create a new data provider function reference when the filter changes or the refresh counter is incremented.\n // This effectively forces the grid to reload\n const dataProviderFn = useMemo(() => dataProvider.load.bind(dataProvider), [dataProvider, filter, refreshCounter]);\n\n return {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n dataProvider: dataProviderFn,\n refresh: () => {\n dataProvider.reset();\n setRefreshCounter(refreshCounter + 1);\n },\n };\n}\n\nexport type UseGridDataProviderResult<TItem> = GridDataProvider<TItem> & {\n refresh(): void;\n};\n\nexport type GridFetchMethod<TItem> = (pageable: Pageable) => Promise<TItem[]>;\n\n/**\n * Creates a data provider for a grid component that fetches data using the provided fetch callback.\n *\n * @param fetch - the callback that fetches the data for the grid. The callback should return a promise that resolves to an array of items.\n * @param dependencies - A list of all reactive values referenced inside of the fetch callback. A change to any of the listed values will cause the grid to refresh its data.\n * @returns a data provider that can be assigned to a <Grid> component usings its dataProvider property and additionally contains a refresh method that can be called to force a reload of the grid data.\n */\nexport function useGridDataProvider<TItem>(\n fetch: GridFetchMethod<TItem>,\n dependencies?: DependencyList,\n): UseGridDataProviderResult<TItem> {\n const result = useDataProvider(\n useMemo(\n () => ({\n list: async (pageable: Pageable) => fetch(pageable),\n }),\n dependencies ?? [],\n ),\n );\n const dataProvider: UseGridDataProviderResult<TItem> = result.dataProvider as UseGridDataProviderResult<TItem>;\n dataProvider.refresh = result.refresh;\n return dataProvider;\n}\n\nexport type UseComboBoxDataProviderResult<TItem> = ComboBoxDataProvider<TItem> & {\n refresh(): void;\n};\n\nexport type ComboBoxFetchMethod<TItem> = (pageable: Pageable, filterString: string) => Promise<TItem[]>;\n\nfunction createComboBoxDataProvider<TItem>(\n list: ComboBoxFetchMethod<TItem>,\n sort: Sort | undefined,\n): AbstractComboBoxDataProvider<TItem> {\n return new InfiniteComboBoxDataProvider(list, sort);\n}\n\ntype ComboboxDataProviderOptions = {\n sort?: Sort;\n};\n\n/**\n * Creates a data provider for a combo box component that fetches data using the provided fetch callback.\n *\n * @param fetch - the method that fetches the data for the grid. The method should return a promise that resolves to an array of items.\n * @param dependencies - A list of all reactive values referenced inside of the fetch callback. A change to any of the listed values will cause the combo box to refresh its data.\n * @returns a data provider that can be assigned to a <ComboBox> component usings its dataProvider property and additionally contains a refresh method that can be called to force a reload of the combo box data.\n */\nexport function useComboBoxDataProvider<TItem>(\n fetch: ComboBoxFetchMethod<TItem>,\n options?: ComboboxDataProviderOptions,\n dependencies?: DependencyList,\n): UseComboBoxDataProviderResult<TItem> {\n const [refreshCounter, setRefreshCounter] = useState(0);\n\n const dataProvider = useMemo(\n () => createComboBoxDataProvider(fetch, options?.sort),\n [options?.sort, ...(dependencies ?? [])],\n );\n\n // Create a new data provider function reference when the refresh counter is incremented.\n // This effectively forces the combo box to reload\n return useMemo(() => {\n const dataProviderWithRefresh = (...args: Parameters<typeof dataProvider.load>) => dataProvider.load(...args);\n dataProviderWithRefresh.refresh = () => {\n dataProvider.reset();\n setRefreshCounter(refreshCounter + 1);\n };\n return dataProviderWithRefresh;\n }, [dataProvider, refreshCounter]);\n}\n"]}
@@ -1,45 +1,17 @@
1
1
  import type { GridColumnProps } from '@vaadin/react-components/GridColumn.js';
2
2
  import { type ComponentType, type JSX, type ReactElement } from 'react';
3
- import type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion';
3
+ import type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion.js';
4
4
  type ExtractComponentTypeProps<T extends ComponentType<any>> = T extends ComponentType<infer U> ? U : never;
5
5
  export type HeaderRendererProps = ExtractComponentTypeProps<NonNullable<Required<GridColumnProps<unknown>>['headerRenderer']>>;
6
6
  export type HeaderFilterRendererProps = HeaderRendererProps & {
7
- /**
8
- * Allows to set custom filters for the column.
9
- * This is used by the header filter components.
10
- * @param filter - The filter to set in the filter list.
11
- */
12
7
  setFilter(filter: FilterUnion): void;
13
8
  };
14
9
  export type HeaderFilterProps = Readonly<{
15
- /**
16
- * If true, the column can be sorted. This is useful to disable sorting for
17
- * properties that are not sortable in the backend, or that require excessive processing.
18
- */
19
10
  sortable?: boolean;
20
- /**
21
- * If true, the column can be filtered. This is useful to disable filtering for
22
- * properties that are not sortable in the backend, or that require excessive processing.
23
- */
24
11
  filterable?: boolean;
25
- /**
26
- * Placeholder text for the filter input.
27
- * Only applies to string, number and date/time value filters.
28
- */
29
12
  filterPlaceholder?: string;
30
- /**
31
- * Debounce time for the filter input in milliseconds.
32
- * Only applies to string value filters and number value filters.
33
- */
34
13
  filterDebounceTime?: number;
35
- /**
36
- * Minimum length for the filter input.
37
- * Only applies to string value filters.
38
- */
39
14
  filterMinLength?: number;
40
- /**
41
- * Custom renderer for the filter in the header.
42
- */
43
15
  headerFilterRenderer?: ComponentType<HeaderFilterRendererProps>;
44
16
  }>;
45
17
  export declare function StringHeaderFilter(): ReactElement;
@@ -51,4 +23,3 @@ export declare function TimeHeaderFilter(): ReactElement;
51
23
  export declare function NoHeaderFilter(): ReactElement;
52
24
  export declare function HeaderFilterWrapper({ original }: HeaderRendererProps): JSX.Element | null;
53
25
  export {};
54
- //# sourceMappingURL=header-filter.d.ts.map