@intellegens/cornerstone-client 0.0.9999-alpha-41 → 0.0.9999-alpha-43
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.
- package/dist/adapters/collection-view-adapter.d.ts +123 -0
- package/dist/adapters/collection-view-adapter.integration.test.d.ts +1 -0
- package/dist/adapters/collection-view-adapter.integration.test.js +141 -0
- package/dist/adapters/collection-view-adapter.js +352 -0
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +2 -2
- package/dist/adapters/search-adapter.d.ts +83 -0
- package/dist/adapters/search-adapter.js +284 -0
- package/dist/data/api/dto/crud/crud-metadata-dto.js +1 -0
- package/dist/data/api/dto/crud/index.d.ts +1 -1
- package/dist/data/api/dto/crud/index.js +1 -1
- package/dist/data/api/dto/index.d.ts +1 -1
- package/dist/data/api/dto/index.js +1 -1
- package/dist/data/api/dto/property-path-dto.d.ts +4 -0
- package/dist/data/api/dto/property-path-dto.js +1 -0
- package/dist/data/api/dto/read/index.d.ts +10 -10
- package/dist/data/api/dto/read/index.js +10 -10
- package/dist/data/api/dto/read/read-metadata-dto.d.ts +8 -0
- package/dist/data/api/dto/read/read-metadata-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-definition-dto.d.ts +18 -0
- package/dist/data/api/dto/read/read-selected-definition-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-nested-collection-criteria-dto.d.ts +22 -0
- package/dist/data/api/dto/read/read-selected-nested-collection-criteria-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-nested-criteria-dto.d.ts +18 -0
- package/dist/data/api/dto/read/read-selected-nested-criteria-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-ordering-definition-dto.d.ts +7 -0
- package/dist/data/api/dto/read/read-selected-ordering-definition-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-ordering-property-definition-dto.d.ts +14 -0
- package/dist/data/api/dto/read/read-selected-ordering-property-definition-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-pagination-definition-dto.d.ts +13 -0
- package/dist/data/api/dto/read/read-selected-pagination-definition-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-search-definition-builder.d.ts +167 -0
- package/dist/data/api/dto/read/read-selected-search-definition-builder.js +267 -0
- package/dist/data/api/dto/read/read-selected-search-definition-dto.d.ts +33 -0
- package/dist/data/api/dto/read/read-selected-search-definition-dto.js +1 -0
- package/dist/data/api/dto/read/read-selected-search-property-definition-dto.d.ts +114 -0
- package/dist/data/api/dto/read/read-selected-search-property-definition-dto.js +1 -0
- package/dist/data/api/dto/read-options-dto.d.ts +8 -0
- package/dist/data/api/dto/read-options-dto.js +1 -0
- package/dist/data/api/dto/read-result-dto.d.ts +12 -0
- package/dist/data/api/dto/read-result-dto.js +1 -0
- package/dist/data/api/dto/read-result-metadata-dto.d.ts +8 -0
- package/dist/data/api/dto/read-result-metadata-dto.js +1 -0
- package/dist/data/api/dto/response/api-error-dto.d.ts +17 -0
- package/dist/data/api/dto/response/api-error-dto.js +1 -0
- package/dist/data/api/dto/response/api-error-response-dto.d.ts +11 -0
- package/dist/data/api/dto/response/api-error-response-dto.js +1 -0
- package/dist/data/api/dto/response/api-response-dto.d.ts +3 -0
- package/dist/data/api/dto/response/api-response-dto.js +1 -0
- package/dist/data/api/dto/response/api-success-response-dto.d.ts +13 -0
- package/dist/data/api/dto/response/api-success-response-dto.js +1 -0
- package/dist/data/api/dto/response/index.d.ts +5 -5
- package/dist/data/api/dto/response/index.js +5 -5
- package/dist/data/api/dto/response/metadata-dto.d.ts +25 -0
- package/dist/data/api/dto/response/metadata-dto.js +1 -0
- package/dist/data/api/enum/read/index.d.ts +5 -5
- package/dist/data/api/enum/read/index.js +5 -5
- package/dist/data/api/enum/read/read-selected-collection-operator.d.ts +16 -0
- package/dist/data/api/enum/read/read-selected-collection-operator.js +17 -0
- package/dist/data/api/enum/read/read-selected-comparison-operator.d.ts +69 -0
- package/dist/data/api/enum/read/read-selected-comparison-operator.js +76 -0
- package/dist/data/api/enum/read/read-selected-logical-operator.d.ts +15 -0
- package/dist/data/api/enum/read/read-selected-logical-operator.js +16 -0
- package/dist/data/api/enum/read/read-selected-ordering-direction.d.ts +13 -0
- package/dist/data/api/enum/read/read-selected-ordering-direction.js +14 -0
- package/dist/data/api/enum/read/read-selected-property-type.d.ts +66 -0
- package/dist/data/api/enum/read/read-selected-property-type.js +75 -0
- package/dist/data/api/enum/response/error-code.d.ts +14 -0
- package/dist/data/api/enum/response/error-code.js +15 -0
- package/dist/data/api/enum/response/index.d.ts +1 -1
- package/dist/data/api/enum/response/index.js +1 -1
- package/dist/data/api/interface/icommon-identifiable.d.ts +7 -0
- package/dist/data/api/interface/icommon-identifiable.js +1 -0
- package/dist/data/api/interface/iconcurrency-safe.d.ts +9 -0
- package/dist/data/api/interface/iconcurrency-safe.js +1 -0
- package/dist/data/api/interface/iidentifiable-secondary.d.ts +9 -0
- package/dist/data/api/interface/iidentifiable-secondary.js +1 -0
- package/dist/data/api/interface/iidentifiable.d.ts +11 -0
- package/dist/data/api/interface/iidentifiable.js +1 -0
- package/dist/data/api/interface/index.d.ts +4 -3
- package/dist/data/api/interface/index.js +4 -3
- package/dist/data/auth/dto/claim-dto.d.ts +4 -0
- package/dist/data/auth/dto/claim-dto.js +1 -0
- package/dist/data/auth/dto/index.d.ts +6 -5
- package/dist/data/auth/dto/index.js +6 -5
- package/dist/data/auth/dto/register-request-dto.d.ts +4 -0
- package/dist/data/auth/dto/register-request-dto.js +1 -0
- package/dist/data/auth/dto/role-dto.d.ts +5 -0
- package/dist/data/auth/dto/role-dto.js +1 -0
- package/dist/data/auth/dto/role-with-claims-dto.d.ts +5 -0
- package/dist/data/auth/dto/role-with-claims-dto.js +1 -0
- package/dist/data/auth/dto/sign-in-request-dto.d.ts +4 -0
- package/dist/data/auth/dto/sign-in-request-dto.js +1 -0
- package/dist/data/auth/dto/tokens-dto.d.ts +4 -0
- package/dist/data/auth/dto/tokens-dto.js +1 -0
- package/dist/data/auth/dto/user-dto.d.ts +16 -0
- package/dist/data/auth/dto/user-dto.js +1 -0
- package/dist/data/auth/dto/user-info-dto.d.ts +14 -0
- package/dist/data/auth/dto/user-info-dto.js +1 -0
- package/dist/services/api/api-crud-controller-client.d.ts +62 -0
- package/dist/services/api/api-crud-controller-client.integration.test.d.ts +1 -0
- package/dist/services/api/api-crud-controller-client.integration.test.js +34 -0
- package/dist/services/api/api-crud-controller-client.js +133 -0
- package/dist/services/api/api-initialization-service.d.ts +106 -0
- package/dist/services/api/api-initialization-service.js +207 -0
- package/dist/services/api/api-read-controller-client.d.ts +62 -0
- package/dist/services/api/api-read-controller-client.integration.test.d.ts +1 -0
- package/dist/services/api/api-read-controller-client.integration.test.js +59 -0
- package/dist/services/api/api-read-controller-client.js +129 -0
- package/dist/services/api/http-service/fetch-http-service.d.ts +7 -0
- package/dist/services/api/http-service/fetch-http-service.integration.test.d.ts +1 -0
- package/dist/services/api/http-service/fetch-http-service.integration.test.js +52 -0
- package/dist/services/api/http-service/fetch-http-service.js +29 -0
- package/dist/services/api/http-service/http-request-config.d.ts +10 -0
- package/dist/services/api/http-service/http-request-config.js +1 -0
- package/dist/services/api/http-service/http-response.d.ts +11 -0
- package/dist/services/api/http-service/http-response.js +3 -0
- package/dist/services/api/http-service/http-service.d.ts +5 -0
- package/dist/services/api/http-service/http-service.js +5 -0
- package/dist/services/api/http-service/ihttp-service.d.ts +13 -0
- package/dist/services/api/http-service/ihttp-service.js +3 -0
- package/dist/services/api/http-service/index.d.ts +5 -0
- package/dist/services/api/http-service/index.js +5 -0
- package/dist/services/api/index.d.ts +5 -5
- package/dist/services/api/index.js +5 -5
- package/dist/services/api/user-management-controller-client.d.ts +80 -0
- package/dist/services/api/user-management-controller-client.integration.test.d.ts +1 -0
- package/dist/services/api/user-management-controller-client.integration.test.js +60 -0
- package/dist/services/api/user-management-controller-client.js +291 -0
- package/dist/services/auth/client/auth-service.d.ts +75 -0
- package/dist/services/auth/client/auth-service.js +200 -0
- package/dist/services/auth/client/authorization-management-controller-client.d.ts +48 -0
- package/dist/services/auth/client/authorization-management-controller-client.integration.test.d.ts +1 -0
- package/dist/services/auth/client/authorization-management-controller-client.integration.test.js +89 -0
- package/dist/services/auth/client/authorization-management-controller-client.js +148 -0
- package/dist/services/auth/client/index.d.ts +2 -2
- package/dist/services/auth/client/index.js +2 -2
- package/dist/utils/authorization.d.ts +17 -0
- package/dist/utils/authorization.js +45 -0
- package/dist/utils/events.d.ts +19 -0
- package/dist/utils/events.js +12 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/result.d.ts +21 -0
- package/dist/utils/result.js +16 -0
- package/dist/utils/search.d.ts +34 -0
- package/dist/utils/search.js +106 -0
- package/package.json +6 -6
- package/src/adapters/collection-view-adapter.integration.test.ts +172 -0
- package/src/adapters/collection-view-adapter.ts +458 -0
- package/src/adapters/index.ts +2 -2
- package/src/adapters/search-adapter.ts +374 -0
- package/src/data/api/dto/crud/crud-metadata-dto.ts +4 -0
- package/src/data/api/dto/crud/index.ts +1 -1
- package/src/data/api/dto/index.ts +1 -1
- package/src/data/api/dto/read/index.ts +10 -10
- package/src/data/api/dto/read/{ReadSelectedSearchDefinitionBuilder.ts → read-selected-search-definition-builder.ts} +4 -4
- package/src/data/api/dto/{ReadResultDto.ts → read-result-dto.ts} +1 -1
- package/src/data/api/dto/response/{ApiErrorDto.ts → api-error-dto.ts} +1 -1
- package/src/data/api/dto/response/index.ts +5 -5
- package/src/data/api/enum/read/index.ts +5 -5
- package/src/data/api/enum/response/{ErrorCode.ts → error-code.ts} +1 -0
- package/src/data/api/enum/response/index.ts +1 -1
- package/src/data/api/interface/{ICommonIdentifiable.ts → icommon-identifiable.ts} +1 -1
- package/src/data/api/interface/{IConcurrencySafe.ts → iconcurrency-safe.ts} +1 -1
- package/src/data/api/interface/{IIdentifiable.ts → iidentifiable.ts} +1 -1
- package/src/data/api/interface/index.ts +4 -3
- package/src/data/auth/dto/index.ts +6 -5
- package/src/data/auth/dto/role-with-claims-dto.ts +6 -0
- package/src/data/auth/dto/{UserDto.ts → user-dto.ts} +5 -6
- package/src/services/api/{ApiCrudControllerClient/index.integration.test.ts → api-crud-controller-client.integration.test.ts} +1 -1
- package/src/services/api/{ApiCrudControllerClient/index.ts → api-crud-controller-client.ts} +62 -7
- package/src/services/api/{ApiInitializationService/index.ts → api-initialization-service.ts} +2 -4
- package/src/services/api/{ApiReadControllerClient/index.integration.test.ts → api-read-controller-client.integration.test.ts} +1 -1
- package/src/services/api/{ApiReadControllerClient/index.ts → api-read-controller-client.ts} +55 -6
- package/src/services/api/{HttpService/FetchHttpService.integration.test.ts → http-service/fetch-http-service.integration.test.ts} +1 -1
- package/src/services/api/http-service/http-service.ts +6 -0
- package/src/services/api/http-service/index.ts +5 -0
- package/src/services/api/index.ts +5 -5
- package/src/services/api/{UserManagementControllerClient/index.integration.test.ts → user-management-controller-client.integration.test.ts} +1 -1
- package/src/services/api/user-management-controller-client.ts +322 -0
- package/src/services/auth/client/index.ts +2 -2
- package/src/utils/events.ts +29 -0
- package/src/utils/index.ts +2 -0
- package/demo/index.ts +0 -29
- package/demo/public_html/favicon.ico +0 -0
- package/demo/public_html/index.html +0 -105
- package/demo/public_html/websettings.json +0 -3
- package/src/adapters/CollectionViewAdapter/index.integration.test.ts +0 -197
- package/src/adapters/CollectionViewAdapter/index.ts +0 -477
- package/src/adapters/SearchAdapter/index.ts +0 -302
- package/src/services/api/HttpService/index.ts +0 -12
- package/src/services/api/UserManagementControllerClient/index.ts +0 -134
- /package/{src/data/api/dto/crud/CrudMetadataDto.ts → dist/data/api/dto/crud/crud-metadata-dto.d.ts} +0 -0
- /package/src/data/api/dto/{PropertyPathDto.ts → property-path-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadMetadataDto.ts → read-metadata-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedDefinitionDto.ts → read-selected-definition-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedNestedCollectionCriteriaDto.ts → read-selected-nested-collection-criteria-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedNestedCriteriaDto.ts → read-selected-nested-criteria-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedOrderingDefinitionDto.ts → read-selected-ordering-definition-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedOrderingPropertyDefinitionDto.ts → read-selected-ordering-property-definition-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedPaginationDefinitionDto.ts → read-selected-pagination-definition-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedSearchDefinitionDto.ts → read-selected-search-definition-dto.ts} +0 -0
- /package/src/data/api/dto/read/{ReadSelectedSearchPropertyDefinitionDto.ts → read-selected-search-property-definition-dto.ts} +0 -0
- /package/src/data/api/dto/{ReadOptionsDto.ts → read-options-dto.ts} +0 -0
- /package/src/data/api/dto/{ReadResultMetadataDto.ts → read-result-metadata-dto.ts} +0 -0
- /package/src/data/api/dto/response/{ApiErrorResponseDto.ts → api-error-response-dto.ts} +0 -0
- /package/src/data/api/dto/response/{ApiResponseDto.ts → api-response-dto.ts} +0 -0
- /package/src/data/api/dto/response/{ApiSuccessResponseDto.ts → api-success-response-dto.ts} +0 -0
- /package/src/data/api/dto/response/{MetadataDto.ts → metadata-dto.ts} +0 -0
- /package/src/data/api/enum/read/{ReadSelectedCollectionOperator.ts → read-selected-collection-operator.ts} +0 -0
- /package/src/data/api/enum/read/{ReadSelectedComparisonOperator.ts → read-selected-comparison-operator.ts} +0 -0
- /package/src/data/api/enum/read/{ReadSelectedLogicalOperator.ts → read-selected-logical-operator.ts} +0 -0
- /package/src/data/api/enum/read/{ReadSelectedOrderingDirection.ts → read-selected-ordering-direction.ts} +0 -0
- /package/src/data/api/enum/read/{ReadSelectedPropertyType.ts → read-selected-property-type.ts} +0 -0
- /package/src/data/api/interface/{IIdentifiableSecondary.ts → iidentifiable-secondary.ts} +0 -0
- /package/src/data/auth/dto/{ClaimDto.ts → claim-dto.ts} +0 -0
- /package/src/data/auth/dto/{RegisterRequestDto.ts → register-request-dto.ts} +0 -0
- /package/src/data/auth/dto/{RoleDto.ts → role-dto.ts} +0 -0
- /package/src/data/auth/dto/{SignInRequestDto.ts → sign-in-request-dto.ts} +0 -0
- /package/src/data/auth/dto/{TokensDto.ts → tokens-dto.ts} +0 -0
- /package/src/data/auth/dto/{UserInfoDto.ts → user-info-dto.ts} +0 -0
- /package/src/services/api/{HttpService → http-service}/README.md +0 -0
- /package/src/services/api/{HttpService/FetchHttpService.ts → http-service/fetch-http-service.ts} +0 -0
- /package/src/services/api/{HttpService/HttpRequestConfig.ts → http-service/http-request-config.ts} +0 -0
- /package/src/services/api/{HttpService/HttpResponse.ts → http-service/http-response.ts} +0 -0
- /package/src/services/api/{HttpService/IHttpService.ts → http-service/ihttp-service.ts} +0 -0
- /package/src/services/auth/client/{AuthService/index.ts → auth-service.ts} +0 -0
- /package/src/services/auth/client/{AuthorizationManagementControllerClient/index.integration.test.ts → authorization-management-controller-client.integration.test.ts} +0 -0
- /package/src/services/auth/client/{AuthorizationManagementControllerClient/index.ts → authorization-management-controller-client.ts} +0 -0
- /package/src/utils/{authorization/index.ts → authorization.ts} +0 -0
- /package/src/utils/{result/index.ts → result.ts} +0 -0
- /package/src/utils/{search/index.ts → search.ts} +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { CollectionViewAdapter, CollectionViewAdapterOptions } from '.';
|
|
3
|
+
import { ReadSelectedComparisonOperator, ReadSelectedOrderingDirection, ReadSelectedPropertyType } from '@/data';
|
|
4
|
+
import { dateInterval, searchTerm } from '@/utils';
|
|
5
|
+
import { ApiReadControllerClient } from '@services';
|
|
6
|
+
|
|
7
|
+
type TestDto = { id: number; name: string; dateOfBirth: string; rowVersion: string };
|
|
8
|
+
|
|
9
|
+
describe('CollectionViewAdapter', () => {
|
|
10
|
+
const options: CollectionViewAdapterOptions<TestDto> = {
|
|
11
|
+
primaryKey: 'id',
|
|
12
|
+
pagination: { defaultPageSize: 5, defaultPageIndex: 0 },
|
|
13
|
+
ordering: { maxOrderingColumns: 1 },
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let adapter: CollectionViewAdapter<TestDto>;
|
|
17
|
+
|
|
18
|
+
const waitForData = async (adapterInstance: CollectionViewAdapter<TestDto>, timeout = 2000) => {
|
|
19
|
+
const start = Date.now();
|
|
20
|
+
while (adapterInstance.isLoading && Date.now() - start < timeout) {
|
|
21
|
+
await new Promise(res => setTimeout(res, 50));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
options.pagination = { defaultPageSize: 5, defaultPageIndex: 0 };
|
|
27
|
+
options.ordering = { maxOrderingColumns: 1 };
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('returns correct loading status and collection data', async () => {
|
|
31
|
+
adapter = new CollectionViewAdapter(options, 'AnythingManuallyMappedRead');
|
|
32
|
+
await waitForData(adapter);
|
|
33
|
+
|
|
34
|
+
expect(adapter.isLoading).toBe(false);
|
|
35
|
+
expect(adapter.pageData).toBeDefined();
|
|
36
|
+
expect(adapter.pageData!.length).toBeGreaterThan(0);
|
|
37
|
+
expect(adapter.error).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('adapter options set correct ordering', async () => {
|
|
41
|
+
adapter = new CollectionViewAdapter(options, 'AnythingManuallyMappedRead');
|
|
42
|
+
await waitForData(adapter);
|
|
43
|
+
adapter.setOrdering(['name'], ReadSelectedOrderingDirection.Descending);
|
|
44
|
+
await waitForData(adapter);
|
|
45
|
+
|
|
46
|
+
expect(adapter.ordering).toEqual([
|
|
47
|
+
{
|
|
48
|
+
path: ['name'],
|
|
49
|
+
direction: ReadSelectedOrderingDirection.Descending,
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('text search is applied to adapter', async () => {
|
|
55
|
+
const searchDefinition = searchTerm('Flu', ['name'], ['id']);
|
|
56
|
+
if (!searchDefinition) throw new Error('searchDefinition is undefined');
|
|
57
|
+
adapter = new CollectionViewAdapter(options, new ApiReadControllerClient<number, TestDto, TestDto>('AnythingManuallyMappedRead'));
|
|
58
|
+
await waitForData(adapter);
|
|
59
|
+
adapter.setSearch(searchDefinition);
|
|
60
|
+
await waitForData(adapter);
|
|
61
|
+
|
|
62
|
+
expect(adapter.pageData).toBeDefined();
|
|
63
|
+
expect(adapter.pageData!.length).toBeGreaterThan(0);
|
|
64
|
+
for (const item of adapter.pageData!) {
|
|
65
|
+
expect(item.name).toMatch(/flu/i);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('numeric search is applied to adapter', async () => {
|
|
70
|
+
const searchDefinition = searchTerm('10000001', ['id'], ['id']);
|
|
71
|
+
if (!searchDefinition) throw new Error('searchDefinition is undefined');
|
|
72
|
+
adapter = new CollectionViewAdapter(options, new ApiReadControllerClient<number, TestDto, TestDto>('AnythingManuallyMappedRead'));
|
|
73
|
+
await waitForData(adapter);
|
|
74
|
+
adapter.setSearch(searchDefinition);
|
|
75
|
+
await waitForData(adapter);
|
|
76
|
+
|
|
77
|
+
expect(adapter.pageData).toBeDefined();
|
|
78
|
+
expect(adapter.pageData!.length).toBe(1);
|
|
79
|
+
for (const item of adapter.pageData!) {
|
|
80
|
+
expect(item.id).toBe(10000001);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('applies date range filter from-to on the same date type property', async () => {
|
|
85
|
+
adapter = new CollectionViewAdapter(options, new ApiReadControllerClient<number, TestDto, TestDto>('PetsSlim'));
|
|
86
|
+
const from = new Date('2017-01-01T00:00:00.000Z');
|
|
87
|
+
const to = new Date('2017-12-31T00:00:00.000Z');
|
|
88
|
+
|
|
89
|
+
const searchDefinition = dateInterval<TestDto>(
|
|
90
|
+
from,
|
|
91
|
+
to,
|
|
92
|
+
ReadSelectedComparisonOperator.GreaterOrEqual,
|
|
93
|
+
ReadSelectedComparisonOperator.LessOrEqual,
|
|
94
|
+
ReadSelectedPropertyType.DateOnly,
|
|
95
|
+
'dateOfBirth',
|
|
96
|
+
);
|
|
97
|
+
if (!searchDefinition) throw new Error('searchDefinition is undefined');
|
|
98
|
+
await waitForData(adapter);
|
|
99
|
+
adapter.setSearch(searchDefinition);
|
|
100
|
+
await waitForData(adapter);
|
|
101
|
+
|
|
102
|
+
expect(adapter.pageData).toBeDefined();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('applies pagination: page size and jump to page set skip/limit', async () => {
|
|
106
|
+
adapter = new CollectionViewAdapter(options, 'AnythingManuallyMappedRead');
|
|
107
|
+
await waitForData(adapter);
|
|
108
|
+
const firstPageData = [...adapter.pageData!];
|
|
109
|
+
adapter.setPageIndex(3);
|
|
110
|
+
await waitForData(adapter);
|
|
111
|
+
|
|
112
|
+
expect(adapter.pageData).toBeDefined();
|
|
113
|
+
expect(adapter.pageData!.length).toBe(5);
|
|
114
|
+
expect([...adapter.pageData!]).not.toEqual(firstPageData);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('calculates total when server does not return totalCount', async () => {
|
|
118
|
+
options.pagination = { defaultPageSize: 10, defaultPageIndex: 0 };
|
|
119
|
+
adapter = new CollectionViewAdapter(options, 'AnythingManuallyMappedRead');
|
|
120
|
+
await waitForData(adapter);
|
|
121
|
+
const firstPageLength = adapter.pageData!.length;
|
|
122
|
+
adapter.setPageIndex(2);
|
|
123
|
+
await waitForData(adapter);
|
|
124
|
+
|
|
125
|
+
expect(adapter.totalItemCount).toBe(firstPageLength + adapter.pageData!.length);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('setOrdering correctly handles PropertyPathDto array comparison and limits columns', async () => {
|
|
129
|
+
options.ordering = { maxOrderingColumns: 2 };
|
|
130
|
+
adapter = new CollectionViewAdapter(options, 'AnythingManuallyMappedRead');
|
|
131
|
+
adapter.setOrdering(['name'], ReadSelectedOrderingDirection.Descending);
|
|
132
|
+
await waitForData(adapter);
|
|
133
|
+
|
|
134
|
+
expect(adapter.ordering).toEqual([
|
|
135
|
+
{
|
|
136
|
+
path: ['name'],
|
|
137
|
+
direction: ReadSelectedOrderingDirection.Descending,
|
|
138
|
+
},
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
// Add second ordering
|
|
142
|
+
adapter.setOrdering(['id'], ReadSelectedOrderingDirection.Ascending);
|
|
143
|
+
await waitForData(adapter);
|
|
144
|
+
|
|
145
|
+
// Should have both orderings, with 'id' first (most recent)
|
|
146
|
+
expect(adapter.ordering).toEqual([
|
|
147
|
+
{
|
|
148
|
+
path: ['id'],
|
|
149
|
+
direction: ReadSelectedOrderingDirection.Ascending,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
path: ['name'],
|
|
153
|
+
direction: ReadSelectedOrderingDirection.Descending,
|
|
154
|
+
},
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
// Add third ordering - should remove the oldest one (name)
|
|
158
|
+
adapter.setOrdering(['description'], ReadSelectedOrderingDirection.Descending);
|
|
159
|
+
await waitForData(adapter);
|
|
160
|
+
|
|
161
|
+
expect(adapter.ordering).toEqual([
|
|
162
|
+
{
|
|
163
|
+
path: ['description'],
|
|
164
|
+
direction: ReadSelectedOrderingDirection.Descending,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
path: ['id'],
|
|
168
|
+
direction: ReadSelectedOrderingDirection.Ascending,
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ErrorCode,
|
|
3
|
+
PropertyPathDto,
|
|
4
|
+
ReadSelectedDefinitionDto,
|
|
5
|
+
ReadSelectedLogicalOperator,
|
|
6
|
+
ReadSelectedOrderingDirection,
|
|
7
|
+
ReadSelectedSearchDefinitionDto,
|
|
8
|
+
} from '@data';
|
|
9
|
+
import { IHasObservableProperty, SingularEventTarget, toPascalCase } from '@utils';
|
|
10
|
+
import { ApiReadControllerClient } from '@services';
|
|
11
|
+
import { IReadSelectedClient } from '@services/api';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Options for the CollectionViewAdapter
|
|
15
|
+
*/
|
|
16
|
+
export type CollectionViewAdapterOptions<TDto> = {
|
|
17
|
+
pagination?: {
|
|
18
|
+
defaultPageSize?: number;
|
|
19
|
+
defaultPageIndex?: number;
|
|
20
|
+
};
|
|
21
|
+
ordering?: {
|
|
22
|
+
maxOrderingColumns?: number;
|
|
23
|
+
defaultOrdering?: {
|
|
24
|
+
path: PropertyPathDto;
|
|
25
|
+
direction: ReadSelectedOrderingDirection;
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
28
|
+
search?: {
|
|
29
|
+
defaultSearch?: ReadSelectedSearchDefinitionDto<TDto>;
|
|
30
|
+
};
|
|
31
|
+
} & {
|
|
32
|
+
primaryKey: string | ((item: TDto) => string);
|
|
33
|
+
selection?: {
|
|
34
|
+
enabled: 'single' | 'multiple' | false;
|
|
35
|
+
defaultSelection?: TDto[];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Adapter for managing a collection view of data
|
|
41
|
+
*/
|
|
42
|
+
export interface ICollectionViewAdapter<TDto>
|
|
43
|
+
extends
|
|
44
|
+
IHasObservableProperty<'isLoading', boolean>,
|
|
45
|
+
IHasObservableProperty<'pageData', readonly TDto[] | undefined>,
|
|
46
|
+
IHasObservableProperty<'error', string | undefined>,
|
|
47
|
+
IHasObservableProperty<'totalItemCount', number>,
|
|
48
|
+
IHasObservableProperty<'pageIndex', number>,
|
|
49
|
+
IHasObservableProperty<'pageSize', number>,
|
|
50
|
+
IHasObservableProperty<'ordering', readonly { path: PropertyPathDto; direction: ReadSelectedOrderingDirection }[]>,
|
|
51
|
+
IHasObservableProperty<'selection', readonly TDto[]>,
|
|
52
|
+
IHasObservableProperty<'search', ReadSelectedSearchDefinitionDto<TDto>> {
|
|
53
|
+
setSearch(searchDefinition: ReadSelectedSearchDefinitionDto<TDto>): void;
|
|
54
|
+
|
|
55
|
+
setOrdering(propertyPath: PropertyPathDto, orderDirection: ReadSelectedOrderingDirection): void;
|
|
56
|
+
|
|
57
|
+
setPageIndex(pageNumber: number): void;
|
|
58
|
+
setPageSize(pageSize: number): void;
|
|
59
|
+
refreshData(): void;
|
|
60
|
+
|
|
61
|
+
selectionToggle(item: TDto): void;
|
|
62
|
+
selectionAdd(item: TDto): void;
|
|
63
|
+
selectionRemove(item: TDto): void;
|
|
64
|
+
selectionClear(): void;
|
|
65
|
+
isSelected(item: TDto): boolean;
|
|
66
|
+
selectionAddPage(): void;
|
|
67
|
+
selectionRemovePage(): void;
|
|
68
|
+
isSelectedPage(): boolean;
|
|
69
|
+
isSomeSelectedPage(): boolean;
|
|
70
|
+
|
|
71
|
+
destroy(): void;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Adapter for managing a collection view of data
|
|
76
|
+
*/
|
|
77
|
+
export class CollectionViewAdapter<TDto> implements ICollectionViewAdapter<TDto> {
|
|
78
|
+
// #region Event targets
|
|
79
|
+
|
|
80
|
+
public readonly isLoadingChanged = new SingularEventTarget<boolean>();
|
|
81
|
+
public readonly pageDataChanged = new SingularEventTarget<readonly TDto[] | undefined>();
|
|
82
|
+
public readonly errorChanged = new SingularEventTarget<string | undefined>();
|
|
83
|
+
public readonly totalItemCountChanged = new SingularEventTarget<number>();
|
|
84
|
+
public readonly pageIndexChanged = new SingularEventTarget<number>();
|
|
85
|
+
public readonly pageSizeChanged = new SingularEventTarget<number>();
|
|
86
|
+
public readonly selectionChanged = new SingularEventTarget<readonly TDto[]>();
|
|
87
|
+
public readonly searchChanged = new SingularEventTarget<ReadSelectedSearchDefinitionDto<TDto> | undefined>();
|
|
88
|
+
public readonly orderingChanged = new SingularEventTarget<readonly { path: PropertyPathDto; direction: ReadSelectedOrderingDirection }[]>();
|
|
89
|
+
// #endregion
|
|
90
|
+
|
|
91
|
+
private _readClient: IReadSelectedClient<any, any>;
|
|
92
|
+
|
|
93
|
+
private _isLoading = false;
|
|
94
|
+
private _pageData: TDto[] | undefined = undefined;
|
|
95
|
+
private _error: string | undefined = undefined;
|
|
96
|
+
private _totalItemCount = 0;
|
|
97
|
+
private _pageIndex = 0;
|
|
98
|
+
private _pageSize = 0;
|
|
99
|
+
private _selection: TDto[] = [];
|
|
100
|
+
private _search: ReadSelectedSearchDefinitionDto<TDto> = { logicalOperator: ReadSelectedLogicalOperator.And };
|
|
101
|
+
private _ordering: { path: PropertyPathDto; direction: ReadSelectedOrderingDirection }[] = [];
|
|
102
|
+
private _currentAbortController?: AbortController;
|
|
103
|
+
private _fetchTimeout?: ReturnType<typeof setTimeout>;
|
|
104
|
+
|
|
105
|
+
private _defaultOptions: Partial<CollectionViewAdapterOptions<TDto>> = {
|
|
106
|
+
pagination: {
|
|
107
|
+
defaultPageSize: 10,
|
|
108
|
+
defaultPageIndex: 0,
|
|
109
|
+
},
|
|
110
|
+
ordering: {
|
|
111
|
+
maxOrderingColumns: 1,
|
|
112
|
+
defaultOrdering: undefined,
|
|
113
|
+
},
|
|
114
|
+
search: {
|
|
115
|
+
defaultSearch: undefined,
|
|
116
|
+
},
|
|
117
|
+
selection: {
|
|
118
|
+
enabled: false,
|
|
119
|
+
defaultSelection: [],
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
private _currentOptions: CollectionViewAdapterOptions<TDto>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a new instance of CollectionViewAdapter
|
|
127
|
+
* @param options Options for the adapter
|
|
128
|
+
* @param client The client to use for reading data. If a string is provided, it will be used as the controller name for the ApiReadControllerClient, otherwise the provided client will be used directly.
|
|
129
|
+
*/
|
|
130
|
+
constructor(options: CollectionViewAdapterOptions<TDto>, client: IReadSelectedClient<any, any> | string) {
|
|
131
|
+
this._readClient = typeof client === 'string' ? new ApiReadControllerClient<any, any, any>(client) : client;
|
|
132
|
+
|
|
133
|
+
this._currentOptions = {
|
|
134
|
+
...options,
|
|
135
|
+
pagination: {
|
|
136
|
+
...this._defaultOptions.pagination,
|
|
137
|
+
...options.pagination,
|
|
138
|
+
},
|
|
139
|
+
ordering: {
|
|
140
|
+
...this._defaultOptions.ordering,
|
|
141
|
+
...options.ordering,
|
|
142
|
+
},
|
|
143
|
+
search: {
|
|
144
|
+
...this._defaultOptions.search,
|
|
145
|
+
...options.search,
|
|
146
|
+
},
|
|
147
|
+
selection: options.selection ?? this._defaultOptions.selection,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
this._pageIndex = this._currentOptions.pagination?.defaultPageIndex ?? this._pageIndex;
|
|
151
|
+
this._pageSize = this._currentOptions.pagination?.defaultPageSize ?? this._pageSize;
|
|
152
|
+
this._search = this._currentOptions.search?.defaultSearch ?? this._search;
|
|
153
|
+
this._selection = this._currentOptions.selection?.defaultSelection ?? this._selection;
|
|
154
|
+
this._ordering = this._currentOptions.ordering?.defaultOrdering ?? this._ordering;
|
|
155
|
+
|
|
156
|
+
this._scheduleFetch();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// #region Getters
|
|
160
|
+
|
|
161
|
+
public get isLoading(): boolean {
|
|
162
|
+
return this._isLoading;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public get pageData(): readonly TDto[] | undefined {
|
|
166
|
+
return this._pageData;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public get error(): string | undefined {
|
|
170
|
+
return this._error;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public get totalItemCount(): number {
|
|
174
|
+
return this._totalItemCount;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public get pageIndex(): number {
|
|
178
|
+
return this._pageIndex;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public get pageSize(): number {
|
|
182
|
+
return this._pageSize;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public get selection(): readonly TDto[] {
|
|
186
|
+
return this._selection;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public get search(): ReadSelectedSearchDefinitionDto<TDto> {
|
|
190
|
+
return this._search;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// #endregion
|
|
194
|
+
// #region Search
|
|
195
|
+
|
|
196
|
+
public setSearch(searchDefinition: ReadSelectedSearchDefinitionDto<TDto>): void {
|
|
197
|
+
this._search = searchDefinition;
|
|
198
|
+
this._pageIndex = 0;
|
|
199
|
+
this.searchChanged.dispatchEvent(searchDefinition);
|
|
200
|
+
this.pageIndexChanged.dispatchEvent(0);
|
|
201
|
+
this._scheduleFetch();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public get ordering(): readonly { path: PropertyPathDto; direction: ReadSelectedOrderingDirection }[] {
|
|
205
|
+
return this._ordering;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// #endregion
|
|
209
|
+
// #region Ordering
|
|
210
|
+
|
|
211
|
+
public setOrdering(propertyPath: PropertyPathDto, orderDirection: ReadSelectedOrderingDirection): void {
|
|
212
|
+
this._ordering = this._ordering.filter(p => !this._arePropertyPathsEqual(p.path, propertyPath));
|
|
213
|
+
|
|
214
|
+
this._ordering = [{ path: propertyPath, direction: orderDirection }, ...this._ordering];
|
|
215
|
+
|
|
216
|
+
const maxColumns = this._currentOptions.ordering?.maxOrderingColumns ?? 1;
|
|
217
|
+
if (this._ordering.length > maxColumns) {
|
|
218
|
+
this._ordering = this._ordering.slice(0, maxColumns);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
this._pageIndex = 0;
|
|
222
|
+
this.orderingChanged.dispatchEvent(this._ordering);
|
|
223
|
+
this.pageIndexChanged.dispatchEvent(0);
|
|
224
|
+
this._scheduleFetch();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// #endregion
|
|
228
|
+
|
|
229
|
+
// #region Pagination
|
|
230
|
+
|
|
231
|
+
public setPageIndex(pageIndex: number): void {
|
|
232
|
+
this._pageIndex = pageIndex;
|
|
233
|
+
this.pageIndexChanged.dispatchEvent(pageIndex);
|
|
234
|
+
this._scheduleFetch();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
public setPageSize(pageSize: number): void {
|
|
238
|
+
this._pageSize = pageSize;
|
|
239
|
+
this._pageIndex = 0;
|
|
240
|
+
this.pageSizeChanged.dispatchEvent(pageSize);
|
|
241
|
+
this.pageIndexChanged.dispatchEvent(0);
|
|
242
|
+
this._scheduleFetch();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public refreshData(): void {
|
|
246
|
+
this._scheduleFetch();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// #endregion
|
|
250
|
+
// #region Selection
|
|
251
|
+
|
|
252
|
+
private _getItemKey(item: TDto): string {
|
|
253
|
+
const pk = this._currentOptions.primaryKey;
|
|
254
|
+
if (typeof pk === 'function') return pk(item);
|
|
255
|
+
return String((item as Record<string, unknown>)[pk]);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private get _selectionEnabled(): 'single' | 'multiple' | false {
|
|
259
|
+
return this._currentOptions.selection?.enabled ?? false;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public selectionToggle(item: TDto): void {
|
|
263
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
264
|
+
const key = this._getItemKey(item);
|
|
265
|
+
if (this._selection.find(x => this._getItemKey(x) === key)) {
|
|
266
|
+
this._selection = this._selection.filter(x => this._getItemKey(x) !== key);
|
|
267
|
+
} else if (this._selectionEnabled === 'single') {
|
|
268
|
+
this._selection = [item];
|
|
269
|
+
} else {
|
|
270
|
+
this._selection = [...this._selection, item];
|
|
271
|
+
}
|
|
272
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
public selectionAdd(item: TDto): void {
|
|
276
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
277
|
+
const key = this._getItemKey(item);
|
|
278
|
+
if (this._selection.find(x => this._getItemKey(x) === key)) return;
|
|
279
|
+
if (this._selectionEnabled === 'single') {
|
|
280
|
+
this._selection = [item];
|
|
281
|
+
} else {
|
|
282
|
+
this._selection = [...this._selection, item];
|
|
283
|
+
}
|
|
284
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public selectionRemove(item: TDto): void {
|
|
288
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
289
|
+
const key = this._getItemKey(item);
|
|
290
|
+
this._selection = this._selection.filter(x => this._getItemKey(x) !== key);
|
|
291
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
public selectionClear(): void {
|
|
295
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
296
|
+
this._selection = [];
|
|
297
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public isSelected(item: TDto): boolean {
|
|
301
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
302
|
+
const key = this._getItemKey(item);
|
|
303
|
+
return this._selection.some(x => this._getItemKey(x) === key);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
public selectionAddPage(): void {
|
|
307
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
308
|
+
if (this._selectionEnabled !== 'multiple' || !this._pageData) return;
|
|
309
|
+
const newItems = this._pageData.filter(item => !this.isSelected(item));
|
|
310
|
+
if (newItems.length > 0) {
|
|
311
|
+
this._selection = [...this._selection, ...newItems];
|
|
312
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
public selectionRemovePage(): void {
|
|
317
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
318
|
+
if (!this._pageData) return;
|
|
319
|
+
const pageItemKeys = new Set(this._pageData.map(item => this._getItemKey(item)));
|
|
320
|
+
this._selection = this._selection.filter(item => !pageItemKeys.has(this._getItemKey(item)));
|
|
321
|
+
this.selectionChanged.dispatchEvent(this._selection);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public isSelectedPage(): boolean {
|
|
325
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
326
|
+
if (!this._pageData || this._pageData.length === 0) return false;
|
|
327
|
+
return this._pageData.every(item => this.isSelected(item));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
public isSomeSelectedPage(): boolean {
|
|
331
|
+
if (!this._selectionEnabled) throw new Error('Selection is not enabled');
|
|
332
|
+
if (!this._pageData || this._pageData.length === 0) return false;
|
|
333
|
+
const selectedCount = this._pageData.filter(item => this.isSelected(item)).length;
|
|
334
|
+
return selectedCount > 0 && selectedCount < this._pageData.length;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// #endregion
|
|
338
|
+
|
|
339
|
+
// #region Lifecycle
|
|
340
|
+
|
|
341
|
+
public destroy(): void {
|
|
342
|
+
this._cancelPendingRequests();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// #endregion
|
|
346
|
+
|
|
347
|
+
// #region Private
|
|
348
|
+
|
|
349
|
+
private _scheduleFetch(): void {
|
|
350
|
+
this._isLoading = true;
|
|
351
|
+
this.isLoadingChanged.dispatchEvent(true);
|
|
352
|
+
if (this._fetchTimeout !== undefined) {
|
|
353
|
+
clearTimeout(this._fetchTimeout);
|
|
354
|
+
}
|
|
355
|
+
this._fetchTimeout = setTimeout(() => this._executeFetch(), 50);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
private async _executeFetch(): Promise<void> {
|
|
359
|
+
let abortController: AbortController | undefined;
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
if (this._currentAbortController) {
|
|
363
|
+
try {
|
|
364
|
+
this._currentAbortController.abort();
|
|
365
|
+
} catch {
|
|
366
|
+
// Ignore abort errors
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
abortController = new AbortController();
|
|
370
|
+
this._currentAbortController = abortController;
|
|
371
|
+
|
|
372
|
+
const definition = this._parseOptionsToDefinition();
|
|
373
|
+
const response = await this._readClient.readSelected(definition, abortController.signal);
|
|
374
|
+
|
|
375
|
+
if (!response.ok) {
|
|
376
|
+
if (response.error.code === ErrorCode.Aborted) return;
|
|
377
|
+
this._error = response.error.details ?? response.error.message ?? 'Unknown error';
|
|
378
|
+
this._pageData = [];
|
|
379
|
+
} else {
|
|
380
|
+
this._error = undefined;
|
|
381
|
+
this._pageData = response.result;
|
|
382
|
+
|
|
383
|
+
if (response.metadata.totalCount !== undefined) {
|
|
384
|
+
this._totalItemCount = response.metadata.totalCount;
|
|
385
|
+
} else {
|
|
386
|
+
this._totalItemCount = this._calculateTotal(this._pageSize, this._pageIndex, this._pageData.length, this._totalItemCount);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
} catch (error: unknown) {
|
|
390
|
+
console.error('Error fetching data:', error);
|
|
391
|
+
this._error = error instanceof Error ? error.message : 'Unknown error';
|
|
392
|
+
} finally {
|
|
393
|
+
if (abortController && this._currentAbortController === abortController) {
|
|
394
|
+
this._isLoading = false;
|
|
395
|
+
this._currentAbortController = undefined;
|
|
396
|
+
this.isLoadingChanged.dispatchEvent(false);
|
|
397
|
+
this.pageDataChanged.dispatchEvent(this._pageData);
|
|
398
|
+
this.errorChanged.dispatchEvent(this._error);
|
|
399
|
+
this.totalItemCountChanged.dispatchEvent(this._totalItemCount);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private _cancelPendingRequests(): void {
|
|
405
|
+
if (this._fetchTimeout !== undefined) {
|
|
406
|
+
clearTimeout(this._fetchTimeout);
|
|
407
|
+
this._fetchTimeout = undefined;
|
|
408
|
+
}
|
|
409
|
+
if (this._currentAbortController) {
|
|
410
|
+
try {
|
|
411
|
+
this._currentAbortController.abort();
|
|
412
|
+
} catch {
|
|
413
|
+
// Ignore abort errors
|
|
414
|
+
}
|
|
415
|
+
this._currentAbortController = undefined;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private _parseOptionsToDefinition(): ReadSelectedDefinitionDto<TDto> {
|
|
420
|
+
const definition: ReadSelectedDefinitionDto<TDto> = {
|
|
421
|
+
paginationDefinition: {
|
|
422
|
+
skip: this._pageIndex * this._pageSize,
|
|
423
|
+
limit: this._pageSize,
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
if (this._ordering.length > 0) {
|
|
428
|
+
definition.orderingDefinition = {
|
|
429
|
+
order: this._ordering.map(o => ({
|
|
430
|
+
propertyPath: o.path.map(x => toPascalCase(x)) as PropertyPathDto,
|
|
431
|
+
direction: o.direction,
|
|
432
|
+
})),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
definition.searchDefinition = this._search;
|
|
437
|
+
|
|
438
|
+
return definition;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private _arePropertyPathsEqual(path1: PropertyPathDto, path2: PropertyPathDto): boolean {
|
|
442
|
+
if (path1.length !== path2.length) return false;
|
|
443
|
+
return path1.every((segment, index) => segment === path2[index]);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private _calculateTotal(pageSize: number, pageIndex: number, itemsOnCurrentPageCount: number, previousTotal: number): number {
|
|
447
|
+
if (itemsOnCurrentPageCount === 0) {
|
|
448
|
+
if (pageSize === 0) return 0;
|
|
449
|
+
return pageSize * pageIndex;
|
|
450
|
+
}
|
|
451
|
+
if (itemsOnCurrentPageCount < pageSize) {
|
|
452
|
+
return pageSize * pageIndex + itemsOnCurrentPageCount;
|
|
453
|
+
}
|
|
454
|
+
return previousTotal;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// #endregion
|
|
458
|
+
}
|
package/src/adapters/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './collection-view-adapter';
|
|
2
|
+
export * from './search-adapter';
|