@genesislcap/pbc-reporting-ui 14.396.3 → 14.397.0
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/dts/new/main/edit-config/col-filters/col-filters-grid.helpers.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/datasource-config/datasource-config-item.d.ts +6 -2
- package/dist/dts/new/main/edit-config/datasource-config/datasource-config-item.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/datasource-config/datasource-config-item.styles.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/datasource-config/datasource-config-item.template.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/datasource-config/datasources-config-container.helpers.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/datasource-config/datasources-config-container.template.d.ts.map +1 -1
- package/dist/dts/new/main/edit-config/shared/datasource-data-base-component.helpers.ts.d.ts.map +1 -1
- package/dist/dts/new/store/slices/datasources-config.d.ts +20 -6
- package/dist/dts/new/store/slices/datasources-config.d.ts.map +1 -1
- package/dist/dts/new/store/slices/types.d.ts +19 -2
- package/dist/dts/new/store/slices/types.d.ts.map +1 -1
- package/dist/dts/new/store/store.d.ts +133 -35
- package/dist/dts/new/store/store.d.ts.map +1 -1
- package/dist/dts/new/types/misc.d.ts +4 -2
- package/dist/dts/new/types/misc.d.ts.map +1 -1
- package/dist/dts/new/utils/alias-generator.d.ts +8 -0
- package/dist/dts/new/utils/alias-generator.d.ts.map +1 -0
- package/dist/dts/new/utils/alias-generator.test.d.ts +2 -0
- package/dist/dts/new/utils/alias-generator.test.d.ts.map +1 -0
- package/dist/dts/new/utils/index.d.ts +1 -0
- package/dist/dts/new/utils/index.d.ts.map +1 -1
- package/dist/dts/new/utils/tooltip.d.ts +3 -0
- package/dist/dts/new/utils/tooltip.d.ts.map +1 -1
- package/dist/dts/new/utils/transformers.d.ts +1 -1
- package/dist/dts/new/utils/transformers.d.ts.map +1 -1
- package/dist/esm/new/main/edit-config/col-filters/col-filters-grid.helpers.js +3 -1
- package/dist/esm/new/main/edit-config/col-filters/col-filters-grid.helpers.test.js +71 -6
- package/dist/esm/new/main/edit-config/col-rename-alias/col-rename-alias-grid.helpers.test.js +32 -4
- package/dist/esm/new/main/edit-config/data-transforms-derived-fields/data-transforms.helpers.test.js +10 -2
- package/dist/esm/new/main/edit-config/datasource-config/datasource-config-item.js +100 -10
- package/dist/esm/new/main/edit-config/datasource-config/datasource-config-item.styles.js +6 -0
- package/dist/esm/new/main/edit-config/datasource-config/datasource-config-item.template.js +38 -3
- package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.helpers.js +11 -7
- package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.helpers.test.js +29 -22
- package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.template.js +3 -0
- package/dist/esm/new/main/edit-config/shared/datasource-data-base-component.helpers.ts.js +16 -8
- package/dist/esm/new/main/edit-config/shared/datasource-data-base-component.test.js +13 -2
- package/dist/esm/new/main/edit-config/tabbed-datasource-container/tabbed-datasource-container.template.js +1 -1
- package/dist/esm/new/store/slices/datasources-config.js +50 -11
- package/dist/esm/new/store/slices/types.js +1 -0
- package/dist/esm/new/utils/alias-generator.js +16 -0
- package/dist/esm/new/utils/alias-generator.test.js +36 -0
- package/dist/esm/new/utils/index.js +1 -0
- package/dist/esm/new/utils/tooltip.js +16 -0
- package/dist/esm/new/utils/transformers.js +20 -6
- package/dist/esm/new/utils/transformers.test.js +61 -11
- package/dist/esm/new/utils/validators.test.js +35 -21
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/new/main/edit-config/col-filters/col-filters-grid.helpers.test.ts +76 -6
- package/src/new/main/edit-config/col-filters/col-filters-grid.helpers.ts +4 -1
- package/src/new/main/edit-config/col-rename-alias/col-rename-alias-grid.helpers.test.ts +32 -4
- package/src/new/main/edit-config/data-transforms-derived-fields/data-transforms.helpers.test.ts +10 -2
- package/src/new/main/edit-config/datasource-config/datasource-config-item.styles.ts +6 -0
- package/src/new/main/edit-config/datasource-config/datasource-config-item.template.ts +62 -3
- package/src/new/main/edit-config/datasource-config/datasource-config-item.ts +107 -8
- package/src/new/main/edit-config/datasource-config/datasources-config-container.helpers.test.ts +32 -23
- package/src/new/main/edit-config/datasource-config/datasources-config-container.helpers.ts +18 -10
- package/src/new/main/edit-config/datasource-config/datasources-config-container.template.ts +6 -0
- package/src/new/main/edit-config/shared/datasource-data-base-component.helpers.ts.ts +21 -11
- package/src/new/main/edit-config/shared/datasource-data-base-component.test.ts +14 -2
- package/src/new/main/edit-config/tabbed-datasource-container/tabbed-datasource-container.template.ts +1 -1
- package/src/new/store/slices/datasources-config.ts +71 -16
- package/src/new/store/slices/types.ts +22 -4
- package/src/new/types/misc.ts +9 -2
- package/src/new/utils/alias-generator.test.ts +44 -0
- package/src/new/utils/alias-generator.ts +18 -0
- package/src/new/utils/index.ts +1 -0
- package/src/new/utils/tooltip.ts +19 -0
- package/src/new/utils/transformers.test.ts +73 -11
- package/src/new/utils/transformers.ts +30 -6
- package/src/new/utils/validators.test.ts +35 -21
package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.helpers.js
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { logger } from '@genesislcap/foundation-comms';
|
|
3
3
|
import { actions, selectors } from '../../../store';
|
|
4
|
-
import { buildDatasourceName } from '../../../utils';
|
|
4
|
+
import { buildDatasourceName, generateUniqueAlias } from '../../../utils';
|
|
5
5
|
import { setDefaultFormatsForDatasource } from '../data-transforms-derived-fields/data-transforms.helpers';
|
|
6
6
|
export const createNewDatasourceConfig = (getSchema) => (choices) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7
7
|
var _a;
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const allDatasources = selectors.datasourceConfig.getAllConfigSet();
|
|
9
|
+
const validDatasources = (_a = choices.filter((ds) => !(buildDatasourceName(ds.name, ds.name, ds.inputType) in allDatasources))) !== null && _a !== void 0 ? _a : [];
|
|
10
10
|
if ((validDatasources === null || validDatasources === void 0 ? void 0 : validDatasources.length) < 1) {
|
|
11
11
|
logger.error('No datasources available to create new config from');
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const baseConfig = selectors.baseConfig.getConfig();
|
|
15
|
-
if (Object.keys(
|
|
15
|
+
if (Object.keys(allDatasources).length > 0 &&
|
|
16
16
|
baseConfig.OUTPUT_FORMAT === 'CSV' &&
|
|
17
17
|
!baseConfig.DOCUMENT_TEMPLATE_ID) {
|
|
18
18
|
logger.error('Cannot add multiple datasources when using csv file without a template');
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
const { KEY, INPUT_TYPE, schema } = yield findFirstValidDatasource(getSchema)(validDatasources);
|
|
22
|
-
|
|
21
|
+
const { KEY: RESOURCE_NAME, INPUT_TYPE, schema, } = yield findFirstValidDatasource(getSchema)(validDatasources);
|
|
22
|
+
// Check for duplicate aliases
|
|
23
|
+
const existingAliases = new Set(Object.values(allDatasources).map((ds) => ds.KEY));
|
|
24
|
+
const uniqueAlias = generateUniqueAlias(RESOURCE_NAME, existingAliases);
|
|
25
|
+
const datasourceName = buildDatasourceName(uniqueAlias, RESOURCE_NAME, INPUT_TYPE);
|
|
23
26
|
actions.datasourceConfig.initDatasourceConfiguration({
|
|
24
27
|
base: {
|
|
25
|
-
KEY,
|
|
28
|
+
KEY: uniqueAlias,
|
|
29
|
+
NAME: RESOURCE_NAME,
|
|
26
30
|
INPUT_TYPE,
|
|
27
31
|
},
|
|
28
32
|
fields: Object.keys(schema.properties), // Properties is valid as we check in findFirstValidDatasource
|
package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.helpers.test.js
CHANGED
|
@@ -154,14 +154,16 @@ CreateNewDatasourceConfig.before.each(() => {
|
|
|
154
154
|
sinon.restore();
|
|
155
155
|
});
|
|
156
156
|
CreateNewDatasourceConfig('should exit when no valid datasources are available', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
|
-
const mockChoices = [{ name: '
|
|
157
|
+
const mockChoices = [{ name: 'testSource', inputType: 'REQ_REP' }];
|
|
158
158
|
const getAllConfigSetStub = sinon.stub(selectors.datasourceConfig, 'getAllConfigSet').returns({
|
|
159
|
-
|
|
160
|
-
KEY: '
|
|
161
|
-
NAME: '
|
|
159
|
+
REQ_REP_testSource_testSource: {
|
|
160
|
+
KEY: 'testSource',
|
|
161
|
+
NAME: 'testSource',
|
|
162
162
|
INPUT_TYPE: 'REQ_REP',
|
|
163
163
|
OUTPUT_TYPE: 'TABLE',
|
|
164
164
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: [] },
|
|
165
|
+
GROUPING_STRATEGY: 'NONE',
|
|
166
|
+
GROUP_KEY: null,
|
|
165
167
|
},
|
|
166
168
|
});
|
|
167
169
|
const loggerStub = sinon.stub(logger, 'error');
|
|
@@ -172,14 +174,16 @@ CreateNewDatasourceConfig('should exit when no valid datasources are available',
|
|
|
172
174
|
assert.ok(!getSchemaStub.called);
|
|
173
175
|
}));
|
|
174
176
|
CreateNewDatasourceConfig('should exit when trying to add multiple datasources with CSV format', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
175
|
-
const mockChoices = [{ name: '
|
|
177
|
+
const mockChoices = [{ name: 'testSource', inputType: 'REQ_REP' }];
|
|
176
178
|
const getAllConfigSetStub = sinon.stub(selectors.datasourceConfig, 'getAllConfigSet').returns({
|
|
177
|
-
|
|
178
|
-
KEY: '
|
|
179
|
-
NAME: '
|
|
179
|
+
REQ_REP_existingSource_existingAlias: {
|
|
180
|
+
KEY: 'existingAlias',
|
|
181
|
+
NAME: 'existingSource',
|
|
180
182
|
INPUT_TYPE: 'REQ_REP',
|
|
181
183
|
OUTPUT_TYPE: 'TABLE',
|
|
182
184
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: [] },
|
|
185
|
+
GROUPING_STRATEGY: 'NONE',
|
|
186
|
+
GROUP_KEY: null,
|
|
183
187
|
},
|
|
184
188
|
});
|
|
185
189
|
const getConfigStub = sinon.stub(selectors.baseConfig, 'getConfig').returns({
|
|
@@ -190,7 +194,7 @@ CreateNewDatasourceConfig('should exit when trying to add multiple datasources w
|
|
|
190
194
|
const loggerStub = sinon.stub(logger, 'error');
|
|
191
195
|
const getSchemaStub = sinon.stub().resolves({});
|
|
192
196
|
yield createNewDatasourceConfig(getSchemaStub)(mockChoices);
|
|
193
|
-
assert.equal(getAllConfigSetStub.callCount,
|
|
197
|
+
assert.equal(getAllConfigSetStub.callCount, 1, 'getAllConfigSetStub should be called once');
|
|
194
198
|
assert.equal(getConfigStub.callCount, 1, 'getConfigStub should be called once');
|
|
195
199
|
// assert.ok(loggerStub.calledWith('Cannot add multiple datasources when using csv file without a template'));
|
|
196
200
|
if (loggerStub.args.length > 0) {
|
|
@@ -202,14 +206,16 @@ CreateNewDatasourceConfig('should exit when trying to add multiple datasources w
|
|
|
202
206
|
assert.equal(getSchemaStub.callCount, 0, 'getSchemaStub should not be called');
|
|
203
207
|
}));
|
|
204
208
|
CreateNewDatasourceConfig('should allow adding multiple datasources with CSV format IF template is selected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
205
|
-
const mockChoices = [{ name: '
|
|
209
|
+
const mockChoices = [{ name: 'testSource', inputType: 'REQ_REP' }];
|
|
206
210
|
const getAllConfigSetStub = sinon.stub(selectors.datasourceConfig, 'getAllConfigSet').returns({
|
|
207
|
-
|
|
208
|
-
KEY: '
|
|
209
|
-
NAME: '
|
|
211
|
+
REQ_REP_existingSource_existingAlias: {
|
|
212
|
+
KEY: 'existingAlias',
|
|
213
|
+
NAME: 'existingSource',
|
|
210
214
|
INPUT_TYPE: 'REQ_REP',
|
|
211
215
|
OUTPUT_TYPE: 'TABLE',
|
|
212
216
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: [] },
|
|
217
|
+
GROUPING_STRATEGY: 'NONE',
|
|
218
|
+
GROUP_KEY: null,
|
|
213
219
|
},
|
|
214
220
|
});
|
|
215
221
|
sinon.stub(selectors.baseConfig, 'getConfig').returns({
|
|
@@ -227,12 +233,12 @@ CreateNewDatasourceConfig('should allow adding multiple datasources with CSV for
|
|
|
227
233
|
const getSchemaStub = sinon.stub().resolves(mockSchema);
|
|
228
234
|
const initConfigStub = sinon.stub(actions.datasourceConfig, 'initDatasourceConfiguration');
|
|
229
235
|
yield createNewDatasourceConfig(getSchemaStub)(mockChoices);
|
|
230
|
-
assert.ok(getAllConfigSetStub.
|
|
236
|
+
assert.ok(getAllConfigSetStub.calledOnce);
|
|
231
237
|
assert.ok(getSchemaStub.calledOnce);
|
|
232
238
|
assert.ok(initConfigStub.called);
|
|
233
239
|
}));
|
|
234
240
|
CreateNewDatasourceConfig('should successfully create new datasource configuration', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
235
|
-
const mockChoices = [{ name: '
|
|
241
|
+
const mockChoices = [{ name: 'testSource', inputType: 'REQ_REP' }];
|
|
236
242
|
const getAllConfigSetStub = sinon.stub(selectors.datasourceConfig, 'getAllConfigSet').returns({});
|
|
237
243
|
sinon.stub(selectors.baseConfig, 'getConfig').returns({
|
|
238
244
|
DESTINATION_IDS: [],
|
|
@@ -248,14 +254,15 @@ CreateNewDatasourceConfig('should successfully create new datasource configurati
|
|
|
248
254
|
const getSchemaStub = sinon.stub().resolves(mockSchema);
|
|
249
255
|
const initConfigStub = sinon.stub(actions.datasourceConfig, 'initDatasourceConfiguration');
|
|
250
256
|
yield createNewDatasourceConfig(getSchemaStub)(mockChoices);
|
|
251
|
-
assert.ok(getAllConfigSetStub.
|
|
257
|
+
assert.ok(getAllConfigSetStub.calledOnce);
|
|
252
258
|
assert.ok(getSchemaStub.calledOnce);
|
|
253
|
-
assert.ok(initConfigStub.calledWith({
|
|
254
|
-
base: {
|
|
255
|
-
KEY: '
|
|
259
|
+
assert.ok(initConfigStub.calledWith(sinon.match({
|
|
260
|
+
base: sinon.match({
|
|
261
|
+
KEY: 'testSource',
|
|
262
|
+
NAME: 'testSource',
|
|
256
263
|
INPUT_TYPE: 'REQ_REP',
|
|
257
|
-
},
|
|
258
|
-
fields: ['field1', 'field2'],
|
|
259
|
-
}));
|
|
264
|
+
}),
|
|
265
|
+
fields: sinon.match.array.deepEquals(['field1', 'field2']),
|
|
266
|
+
})));
|
|
260
267
|
}));
|
|
261
268
|
CreateNewDatasourceConfig.run();
|
package/dist/esm/new/main/edit-config/datasource-config/datasources-config-container.template.js
CHANGED
|
@@ -27,6 +27,9 @@ const container = html `
|
|
|
27
27
|
</p>
|
|
28
28
|
<div>
|
|
29
29
|
${repeat((_) => Object.keys(selectors.datasourceConfig.getAllConfigSet()), html `
|
|
30
|
+
${when((_, ctx) => !ctx.isFirst, html `
|
|
31
|
+
<rapid-divider></rapid-divider>
|
|
32
|
+
`)}
|
|
30
33
|
<datasource-config-item
|
|
31
34
|
:datasourceName=${(x) => x}
|
|
32
35
|
:datasourceChoices=${(_, c) => c.parent.datasourceChoices}
|
|
@@ -77,9 +77,17 @@ export function datasourceNameFromDisplay(input) {
|
|
|
77
77
|
.replace(/[)]/g, '')
|
|
78
78
|
.split('(')
|
|
79
79
|
.map((x) => x.trim());
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const type = datasourceInputFromDisplay(parts[1]);
|
|
81
|
+
const name = parts[0];
|
|
82
|
+
const match = Object.entries(selectors.datasourceConfig.getAllConfigSet()).find(([_, ds]) => ds.KEY === name && ds.INPUT_TYPE === type);
|
|
83
|
+
if (!match) {
|
|
84
|
+
/**
|
|
85
|
+
* This can occur when the datasource is first being initialized and the name
|
|
86
|
+
* hasn't yet been persisted to the store.
|
|
87
|
+
*/
|
|
88
|
+
return `${type}_${name}_${name}`;
|
|
89
|
+
}
|
|
90
|
+
return match[0];
|
|
83
91
|
}
|
|
84
92
|
/**
|
|
85
93
|
* Formats datasource name for display
|
|
@@ -137,12 +145,12 @@ export function fetchDatasourceSpecs(datasourceName, getSchema, onError) {
|
|
|
137
145
|
return [];
|
|
138
146
|
}
|
|
139
147
|
try {
|
|
140
|
-
return yield Promise.all(Object.
|
|
141
|
-
.filter((
|
|
142
|
-
.map((_a) => __awaiter(this, [_a], void 0, function* ({ NAME }) {
|
|
148
|
+
return yield Promise.all(Object.entries(selectors.datasourceConfig.getAllConfigSet())
|
|
149
|
+
.filter(([key, ds]) => ds.INPUT_TYPE === 'REQ_REP' && key === datasourceName)
|
|
150
|
+
.map((_a) => __awaiter(this, [_a], void 0, function* ([_, { KEY, NAME }]) {
|
|
143
151
|
return ({
|
|
144
|
-
spec: yield getSchema(NAME),
|
|
145
|
-
name: datasourceNameForDisplay(
|
|
152
|
+
spec: yield getSchema(NAME), // Fetch schema by Resource Name
|
|
153
|
+
name: datasourceNameForDisplay(KEY, 'REQ_REP'), // Display Alias
|
|
146
154
|
});
|
|
147
155
|
})));
|
|
148
156
|
}
|
|
@@ -17,14 +17,17 @@ function createTestRowData(overrides = {}) {
|
|
|
17
17
|
const FIRST_PARAM = 0;
|
|
18
18
|
// DatasourceNameFromDisplay tests
|
|
19
19
|
const DatasourceNameFromDisplayTests = suite('datasourceNameFromDisplay()');
|
|
20
|
+
DatasourceNameFromDisplayTests.before.each(() => {
|
|
21
|
+
sinon.restore();
|
|
22
|
+
});
|
|
20
23
|
DatasourceNameFromDisplayTests('Correctly builds datasource key from Snapshot (REQ_REP) input', () => {
|
|
21
24
|
const input = 'myService (Snapshot)';
|
|
22
|
-
const expected = '
|
|
25
|
+
const expected = 'REQ_REP_myService_myService';
|
|
23
26
|
assert.equal(datasourceNameFromDisplay(input), expected);
|
|
24
27
|
});
|
|
25
28
|
DatasourceNameFromDisplayTests('Correctly builds datasource key from Data Pipeline (DATA_PIPELINE) input', () => {
|
|
26
29
|
const input = 'dataFlow (Data Pipeline)';
|
|
27
|
-
const expected = '
|
|
30
|
+
const expected = 'DATA_PIPELINE_dataFlow_dataFlow';
|
|
28
31
|
assert.equal(datasourceNameFromDisplay(input), expected);
|
|
29
32
|
});
|
|
30
33
|
DatasourceNameFromDisplayTests.run();
|
|
@@ -60,6 +63,8 @@ LookupColumnIsIncluded('returns true when column is in included', () => {
|
|
|
60
63
|
NAME: 'Test Datasource',
|
|
61
64
|
INPUT_TYPE: 'REQ_REP',
|
|
62
65
|
OUTPUT_TYPE: 'TABLE',
|
|
66
|
+
GROUPING_STRATEGY: 'NONE',
|
|
67
|
+
GROUP_KEY: null,
|
|
63
68
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: ['testColumn', 'otherColumn'] },
|
|
64
69
|
};
|
|
65
70
|
sinon.stub(selectors.datasourceConfig, 'getDatasource').returns(mockDatasource);
|
|
@@ -78,6 +83,8 @@ LookupColumnIsIncluded('returns false when column is not in filters', () => {
|
|
|
78
83
|
NAME: 'Test Datasource',
|
|
79
84
|
INPUT_TYPE: 'REQ_REP',
|
|
80
85
|
OUTPUT_TYPE: 'TABLE',
|
|
86
|
+
GROUPING_STRATEGY: 'NONE',
|
|
87
|
+
GROUP_KEY: null,
|
|
81
88
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: ['testColumn', 'otherColumn'] },
|
|
82
89
|
};
|
|
83
90
|
sinon.stub(selectors.datasourceConfig, 'getDatasource').returns(mockDatasource);
|
|
@@ -96,6 +103,8 @@ LookupColumnIsIncluded('returns false when INCLUDE_COLUMNS is undefined', () =>
|
|
|
96
103
|
NAME: 'Test Datasource',
|
|
97
104
|
INPUT_TYPE: 'REQ_REP',
|
|
98
105
|
OUTPUT_TYPE: 'TABLE',
|
|
106
|
+
GROUPING_STRATEGY: 'NONE',
|
|
107
|
+
GROUP_KEY: null,
|
|
99
108
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: undefined },
|
|
100
109
|
};
|
|
101
110
|
sinon.stub(selectors.datasourceConfig, 'getDatasource').returns(mockDatasource);
|
|
@@ -114,6 +123,8 @@ LookupColumnIsIncluded('returns false when INCLUDE_COLUMNS is empty array', () =
|
|
|
114
123
|
NAME: 'Test Datasource',
|
|
115
124
|
INPUT_TYPE: 'REQ_REP',
|
|
116
125
|
OUTPUT_TYPE: 'TABLE',
|
|
126
|
+
GROUPING_STRATEGY: 'NONE',
|
|
127
|
+
GROUP_KEY: null,
|
|
117
128
|
TRANSFORMER_CONFIGURATION: { INCLUDE_COLUMNS: [] },
|
|
118
129
|
};
|
|
119
130
|
sinon.stub(selectors.datasourceConfig, 'getDatasource').returns(mockDatasource);
|
|
@@ -7,7 +7,7 @@ export const template = html `
|
|
|
7
7
|
<rapid-tabs ${ref('tabs')}>
|
|
8
8
|
${repeat((_) => Object.entries(selectors.datasourceConfig.getAllConfigSet()), html `
|
|
9
9
|
<rapid-tab @click=${(x, c) => c.parent.handleDatasourceChanged(x[0])}>
|
|
10
|
-
${(x) => x[1].
|
|
10
|
+
${(x) => x[1].KEY}
|
|
11
11
|
</rapid-tab>
|
|
12
12
|
`)}
|
|
13
13
|
<!-- rapid-tab-panel unused for content, only used to make the rapid-tabs work correctly -->
|
|
@@ -10,14 +10,16 @@ export const datasourceSlice = createSlice({
|
|
|
10
10
|
initialState,
|
|
11
11
|
reducers: {
|
|
12
12
|
initDatasourceConfiguration(state, action) {
|
|
13
|
-
const { KEY, INPUT_TYPE } = action.payload.base;
|
|
14
|
-
const key = buildDatasourceName(KEY, INPUT_TYPE);
|
|
13
|
+
const { KEY, NAME, INPUT_TYPE } = action.payload.base;
|
|
14
|
+
const key = buildDatasourceName(KEY, NAME, INPUT_TYPE);
|
|
15
15
|
state[key] = {
|
|
16
16
|
KEY: KEY,
|
|
17
17
|
INPUT_TYPE: INPUT_TYPE,
|
|
18
|
-
NAME:
|
|
18
|
+
NAME: NAME,
|
|
19
19
|
OUTPUT_TYPE: 'TABLE',
|
|
20
20
|
TRANSFORMER_CONFIGURATION: {},
|
|
21
|
+
GROUPING_STRATEGY: 'NONE',
|
|
22
|
+
GROUP_KEY: null,
|
|
21
23
|
};
|
|
22
24
|
action.payload.fields.forEach((field) => {
|
|
23
25
|
datasourceSlice.caseReducers.setColumnRename(state, Object.assign(Object.assign({}, action), { payload: {
|
|
@@ -33,8 +35,32 @@ export const datasourceSlice = createSlice({
|
|
|
33
35
|
} }));
|
|
34
36
|
});
|
|
35
37
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
reorderDatasource(state, action) {
|
|
39
|
+
const { key, newIndex } = action.payload;
|
|
40
|
+
const entries = Object.entries(state);
|
|
41
|
+
const currentIndex = entries.findIndex(([k]) => k === key);
|
|
42
|
+
if (currentIndex === -1)
|
|
43
|
+
return state;
|
|
44
|
+
const [item] = entries.splice(currentIndex, 1);
|
|
45
|
+
entries.splice(newIndex, 0, item);
|
|
46
|
+
return Object.fromEntries(entries);
|
|
47
|
+
},
|
|
48
|
+
renameDatasource(state, action) {
|
|
49
|
+
const { key: oldKey, newName } = action.payload;
|
|
50
|
+
const datasource = state[oldKey];
|
|
51
|
+
if (!datasource) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const newKey = buildDatasourceName(newName, datasource.NAME, datasource.INPUT_TYPE);
|
|
55
|
+
if (state[newKey] && newKey !== oldKey) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
return Object.fromEntries(Object.entries(state).map(([k, v]) => {
|
|
59
|
+
if (k === oldKey) {
|
|
60
|
+
return [newKey, Object.assign(Object.assign({}, v), { KEY: newName })];
|
|
61
|
+
}
|
|
62
|
+
return [k, v];
|
|
63
|
+
}));
|
|
38
64
|
},
|
|
39
65
|
updateDatasourceOutputType(state, action) {
|
|
40
66
|
state[action.payload.key].OUTPUT_TYPE = action.payload.newType;
|
|
@@ -59,17 +85,20 @@ export const datasourceSlice = createSlice({
|
|
|
59
85
|
*/
|
|
60
86
|
setColumnIncluded(state, action) {
|
|
61
87
|
var _a, _b;
|
|
62
|
-
const { key, column, included, type } = action.payload;
|
|
88
|
+
const { key, column, included, type, setDefaultFormat = true } = action.payload;
|
|
63
89
|
if (included) {
|
|
64
90
|
state[key].TRANSFORMER_CONFIGURATION.INCLUDE_COLUMNS = [
|
|
65
91
|
...((_a = state[key].TRANSFORMER_CONFIGURATION.INCLUDE_COLUMNS) !== null && _a !== void 0 ? _a : []),
|
|
66
92
|
column,
|
|
67
93
|
];
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
const defaultFormat = getDefaultFormat(type);
|
|
95
|
+
if (defaultFormat && setDefaultFormat) {
|
|
96
|
+
datasourceSlice.caseReducers.setColumnFormat(state, Object.assign(Object.assign({}, action), { payload: {
|
|
97
|
+
key,
|
|
98
|
+
column,
|
|
99
|
+
format: defaultFormat,
|
|
100
|
+
} }));
|
|
101
|
+
}
|
|
73
102
|
}
|
|
74
103
|
else {
|
|
75
104
|
state[key].TRANSFORMER_CONFIGURATION.INCLUDE_COLUMNS = ((_b = state[key].TRANSFORMER_CONFIGURATION.INCLUDE_COLUMNS) !== null && _b !== void 0 ? _b : []).filter((col) => col !== column);
|
|
@@ -119,6 +148,16 @@ export const datasourceSlice = createSlice({
|
|
|
119
148
|
const _c = (_b = (_a = state[key].TRANSFORMER_CONFIGURATION) === null || _a === void 0 ? void 0 : _a.COLUMN_FORMATS) !== null && _b !== void 0 ? _b : {}, _d = column, _ = _c[_d], rest = __rest(_c, [typeof _d === "symbol" ? _d : _d + ""]);
|
|
120
149
|
state[key].TRANSFORMER_CONFIGURATION.COLUMN_FORMATS = rest;
|
|
121
150
|
},
|
|
151
|
+
setGrouping(state, action) {
|
|
152
|
+
const { key, grouping } = action.payload;
|
|
153
|
+
state[key].GROUPING_STRATEGY = grouping.GROUPING_STRATEGY;
|
|
154
|
+
state[key].GROUP_KEY = grouping.GROUP_KEY;
|
|
155
|
+
},
|
|
156
|
+
deleteGrouping(state, action) {
|
|
157
|
+
const { key } = action.payload;
|
|
158
|
+
state[key].GROUPING_STRATEGY = 'NONE';
|
|
159
|
+
state[key].GROUP_KEY = null;
|
|
160
|
+
},
|
|
122
161
|
},
|
|
123
162
|
selectors: {
|
|
124
163
|
getAllConfigSet(state) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a unique alias by appending a counter if the base alias already exists in the set.
|
|
3
|
+
* @param baseAlias The desired alias name (usually the resource name).
|
|
4
|
+
* @param existingAliases A Set of currently used aliases to check against.
|
|
5
|
+
* @returns A unique alias string.
|
|
6
|
+
*/
|
|
7
|
+
export function generateUniqueAlias(baseAlias, existingAliases) {
|
|
8
|
+
const existingAliasesLower = new Set(Array.from(existingAliases).map((alias) => alias.toLowerCase()));
|
|
9
|
+
let uniqueAlias = baseAlias;
|
|
10
|
+
let counter = 1;
|
|
11
|
+
while (existingAliasesLower.has(uniqueAlias.toLowerCase())) {
|
|
12
|
+
uniqueAlias = `${baseAlias}_${counter}`;
|
|
13
|
+
counter += 1;
|
|
14
|
+
}
|
|
15
|
+
return uniqueAlias;
|
|
16
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { assert, suite } from '@genesislcap/foundation-testing';
|
|
2
|
+
import { generateUniqueAlias } from './alias-generator';
|
|
3
|
+
const GenerateUniqueAlias = suite('generateUniqueAlias');
|
|
4
|
+
GenerateUniqueAlias('returns the base alias if it does not exist', () => {
|
|
5
|
+
const existingAliases = new Set(['other']);
|
|
6
|
+
const alias = generateUniqueAlias('test', existingAliases);
|
|
7
|
+
assert.equal(alias, 'test');
|
|
8
|
+
});
|
|
9
|
+
GenerateUniqueAlias('increments the alias if it already exists', () => {
|
|
10
|
+
const existingAliases = new Set(['test']);
|
|
11
|
+
const alias = generateUniqueAlias('test', existingAliases);
|
|
12
|
+
assert.equal(alias, 'test_1');
|
|
13
|
+
});
|
|
14
|
+
GenerateUniqueAlias('increments the alias until it is unique', () => {
|
|
15
|
+
const existingAliases = new Set(['test', 'test_1']);
|
|
16
|
+
const alias = generateUniqueAlias('test', existingAliases);
|
|
17
|
+
assert.equal(alias, 'test_2');
|
|
18
|
+
});
|
|
19
|
+
GenerateUniqueAlias('handles case-insensitivity when checking for existing aliases', () => {
|
|
20
|
+
const existingAliases = new Set(['Test']);
|
|
21
|
+
const alias = generateUniqueAlias('test', existingAliases);
|
|
22
|
+
assert.equal(alias, 'test_1');
|
|
23
|
+
});
|
|
24
|
+
GenerateUniqueAlias('handles case-insensitivity for new alias generation', () => {
|
|
25
|
+
const existingAliases = new Set(['test']);
|
|
26
|
+
const alias = generateUniqueAlias('Test', existingAliases);
|
|
27
|
+
// Since input baseAlias is 'Test', it tries 'Test'. 'Test' matches 'test' case-insensitively.
|
|
28
|
+
// Next attempt 'Test_1'.
|
|
29
|
+
assert.equal(alias, 'Test_1');
|
|
30
|
+
});
|
|
31
|
+
GenerateUniqueAlias('handles mixed case existing aliases', () => {
|
|
32
|
+
const existingAliases = new Set(['TeSt', 'tEsT_1']);
|
|
33
|
+
const alias = generateUniqueAlias('test', existingAliases);
|
|
34
|
+
assert.equal(alias, 'test_2');
|
|
35
|
+
});
|
|
36
|
+
GenerateUniqueAlias.run();
|
|
@@ -44,6 +44,10 @@ export var TOOLTIP;
|
|
|
44
44
|
<li>Where File type is set to <strong>PDF</strong> you must select a <code>.html</code> or <code>.xhtml</code> template that you've uploaded to the document manager PBC</li>
|
|
45
45
|
</ul>
|
|
46
46
|
`;
|
|
47
|
+
TOOLTIP.DATASOURCES_DATASOURCE = `
|
|
48
|
+
<h3>Datasource</h3>
|
|
49
|
+
<p>This is the name of the server resource that data will be pulled from to generate the report.</p>
|
|
50
|
+
`;
|
|
47
51
|
TOOLTIP.DATASOURCES_NAME = `
|
|
48
52
|
<h3>Datasource name</h3>
|
|
49
53
|
<p>Allows you to set a name for the datasource which must correspond with your template data references where the report is configured to use a template file.</p>
|
|
@@ -52,6 +56,18 @@ export var TOOLTIP;
|
|
|
52
56
|
TOOLTIP.DATASOURCES_TYPE = `
|
|
53
57
|
<h3>Datasource type</h3>
|
|
54
58
|
<p>Configures the method by which the server constructs the report configuration. Currently only TABLE is supported, which means the entire datasource is loaded into memory when generating the report using this report configuration.</p>
|
|
59
|
+
`;
|
|
60
|
+
TOOLTIP.DATASOURCES_GROUPING_STRATEGY = `
|
|
61
|
+
<h3>Grouping Strategy</h3>
|
|
62
|
+
<p>Select "None" to disable grouping strategies, or select the strategy you'd like to use.</p>
|
|
63
|
+
<ul>
|
|
64
|
+
<li><strong>Multi-sheet</strong>: Group data for <code>JXLS</code> template Multi-sheet functionality, to split different groups across multiple excel worksheets.</li>
|
|
65
|
+
<li><strong>Lookup-table</strong>: Create a lookup table of key value pairs in the template data, where the group key field is the map key.</li>
|
|
66
|
+
</ul>
|
|
67
|
+
`;
|
|
68
|
+
TOOLTIP.DATASOURCES_GROUPING_KEY = `
|
|
69
|
+
<h3>Grouping Key</h3>
|
|
70
|
+
<p>Select the field for this datasource you want to operate the grouping strategy on.</p>
|
|
55
71
|
`;
|
|
56
72
|
TOOLTIP.DELIVERY_TIMEZONE = `
|
|
57
73
|
<h3>Timezone</h3>
|
|
@@ -10,7 +10,14 @@ export function transformToServerPayload(state) {
|
|
|
10
10
|
// TODO: server workaround - currently need to explicitly set to null if unset
|
|
11
11
|
DOCUMENT_TEMPLATE_ID: restBaseConfig.DOCUMENT_TEMPLATE_ID
|
|
12
12
|
? restBaseConfig.DOCUMENT_TEMPLATE_ID
|
|
13
|
-
: null, DATA_SOURCES: Object.values(datasourceConfig)
|
|
13
|
+
: null, DATA_SOURCES: Object.values(datasourceConfig).map((ds) => {
|
|
14
|
+
// For NONE case we just don't send it to the server to be backwards compatible
|
|
15
|
+
if (ds.GROUPING_STRATEGY === 'NONE') {
|
|
16
|
+
const { GROUPING_STRATEGY, GROUP_KEY } = ds, rest = __rest(ds, ["GROUPING_STRATEGY", "GROUP_KEY"]);
|
|
17
|
+
return rest;
|
|
18
|
+
}
|
|
19
|
+
return ds;
|
|
20
|
+
}) });
|
|
14
21
|
}
|
|
15
22
|
/**
|
|
16
23
|
* Cleans up orphaned field references from transformer configuration
|
|
@@ -46,10 +53,12 @@ export function transformFromServerPayload(payload, getSchema) {
|
|
|
46
53
|
DESTINATION_IDS,
|
|
47
54
|
OUTPUT_DIRECTORY,
|
|
48
55
|
DOCUMENT_TEMPLATE_ID }, (SCHEDULES.length > 0 && { SCHEDULE: SCHEDULES[0] }));
|
|
49
|
-
const cleanedDatasources = yield Promise.all(DATA_SOURCES.map((_a) => __awaiter(this,
|
|
56
|
+
const cleanedDatasources = yield Promise.all(DATA_SOURCES.map((_a) => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
var { KEY, INPUT_TYPE, NAME: DS_NAME, OUTPUT_TYPE, TRANSFORMER_CONFIGURATION } = _a, rest = __rest(_a, ["KEY", "INPUT_TYPE", "NAME", "OUTPUT_TYPE", "TRANSFORMER_CONFIGURATION"]);
|
|
50
58
|
try {
|
|
51
|
-
const schema = yield getSchema(
|
|
59
|
+
const schema = yield getSchema(DS_NAME);
|
|
52
60
|
const validFields = new Set(Object.keys(schema.properties || {}));
|
|
61
|
+
const { GROUPING_STRATEGY, GROUP_KEY } = rest;
|
|
53
62
|
const cleanedConfig = cleanupTransformerConfig(TRANSFORMER_CONFIGURATION || {}, validFields);
|
|
54
63
|
return {
|
|
55
64
|
KEY,
|
|
@@ -57,23 +66,28 @@ export function transformFromServerPayload(payload, getSchema) {
|
|
|
57
66
|
NAME: DS_NAME,
|
|
58
67
|
OUTPUT_TYPE,
|
|
59
68
|
TRANSFORMER_CONFIGURATION: cleanedConfig,
|
|
69
|
+
GROUPING_STRATEGY: GROUPING_STRATEGY || 'NONE',
|
|
70
|
+
GROUP_KEY: GROUP_KEY || null,
|
|
60
71
|
};
|
|
61
72
|
}
|
|
62
73
|
catch (error) {
|
|
63
74
|
// If schema fetch fails, log warning but keep original config
|
|
64
75
|
console.warn(`Failed to fetch schema for ${KEY}, skipping cleanup:`, error);
|
|
76
|
+
const { GROUPING_STRATEGY, GROUP_KEY } = rest;
|
|
65
77
|
return {
|
|
66
78
|
KEY,
|
|
67
79
|
INPUT_TYPE,
|
|
68
80
|
NAME: DS_NAME,
|
|
69
81
|
OUTPUT_TYPE,
|
|
70
82
|
TRANSFORMER_CONFIGURATION: TRANSFORMER_CONFIGURATION || {},
|
|
83
|
+
GROUPING_STRATEGY: GROUPING_STRATEGY || 'NONE',
|
|
84
|
+
GROUP_KEY: GROUP_KEY || null,
|
|
71
85
|
};
|
|
72
86
|
}
|
|
73
87
|
})));
|
|
74
88
|
return {
|
|
75
89
|
baseConfig,
|
|
76
|
-
datasourceConfig: cleanedDatasources.reduce((acum, ds) => (Object.assign(Object.assign({}, acum), { [buildDatasourceName(ds.NAME, ds.INPUT_TYPE)]: ds })), {}),
|
|
90
|
+
datasourceConfig: cleanedDatasources.reduce((acum, ds) => (Object.assign(Object.assign({}, acum), { [buildDatasourceName(ds.KEY, ds.NAME, ds.INPUT_TYPE)]: ds })), {}),
|
|
77
91
|
};
|
|
78
92
|
});
|
|
79
93
|
}
|
|
@@ -93,6 +107,6 @@ export function datasourceInputFromDisplay(display) {
|
|
|
93
107
|
else
|
|
94
108
|
throw new Error(`datasourceInputFromDisplay - Uncaught case ${display}`);
|
|
95
109
|
}
|
|
96
|
-
export function buildDatasourceName(
|
|
97
|
-
return `${type}_${
|
|
110
|
+
export function buildDatasourceName(alias, resourceName, type) {
|
|
111
|
+
return `${type}_${resourceName}_${alias}`;
|
|
98
112
|
}
|