@openmfp/webcomponents 0.6.1 → 0.6.7
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/mfp-wc-dashboard.js +153 -0
- package/mfp-webcomponents.js +573 -0
- package/package.json +14 -68
- package/.github/workflows/pipeline.yaml +0 -41
- package/.storybook/main.ts +0 -34
- package/.storybook/preview.ts +0 -29
- package/.storybook/tsconfig.json +0 -11
- package/AGENTS.md +0 -153
- package/CODEOWNERS +0 -6
- package/CONTRIBUTING.md +0 -95
- package/LICENSE +0 -201
- package/LICENSES/Apache-2.0.txt +0 -73
- package/README.md +0 -91
- package/REUSE.toml +0 -9
- package/angular.json +0 -157
- package/docs/dashboard.md +0 -358
- package/docs/declarative-form.md +0 -178
- package/docs/declarative-table-card.md +0 -235
- package/docs/declarative-table.md +0 -315
- package/eslint.config.js +0 -41
- package/projects/ngx/cards/favorites/favorites.component.html +0 -12
- package/projects/ngx/cards/favorites/favorites.component.scss +0 -50
- package/projects/ngx/cards/favorites/favorites.component.ts +0 -19
- package/projects/ngx/cards/public-api.ts +0 -4
- package/projects/ngx/cards/service-status/service-status-card.component.html +0 -15
- package/projects/ngx/cards/service-status/service-status-card.component.scss +0 -87
- package/projects/ngx/cards/service-status/service-status-card.component.ts +0 -36
- package/projects/ngx/cards/stories/visited-service-card.stories.ts +0 -149
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.html +0 -17
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.scss +0 -34
- package/projects/ngx/cards/visited-service-card/visited-service-card.component.ts +0 -22
- package/projects/ngx/cards/whats-new/whats-new.component.html +0 -10
- package/projects/ngx/cards/whats-new/whats-new.component.scss +0 -25
- package/projects/ngx/cards/whats-new/whats-new.component.ts +0 -46
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.html +0 -28
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.scss +0 -44
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.spec.ts +0 -85
- package/projects/ngx/declarative-ui/dashboard/add-card-dialog/add-card-dialog.component.ts +0 -58
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.html +0 -29
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.scss +0 -63
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.spec.ts +0 -255
- package/projects/ngx/declarative-ui/dashboard/card/dashboard-card.component.ts +0 -75
- package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.spec.ts +0 -76
- package/projects/ngx/declarative-ui/dashboard/card/utils/dashboard-card-registry.ts +0 -109
- package/projects/ngx/declarative-ui/dashboard/card/utils/index.ts +0 -4
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.spec.ts +0 -141
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-angular-card.ts +0 -44
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.spec.ts +0 -142
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-sap-card.ts +0 -52
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.spec.ts +0 -107
- package/projects/ngx/declarative-ui/dashboard/card/utils/mount-wc-card.ts +0 -22
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.html +0 -134
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.scss +0 -88
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.spec.ts +0 -354
- package/projects/ngx/declarative-ui/dashboard/dashboard/dashboard.component.ts +0 -238
- package/projects/ngx/declarative-ui/dashboard/dashboard/index.ts +0 -1
- package/projects/ngx/declarative-ui/dashboard/index.ts +0 -5
- package/projects/ngx/declarative-ui/dashboard/models/constants.ts +0 -2
- package/projects/ngx/declarative-ui/dashboard/models/dashboard.model.ts +0 -50
- package/projects/ngx/declarative-ui/dashboard/models/index.ts +0 -1
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.html +0 -28
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.scss +0 -85
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.spec.ts +0 -104
- package/projects/ngx/declarative-ui/dashboard/section/dashboard-section.component.ts +0 -23
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.html +0 -62
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.scss +0 -12
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.spec.ts +0 -301
- package/projects/ngx/declarative-ui/form/declarative-form/declarative-form.component.ts +0 -166
- package/projects/ngx/declarative-ui/form/declarative-form/index.ts +0 -1
- package/projects/ngx/declarative-ui/form/index.ts +0 -2
- package/projects/ngx/declarative-ui/form/models/form-field-definition.ts +0 -15
- package/projects/ngx/declarative-ui/form/models/index.ts +0 -1
- package/projects/ngx/declarative-ui/form/utils/set-property-by-path.ts +0 -30
- package/projects/ngx/declarative-ui/models/index.ts +0 -2
- package/projects/ngx/declarative-ui/models/resource.ts +0 -5
- package/projects/ngx/declarative-ui/models/ui-definition.ts +0 -95
- package/projects/ngx/declarative-ui/public-api.ts +0 -4
- package/projects/ngx/declarative-ui/stories/add-card-dialog.stories.ts +0 -91
- package/projects/ngx/declarative-ui/stories/background-lightblue.png +0 -0
- package/projects/ngx/declarative-ui/stories/dashboard.cards.ts +0 -107
- package/projects/ngx/declarative-ui/stories/dashboard.stories.ts +0 -296
- package/projects/ngx/declarative-ui/stories/declarative-form.stories.ts +0 -149
- package/projects/ngx/declarative-ui/stories/declarative-table-card.stories.ts +0 -358
- package/projects/ngx/declarative-ui/stories/declarative-table.stories.ts +0 -363
- package/projects/ngx/declarative-ui/stories/pods-table.config.ts +0 -188
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.html +0 -138
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.scss +0 -21
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.spec.ts +0 -345
- package/projects/ngx/declarative-ui/table/declarative-table/declarative-table.component.ts +0 -61
- package/projects/ngx/declarative-ui/table/declarative-table/index.ts +0 -1
- package/projects/ngx/declarative-ui/table/index.ts +0 -2
- package/projects/ngx/declarative-ui/table/models/index.ts +0 -14
- package/projects/ngx/declarative-ui/table/models/table.model.ts +0 -17
- package/projects/ngx/declarative-ui/table/utils/cssRules.engine.spec.ts +0 -146
- package/projects/ngx/declarative-ui/table/utils/cssRules.engine.ts +0 -69
- package/projects/ngx/declarative-ui/table/utils/field-definition.utils.spec.ts +0 -70
- package/projects/ngx/declarative-ui/table/utils/field-definition.utils.ts +0 -13
- package/projects/ngx/declarative-ui/table/utils/proccess-fields.spec.ts +0 -511
- package/projects/ngx/declarative-ui/table/utils/proccess-fields.ts +0 -71
- package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.spec.ts +0 -372
- package/projects/ngx/declarative-ui/table/utils/resource-field-by-path.ts +0 -98
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-cell.constants.ts +0 -5
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.html +0 -1
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.scss +0 -0
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.spec.ts +0 -119
- package/projects/ngx/declarative-ui/table/value-cell/boolean-value/boolean-value.component.ts +0 -35
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.html +0 -7
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.scss +0 -0
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.spec.ts +0 -114
- package/projects/ngx/declarative-ui/table/value-cell/link-value/link-value.component.ts +0 -19
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.html +0 -7
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.scss +0 -10
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.spec.ts +0 -188
- package/projects/ngx/declarative-ui/table/value-cell/secret-value/secret-value.component.ts +0 -16
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.html +0 -59
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.scss +0 -33
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.spec.ts +0 -316
- package/projects/ngx/declarative-ui/table/value-cell/value-cell.component.ts +0 -115
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.html +0 -156
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.scss +0 -123
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.spec.ts +0 -786
- package/projects/ngx/declarative-ui/table-card/declarative-table-card.component.ts +0 -286
- package/projects/ngx/declarative-ui/table-card/index.ts +0 -2
- package/projects/ngx/declarative-ui/table-card/models/configs.ts +0 -46
- package/projects/ngx/declarative-ui/tsconfig.lib.json +0 -11
- package/projects/ngx/declarative-ui/tsconfig.lib.prod.json +0 -9
- package/projects/ngx/declarative-ui/tsconfig.spec.json +0 -9
- package/projects/ngx/ng-package.json +0 -8
- package/projects/ngx/package.json +0 -22
- package/projects/ngx/public-api.ts +0 -2
- package/projects/ngx/tsconfig.lib.json +0 -11
- package/projects/ngx/tsconfig.lib.prod.json +0 -9
- package/projects/webcomponents/main.ts +0 -92
- package/projects/webcomponents/tsconfig.app.json +0 -9
- package/projects/webcomponents-dashboard/main.ts +0 -15
- package/projects/webcomponents-dashboard/tsconfig.app.json +0 -9
- package/renovate.json +0 -6
- package/scripts/bundle-wc.mjs +0 -79
- package/tsconfig.json +0 -37
- package/tsconfig.spec.json +0 -8
- package/tsconfig.storybook.json +0 -16
- package/vitest.config.ts +0 -26
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { FieldDefinition } from '../../models';
|
|
2
|
-
import { getFieldValue } from './field-definition.utils';
|
|
3
|
-
|
|
4
|
-
describe('field-definition.utils', () => {
|
|
5
|
-
describe('getFieldValue', () => {
|
|
6
|
-
it('returns resource property value when resource is provided', () => {
|
|
7
|
-
const field: FieldDefinition = { property: 'name' };
|
|
8
|
-
expect(getFieldValue(field, { name: 'Alice' })).toBe('Alice');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('returns nested property via jsonpath dot notation', () => {
|
|
12
|
-
const field: FieldDefinition = { property: 'metadata.name' };
|
|
13
|
-
expect(getFieldValue(field, { metadata: { name: 'test' } })).toBe('test');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('returns empty string when property resolves to empty string', () => {
|
|
17
|
-
const field: FieldDefinition = {
|
|
18
|
-
property: 'metadata.name',
|
|
19
|
-
value: 'fallback',
|
|
20
|
-
};
|
|
21
|
-
expect(getFieldValue(field, { metadata: { name: '' } })).toBe('');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('returns falsy value (false) over field.value fallback', () => {
|
|
25
|
-
const field: FieldDefinition = {
|
|
26
|
-
property: 'spec.enabled',
|
|
27
|
-
value: 'default',
|
|
28
|
-
};
|
|
29
|
-
expect(getFieldValue(field, { spec: { enabled: false } })).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('falls back to field.value when resource property is undefined', () => {
|
|
33
|
-
const field: FieldDefinition = { property: 'missing', value: 'fallback' };
|
|
34
|
-
expect(getFieldValue(field, {})).toBe('fallback');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('returns field.value when resource is undefined', () => {
|
|
38
|
-
const field: FieldDefinition = { property: 'name', value: 'static' };
|
|
39
|
-
expect(getFieldValue(field, undefined)).toBe('static');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('returns undefined when field.value is undefined and resource is undefined', () => {
|
|
43
|
-
const field: FieldDefinition = { property: 'name' };
|
|
44
|
-
expect(getFieldValue(field, undefined)).toBeUndefined();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('returns empty string field.value when resource is undefined', () => {
|
|
48
|
-
const field: FieldDefinition = { property: 'name', value: '' };
|
|
49
|
-
expect(getFieldValue(field, undefined)).toBe('');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('returns complex object as field.value', () => {
|
|
53
|
-
const complexValue = { nested: { data: 'value' } };
|
|
54
|
-
const field: FieldDefinition = {
|
|
55
|
-
property: 'spec.config',
|
|
56
|
-
value: complexValue as unknown as string,
|
|
57
|
-
};
|
|
58
|
-
expect(getFieldValue(field, undefined)).toEqual(complexValue);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('returns array as field.value', () => {
|
|
62
|
-
const arrayValue = ['item1', 'item2'];
|
|
63
|
-
const field: FieldDefinition = {
|
|
64
|
-
property: 'spec.items',
|
|
65
|
-
value: arrayValue as unknown as string,
|
|
66
|
-
};
|
|
67
|
-
expect(getFieldValue(field, undefined)).toEqual(arrayValue);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { FieldDefinition } from '../../models';
|
|
2
|
-
import { getResourceValueByJsonPath } from './resource-field-by-path';
|
|
3
|
-
|
|
4
|
-
export function getFieldValue<T>(
|
|
5
|
-
field: FieldDefinition,
|
|
6
|
-
resource: T | undefined,
|
|
7
|
-
) {
|
|
8
|
-
if (resource) {
|
|
9
|
-
return getResourceValueByJsonPath<T>(resource, field) ?? field.value;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return field.value;
|
|
13
|
-
}
|
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
import { processGroupFields } from './proccess-fields';
|
|
2
|
-
import { TableFieldDefinition } from '../models';
|
|
3
|
-
|
|
4
|
-
describe('proccess-fields', () => {
|
|
5
|
-
describe('processFields', () => {
|
|
6
|
-
it('should return empty array when input is empty', () => {
|
|
7
|
-
const result = processGroupFields([]);
|
|
8
|
-
expect(result).toEqual([]);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should return fields without groups unchanged', () => {
|
|
12
|
-
const fields: TableFieldDefinition[] = [
|
|
13
|
-
{
|
|
14
|
-
property: 'name',
|
|
15
|
-
label: 'Name',
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
property: 'age',
|
|
19
|
-
label: 'Age',
|
|
20
|
-
},
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const result = processGroupFields(fields);
|
|
24
|
-
expect(result).toEqual(fields);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should combine fields with the same group name', () => {
|
|
28
|
-
const fields: TableFieldDefinition[] = [
|
|
29
|
-
{
|
|
30
|
-
property: 'firstName',
|
|
31
|
-
label: 'First Name',
|
|
32
|
-
group: {
|
|
33
|
-
name: 'personalInfo',
|
|
34
|
-
label: 'Personal Information',
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
property: 'lastName',
|
|
39
|
-
label: 'Last Name',
|
|
40
|
-
group: {
|
|
41
|
-
name: 'personalInfo',
|
|
42
|
-
label: 'Personal Information',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
property: 'email',
|
|
47
|
-
label: 'Email',
|
|
48
|
-
group: {
|
|
49
|
-
name: 'personalInfo',
|
|
50
|
-
label: 'Personal Information',
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
const result = processGroupFields(fields);
|
|
56
|
-
|
|
57
|
-
expect(result).toHaveLength(1);
|
|
58
|
-
expect(result[0]).toEqual({
|
|
59
|
-
property: 'firstName',
|
|
60
|
-
label: 'First Name',
|
|
61
|
-
group: {
|
|
62
|
-
name: 'personalInfo',
|
|
63
|
-
label: 'Personal Information',
|
|
64
|
-
fields: [
|
|
65
|
-
{ property: 'firstName', label: 'First Name' },
|
|
66
|
-
{ property: 'lastName', label: 'Last Name' },
|
|
67
|
-
{ property: 'email', label: 'Email' },
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should handle multiple different groups', () => {
|
|
74
|
-
const fields: TableFieldDefinition[] = [
|
|
75
|
-
{
|
|
76
|
-
property: 'firstName',
|
|
77
|
-
label: 'First Name',
|
|
78
|
-
group: {
|
|
79
|
-
name: 'personalInfo',
|
|
80
|
-
label: 'Personal Information',
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
property: 'lastName',
|
|
85
|
-
label: 'Last Name',
|
|
86
|
-
group: {
|
|
87
|
-
name: 'personalInfo',
|
|
88
|
-
label: 'Personal Information',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
property: 'street',
|
|
93
|
-
label: 'Street',
|
|
94
|
-
group: {
|
|
95
|
-
name: 'address',
|
|
96
|
-
label: 'Address',
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
property: 'city',
|
|
101
|
-
label: 'City',
|
|
102
|
-
group: {
|
|
103
|
-
name: 'address',
|
|
104
|
-
label: 'Address',
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
const result = processGroupFields(fields);
|
|
110
|
-
|
|
111
|
-
expect(result).toHaveLength(2);
|
|
112
|
-
|
|
113
|
-
const personalInfoField = result.find(
|
|
114
|
-
(f) => f.group?.name === 'personalInfo',
|
|
115
|
-
);
|
|
116
|
-
const addressField = result.find((f) => f.group?.name === 'address');
|
|
117
|
-
|
|
118
|
-
expect(personalInfoField).toEqual({
|
|
119
|
-
property: 'firstName',
|
|
120
|
-
label: 'First Name',
|
|
121
|
-
group: {
|
|
122
|
-
name: 'personalInfo',
|
|
123
|
-
label: 'Personal Information',
|
|
124
|
-
fields: [
|
|
125
|
-
{ property: 'firstName', label: 'First Name' },
|
|
126
|
-
{ property: 'lastName', label: 'Last Name' },
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
expect(addressField).toEqual({
|
|
132
|
-
property: 'street',
|
|
133
|
-
label: 'Street',
|
|
134
|
-
group: {
|
|
135
|
-
name: 'address',
|
|
136
|
-
label: 'Address',
|
|
137
|
-
fields: [
|
|
138
|
-
{ property: 'street', label: 'Street' },
|
|
139
|
-
{ property: 'city', label: 'City' },
|
|
140
|
-
],
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should handle mixed fields with and without groups', () => {
|
|
146
|
-
const fields: TableFieldDefinition[] = [
|
|
147
|
-
{
|
|
148
|
-
property: 'id',
|
|
149
|
-
label: 'ID',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
property: 'firstName',
|
|
153
|
-
label: 'First Name',
|
|
154
|
-
group: {
|
|
155
|
-
name: 'personalInfo',
|
|
156
|
-
label: 'Personal Information',
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
property: 'lastName',
|
|
161
|
-
label: 'Last Name',
|
|
162
|
-
group: {
|
|
163
|
-
name: 'personalInfo',
|
|
164
|
-
label: 'Personal Information',
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
property: 'status',
|
|
169
|
-
label: 'Status',
|
|
170
|
-
},
|
|
171
|
-
];
|
|
172
|
-
|
|
173
|
-
const result = processGroupFields(fields);
|
|
174
|
-
|
|
175
|
-
expect(result).toHaveLength(3);
|
|
176
|
-
|
|
177
|
-
const idField = result.find((f) => f.property === 'id');
|
|
178
|
-
const statusField = result.find((f) => f.property === 'status');
|
|
179
|
-
const personalInfoField = result.find(
|
|
180
|
-
(f) => f.group?.name === 'personalInfo',
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
expect(idField).toEqual({
|
|
184
|
-
property: 'id',
|
|
185
|
-
label: 'ID',
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
expect(statusField).toEqual({
|
|
189
|
-
property: 'status',
|
|
190
|
-
label: 'Status',
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
expect(personalInfoField).toEqual({
|
|
194
|
-
property: 'firstName',
|
|
195
|
-
label: 'First Name',
|
|
196
|
-
group: {
|
|
197
|
-
name: 'personalInfo',
|
|
198
|
-
label: 'Personal Information',
|
|
199
|
-
fields: [
|
|
200
|
-
{ property: 'firstName', label: 'First Name' },
|
|
201
|
-
{ property: 'lastName', label: 'Last Name' },
|
|
202
|
-
],
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('should use jsonPathExpression when available instead of property', () => {
|
|
208
|
-
const fields: TableFieldDefinition[] = [
|
|
209
|
-
{
|
|
210
|
-
property: 'firstName',
|
|
211
|
-
label: 'First Name',
|
|
212
|
-
jsonPathExpression: 'user.personal.firstName',
|
|
213
|
-
group: {
|
|
214
|
-
name: 'personalInfo',
|
|
215
|
-
label: 'Personal Information',
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
property: 'lastName',
|
|
220
|
-
label: 'Last Name',
|
|
221
|
-
jsonPathExpression: 'user.personal.lastName',
|
|
222
|
-
group: {
|
|
223
|
-
name: 'personalInfo',
|
|
224
|
-
label: 'Personal Information',
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
property: 'email',
|
|
229
|
-
label: 'Email',
|
|
230
|
-
group: {
|
|
231
|
-
name: 'personalInfo',
|
|
232
|
-
label: 'Personal Information',
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
];
|
|
236
|
-
|
|
237
|
-
const result = processGroupFields(fields);
|
|
238
|
-
|
|
239
|
-
expect(result).toHaveLength(1);
|
|
240
|
-
expect(result[0].group?.fields).toEqual([
|
|
241
|
-
{
|
|
242
|
-
property: 'firstName',
|
|
243
|
-
label: 'First Name',
|
|
244
|
-
jsonPathExpression: 'user.personal.firstName',
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
property: 'lastName',
|
|
248
|
-
label: 'Last Name',
|
|
249
|
-
jsonPathExpression: 'user.personal.lastName',
|
|
250
|
-
},
|
|
251
|
-
{ property: 'email', label: 'Email' },
|
|
252
|
-
]);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should handle array properties', () => {
|
|
256
|
-
const fields: TableFieldDefinition[] = [
|
|
257
|
-
{
|
|
258
|
-
property: ['firstName', 'first_name'],
|
|
259
|
-
label: 'First Name',
|
|
260
|
-
group: {
|
|
261
|
-
name: 'personalInfo',
|
|
262
|
-
label: 'Personal Information',
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
property: ['lastName', 'last_name'],
|
|
267
|
-
label: 'Last Name',
|
|
268
|
-
group: {
|
|
269
|
-
name: 'personalInfo',
|
|
270
|
-
label: 'Personal Information',
|
|
271
|
-
},
|
|
272
|
-
},
|
|
273
|
-
];
|
|
274
|
-
|
|
275
|
-
const result = processGroupFields(fields);
|
|
276
|
-
|
|
277
|
-
expect(result).toHaveLength(1);
|
|
278
|
-
expect(result[0].group?.fields).toEqual([
|
|
279
|
-
{ property: ['firstName', 'first_name'], label: 'First Name' },
|
|
280
|
-
{ property: ['lastName', 'last_name'], label: 'Last Name' },
|
|
281
|
-
]);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('should handle fields with group but no name', () => {
|
|
285
|
-
const fields: TableFieldDefinition[] = [
|
|
286
|
-
{
|
|
287
|
-
property: 'firstName',
|
|
288
|
-
label: 'First Name',
|
|
289
|
-
group: {
|
|
290
|
-
name: '',
|
|
291
|
-
label: 'Personal Information',
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
property: 'lastName',
|
|
296
|
-
label: 'Last Name',
|
|
297
|
-
group: {
|
|
298
|
-
name: 'personalInfo',
|
|
299
|
-
label: 'Personal Information',
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
];
|
|
303
|
-
|
|
304
|
-
const result = processGroupFields(fields);
|
|
305
|
-
|
|
306
|
-
expect(result).toHaveLength(2);
|
|
307
|
-
expect(result[0]).toEqual({
|
|
308
|
-
property: 'firstName',
|
|
309
|
-
label: 'First Name',
|
|
310
|
-
group: {
|
|
311
|
-
name: '',
|
|
312
|
-
label: 'Personal Information',
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
expect(result[1]).toEqual({
|
|
316
|
-
property: 'lastName',
|
|
317
|
-
label: 'Last Name',
|
|
318
|
-
group: {
|
|
319
|
-
name: 'personalInfo',
|
|
320
|
-
label: 'Personal Information',
|
|
321
|
-
fields: [{ property: 'lastName', label: 'Last Name' }],
|
|
322
|
-
},
|
|
323
|
-
});
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it('should handle fields with undefined group', () => {
|
|
327
|
-
const fields: TableFieldDefinition[] = [
|
|
328
|
-
{
|
|
329
|
-
property: 'firstName',
|
|
330
|
-
label: 'First Name',
|
|
331
|
-
group: undefined,
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
property: 'lastName',
|
|
335
|
-
label: 'Last Name',
|
|
336
|
-
group: {
|
|
337
|
-
name: 'personalInfo',
|
|
338
|
-
label: 'Personal Information',
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
];
|
|
342
|
-
|
|
343
|
-
const result = processGroupFields(fields);
|
|
344
|
-
|
|
345
|
-
expect(result).toHaveLength(2);
|
|
346
|
-
expect(result[0]).toEqual({
|
|
347
|
-
property: 'firstName',
|
|
348
|
-
label: 'First Name',
|
|
349
|
-
group: undefined,
|
|
350
|
-
});
|
|
351
|
-
expect(result[1]).toEqual({
|
|
352
|
-
property: 'lastName',
|
|
353
|
-
label: 'Last Name',
|
|
354
|
-
group: {
|
|
355
|
-
name: 'personalInfo',
|
|
356
|
-
label: 'Personal Information',
|
|
357
|
-
fields: [{ property: 'lastName', label: 'Last Name' }],
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it('should preserve all original field properties in the result', () => {
|
|
363
|
-
const fields = [
|
|
364
|
-
{
|
|
365
|
-
property: 'firstName',
|
|
366
|
-
label: 'First Name',
|
|
367
|
-
required: true,
|
|
368
|
-
values: ['John', 'Jane'],
|
|
369
|
-
group: {
|
|
370
|
-
name: 'personalInfo',
|
|
371
|
-
label: 'Personal Information',
|
|
372
|
-
delimiter: ' | ',
|
|
373
|
-
},
|
|
374
|
-
dynamicValuesDefinition: {
|
|
375
|
-
operation: 'query',
|
|
376
|
-
gqlQuery: 'query { users { name } }',
|
|
377
|
-
value: 'name',
|
|
378
|
-
key: 'id',
|
|
379
|
-
},
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
property: 'lastName',
|
|
383
|
-
label: 'Last Name',
|
|
384
|
-
required: false,
|
|
385
|
-
group: {
|
|
386
|
-
name: 'personalInfo',
|
|
387
|
-
label: 'Personal Information',
|
|
388
|
-
delimiter: ' | ',
|
|
389
|
-
},
|
|
390
|
-
},
|
|
391
|
-
] as unknown as TableFieldDefinition[];
|
|
392
|
-
|
|
393
|
-
const result = processGroupFields(fields);
|
|
394
|
-
|
|
395
|
-
expect(result).toHaveLength(1);
|
|
396
|
-
expect(result[0]).toEqual({
|
|
397
|
-
property: 'firstName',
|
|
398
|
-
label: 'First Name',
|
|
399
|
-
required: true,
|
|
400
|
-
values: ['John', 'Jane'],
|
|
401
|
-
group: {
|
|
402
|
-
name: 'personalInfo',
|
|
403
|
-
label: 'Personal Information',
|
|
404
|
-
delimiter: ' | ',
|
|
405
|
-
fields: [
|
|
406
|
-
{
|
|
407
|
-
property: 'firstName',
|
|
408
|
-
label: 'First Name',
|
|
409
|
-
required: true,
|
|
410
|
-
values: ['John', 'Jane'],
|
|
411
|
-
dynamicValuesDefinition: {
|
|
412
|
-
operation: 'query',
|
|
413
|
-
gqlQuery: 'query { users { name } }',
|
|
414
|
-
value: 'name',
|
|
415
|
-
key: 'id',
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
property: 'lastName',
|
|
420
|
-
label: 'Last Name',
|
|
421
|
-
required: false,
|
|
422
|
-
},
|
|
423
|
-
],
|
|
424
|
-
},
|
|
425
|
-
dynamicValuesDefinition: {
|
|
426
|
-
operation: 'query',
|
|
427
|
-
gqlQuery: 'query { users { name } }',
|
|
428
|
-
value: 'name',
|
|
429
|
-
key: 'id',
|
|
430
|
-
},
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
it('should handle complex nested group scenarios', () => {
|
|
435
|
-
const fields: TableFieldDefinition[] = [
|
|
436
|
-
{
|
|
437
|
-
property: 'id',
|
|
438
|
-
label: 'ID',
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
property: 'firstName',
|
|
442
|
-
label: 'First Name',
|
|
443
|
-
group: {
|
|
444
|
-
name: 'personalInfo',
|
|
445
|
-
label: 'Personal Information',
|
|
446
|
-
},
|
|
447
|
-
},
|
|
448
|
-
{
|
|
449
|
-
property: 'lastName',
|
|
450
|
-
label: 'Last Name',
|
|
451
|
-
group: {
|
|
452
|
-
name: 'personalInfo',
|
|
453
|
-
label: 'Personal Information',
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
property: 'street',
|
|
458
|
-
label: 'Street',
|
|
459
|
-
group: {
|
|
460
|
-
name: 'address',
|
|
461
|
-
label: 'Address',
|
|
462
|
-
},
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
property: 'city',
|
|
466
|
-
label: 'City',
|
|
467
|
-
group: {
|
|
468
|
-
name: 'address',
|
|
469
|
-
label: 'Address',
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
property: 'country',
|
|
474
|
-
label: 'Country',
|
|
475
|
-
group: {
|
|
476
|
-
name: 'address',
|
|
477
|
-
label: 'Address',
|
|
478
|
-
},
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
property: 'status',
|
|
482
|
-
label: 'Status',
|
|
483
|
-
},
|
|
484
|
-
];
|
|
485
|
-
|
|
486
|
-
const result = processGroupFields(fields);
|
|
487
|
-
|
|
488
|
-
expect(result).toHaveLength(4);
|
|
489
|
-
|
|
490
|
-
const idField = result.find((f) => f.property === 'id');
|
|
491
|
-
const statusField = result.find((f) => f.property === 'status');
|
|
492
|
-
const personalInfoField = result.find(
|
|
493
|
-
(f) => f.group?.name === 'personalInfo',
|
|
494
|
-
);
|
|
495
|
-
const addressField = result.find((f) => f.group?.name === 'address');
|
|
496
|
-
|
|
497
|
-
expect(idField?.property).toBe('id');
|
|
498
|
-
expect(statusField?.property).toBe('status');
|
|
499
|
-
|
|
500
|
-
expect(personalInfoField?.group?.fields).toEqual([
|
|
501
|
-
{ property: 'firstName', label: 'First Name' },
|
|
502
|
-
{ property: 'lastName', label: 'Last Name' },
|
|
503
|
-
]);
|
|
504
|
-
expect(addressField?.group?.fields).toEqual([
|
|
505
|
-
{ property: 'street', label: 'Street' },
|
|
506
|
-
{ property: 'city', label: 'City' },
|
|
507
|
-
{ property: 'country', label: 'Country' },
|
|
508
|
-
]);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
});
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { TableFieldDefinition } from '../models';
|
|
2
|
-
|
|
3
|
-
type GroupBase = NonNullable<TableFieldDefinition['group']>;
|
|
4
|
-
type ProcessedGroup = GroupBase & {
|
|
5
|
-
fields?: TableFieldDefinition[];
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export type ProcessedTableFieldDefinition = Omit<TableFieldDefinition, 'group'> & {
|
|
9
|
-
group?: ProcessedGroup;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const processGroupFields = (
|
|
13
|
-
fields: TableFieldDefinition[],
|
|
14
|
-
): ProcessedTableFieldDefinition[] => {
|
|
15
|
-
return combineGroupFields(fields);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const collectGroupFields = (
|
|
19
|
-
fields: TableFieldDefinition[],
|
|
20
|
-
): Record<string, TableFieldDefinition[]> => {
|
|
21
|
-
return fields.reduce(
|
|
22
|
-
(acc, f): Record<string, TableFieldDefinition[]> => {
|
|
23
|
-
if (!f.group?.name) {
|
|
24
|
-
return acc;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const key = f.group.name;
|
|
28
|
-
if (!acc[key]) {
|
|
29
|
-
acc[key] = [];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Strip group information from the field when adding to the fields array
|
|
33
|
-
const { group, ...fieldWithoutGroup } = f;
|
|
34
|
-
acc[key].push(fieldWithoutGroup);
|
|
35
|
-
return acc;
|
|
36
|
-
},
|
|
37
|
-
{} as Record<string, TableFieldDefinition[]>,
|
|
38
|
-
);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const combineGroupFields = (fields: TableFieldDefinition[]): ProcessedTableFieldDefinition[] => {
|
|
42
|
-
const seenGroup = new Set<string>();
|
|
43
|
-
const groupFields = collectGroupFields(fields);
|
|
44
|
-
const result: ProcessedTableFieldDefinition[] = [];
|
|
45
|
-
|
|
46
|
-
fields.forEach((f) => {
|
|
47
|
-
if (!f.group?.name) {
|
|
48
|
-
result.push(f);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const key = f.group.name;
|
|
53
|
-
if (seenGroup.has(key)) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
seenGroup.add(key);
|
|
58
|
-
|
|
59
|
-
const grouped: ProcessedTableFieldDefinition = {
|
|
60
|
-
...f,
|
|
61
|
-
group: {
|
|
62
|
-
...f.group,
|
|
63
|
-
fields: groupFields[key],
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
result.push(grouped);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return result;
|
|
71
|
-
};
|