@axinom/mosaic-graphql-codegen-plugins 0.6.0-rc.9 → 0.6.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/generate-bulk-edit-ui-config/generate-bulk-edit-ui-config.d.ts +1 -0
- package/dist/generate-bulk-edit-ui-config/generate-bulk-edit-ui-config.js +23 -1
- package/dist/generate-bulk-edit-ui-config/model.d.ts +24 -0
- package/dist/generate-bulk-edit-ui-config/model.js +2 -0
- package/package.json +2 -2
- package/src/generate-bulk-edit-ui-config/generate-bulk-edit-ui-config.spec.ts +144 -1
- package/src/generate-bulk-edit-ui-config/generate-bulk-edit-ui-config.ts +44 -10
- package/src/generate-bulk-edit-ui-config/model.ts +25 -0
|
@@ -5,6 +5,7 @@ const change_case_all_1 = require("change-case-all");
|
|
|
5
5
|
const plugin = (schema, _documents, config) => {
|
|
6
6
|
const addKey = config.addKey || 'relatedEntitiesToAdd';
|
|
7
7
|
const removeKey = config.removeKey || 'relatedEntitiesToRemove';
|
|
8
|
+
const clearKey = config.clearKey || 'relatedEntitiesToClear';
|
|
8
9
|
const setKey = config.setKey || 'set';
|
|
9
10
|
const filterKey = config.filterKey || 'filter';
|
|
10
11
|
const mutationType = schema.getMutationType();
|
|
@@ -32,8 +33,15 @@ const plugin = (schema, _documents, config) => {
|
|
|
32
33
|
break;
|
|
33
34
|
}
|
|
34
35
|
});
|
|
36
|
+
// Check for related entities to clear and set clearable and clearValue accordingly
|
|
37
|
+
if (mutation.args.some((a) => a.name === clearKey)) {
|
|
38
|
+
const clearArg = mutation.args.find((a) => a.name === clearKey);
|
|
39
|
+
if (clearArg) {
|
|
40
|
+
formFieldsConfig = resolveClearValues(typesMap[clearArg.type.toString()].getFields(), formFieldsConfig, removeKey);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
35
43
|
if (Object.keys(formFieldsConfig).length > 0) {
|
|
36
|
-
return `export const ${(0, change_case_all_1.pascalCase)(mutationName)}FormFieldsConfig = { mutation: '${mutationName}', keys: { add: '${addKey}', remove: '${removeKey}', set: '${setKey}', filter: '${filterKey}' }, fields: ${JSON.stringify(formFieldsConfig, null, 2)}};`;
|
|
44
|
+
return `export const ${(0, change_case_all_1.pascalCase)(mutationName)}FormFieldsConfig = { mutation: '${mutationName}', keys: { add: '${addKey}', remove: '${removeKey}', clear: '${clearKey}', set: '${setKey}', filter: '${filterKey}' }, fields: ${JSON.stringify(formFieldsConfig, null, 2)}};`;
|
|
37
45
|
}
|
|
38
46
|
});
|
|
39
47
|
return ['/** Bulk Edit Configurations **/', ...configs]
|
|
@@ -77,3 +85,17 @@ function resolveFields(fields, action, postfix = '') {
|
|
|
77
85
|
});
|
|
78
86
|
return resultingFields;
|
|
79
87
|
}
|
|
88
|
+
// If relatedEntitiesToClear contains a field make the clearable field true on the corresponding relatedEntitiesToRemove field.
|
|
89
|
+
function resolveClearValues(fields, fieldMap, action) {
|
|
90
|
+
const resultingFields = Object.assign({}, fieldMap);
|
|
91
|
+
Object.keys(fields).forEach((fieldName) => {
|
|
92
|
+
Object.keys(fieldMap).map((fieldMapFieldName) => {
|
|
93
|
+
const field = fieldMap[fieldMapFieldName];
|
|
94
|
+
if (field.originalFieldName === fieldName && field.action === action) {
|
|
95
|
+
resultingFields[fieldMapFieldName].clearable = true;
|
|
96
|
+
resultingFields[fieldMapFieldName].clearValue = [];
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
return resultingFields;
|
|
101
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface BulkEditFieldConfig {
|
|
2
|
+
type: string | {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}[];
|
|
5
|
+
label: string;
|
|
6
|
+
originalFieldName: string;
|
|
7
|
+
action: string;
|
|
8
|
+
clearable?: boolean;
|
|
9
|
+
clearValue?: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface BulkEditFieldConfigMap {
|
|
12
|
+
[key: string]: BulkEditFieldConfig;
|
|
13
|
+
}
|
|
14
|
+
export interface BulkEditConfig {
|
|
15
|
+
mutation: string;
|
|
16
|
+
keys?: {
|
|
17
|
+
add: string;
|
|
18
|
+
remove: string;
|
|
19
|
+
clear: string;
|
|
20
|
+
set: string;
|
|
21
|
+
filter: string;
|
|
22
|
+
};
|
|
23
|
+
fields: BulkEditFieldConfigMap;
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-graphql-codegen-plugins",
|
|
3
|
-
"version": "0.6.0
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Library of graphql-codegen plugins for Mosaic workflows",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc -w",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "9482bdb8e36edf78e1a64c53e9b9f5bdfff9eac1"
|
|
48
48
|
}
|
|
@@ -81,7 +81,7 @@ describe('generate-bulk-edit-ui-config plugin', () => {
|
|
|
81
81
|
expect(result).toContain('export const BulkEditEntityFormFieldsConfig');
|
|
82
82
|
expect(result).toContain("mutation: 'bulkEditEntity'");
|
|
83
83
|
expect(result).toContain(
|
|
84
|
-
"keys: { add: 'relatedEntitiesToAdd', remove: 'relatedEntitiesToRemove', set: 'set', filter: 'filter' }",
|
|
84
|
+
"keys: { add: 'relatedEntitiesToAdd', remove: 'relatedEntitiesToRemove', clear: 'relatedEntitiesToClear', set: 'set', filter: 'filter' }",
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
// Validate the config contains proper JSON structure for fields
|
|
@@ -289,6 +289,7 @@ describe('generate-bulk-edit-ui-config plugin', () => {
|
|
|
289
289
|
const customConfig: Partial<BulkEditPluginConfig> = {
|
|
290
290
|
addKey: 'customAdd',
|
|
291
291
|
removeKey: 'customRemove',
|
|
292
|
+
clearKey: 'customClear',
|
|
292
293
|
setKey: 'customSet',
|
|
293
294
|
filterKey: 'customFilter',
|
|
294
295
|
};
|
|
@@ -376,4 +377,146 @@ describe('generate-bulk-edit-ui-config plugin', () => {
|
|
|
376
377
|
// Restore console.warn
|
|
377
378
|
consoleWarnSpy.mockRestore();
|
|
378
379
|
});
|
|
380
|
+
|
|
381
|
+
it('should handle relatedEntitiesToClear and set clearable flags on remove fields', () => {
|
|
382
|
+
const ClearableEntitiesInputType = new GraphQLInputObjectType({
|
|
383
|
+
name: 'ClearableEntitiesInput',
|
|
384
|
+
fields: {
|
|
385
|
+
assignee: { type: GraphQLString },
|
|
386
|
+
tags: { type: GraphQLString },
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const RelatedEntitiesInputType = new GraphQLInputObjectType({
|
|
391
|
+
name: 'RelatedEntitiesInput',
|
|
392
|
+
fields: {
|
|
393
|
+
assignee: { type: GraphQLString },
|
|
394
|
+
tags: { type: GraphQLString },
|
|
395
|
+
reviewer: { type: GraphQLString },
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
const SetInputType = new GraphQLInputObjectType({
|
|
400
|
+
name: 'SetInput',
|
|
401
|
+
fields: {
|
|
402
|
+
status: { type: GraphQLString },
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
const MutationTypeWithClear = new GraphQLObjectType({
|
|
407
|
+
name: 'Mutation',
|
|
408
|
+
fields: {
|
|
409
|
+
bulkEditWithClear: {
|
|
410
|
+
type: GraphQLString,
|
|
411
|
+
args: {
|
|
412
|
+
relatedEntitiesToAdd: { type: RelatedEntitiesInputType },
|
|
413
|
+
relatedEntitiesToRemove: { type: RelatedEntitiesInputType },
|
|
414
|
+
relatedEntitiesToClear: { type: ClearableEntitiesInputType },
|
|
415
|
+
set: { type: SetInputType },
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const schemaWithClear = new GraphQLSchema({
|
|
422
|
+
query: new GraphQLObjectType({
|
|
423
|
+
name: 'Query',
|
|
424
|
+
fields: { dummy: { type: GraphQLString } },
|
|
425
|
+
}),
|
|
426
|
+
mutation: MutationTypeWithClear,
|
|
427
|
+
types: [
|
|
428
|
+
RelatedEntitiesInputType,
|
|
429
|
+
ClearableEntitiesInputType,
|
|
430
|
+
SetInputType,
|
|
431
|
+
],
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
const result = plugin(schemaWithClear, [], {}) as string;
|
|
435
|
+
|
|
436
|
+
// Check that the config is generated
|
|
437
|
+
expect(result).toContain('BulkEditWithClearFormFieldsConfig');
|
|
438
|
+
|
|
439
|
+
// Parse the result to verify the clearable flags
|
|
440
|
+
const fieldsMatch = result.match(/fields: (\{[\s\S]*?\})\};/);
|
|
441
|
+
expect(fieldsMatch).toBeTruthy();
|
|
442
|
+
|
|
443
|
+
const fieldsJson = JSON.parse(fieldsMatch![1]);
|
|
444
|
+
|
|
445
|
+
// Fields that appear in relatedEntitiesToClear should have clearable: true
|
|
446
|
+
expect(fieldsJson.assigneeRemove).toHaveProperty('clearable', true);
|
|
447
|
+
expect(fieldsJson.assigneeRemove).toHaveProperty('clearValue', []);
|
|
448
|
+
expect(fieldsJson.tagsRemove).toHaveProperty('clearable', true);
|
|
449
|
+
expect(fieldsJson.tagsRemove).toHaveProperty('clearValue', []);
|
|
450
|
+
|
|
451
|
+
// Field that does NOT appear in relatedEntitiesToClear should not have clearable
|
|
452
|
+
expect(fieldsJson.reviewerRemove).not.toHaveProperty('clearable');
|
|
453
|
+
expect(fieldsJson.reviewerRemove).not.toHaveProperty('clearValue');
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it('should use custom clearKey from config', () => {
|
|
457
|
+
const ClearableEntitiesInputType = new GraphQLInputObjectType({
|
|
458
|
+
name: 'ClearableEntitiesInput',
|
|
459
|
+
fields: {
|
|
460
|
+
assignee: { type: GraphQLString },
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
const RelatedEntitiesInputType = new GraphQLInputObjectType({
|
|
465
|
+
name: 'RelatedEntitiesInput',
|
|
466
|
+
fields: {
|
|
467
|
+
assignee: { type: GraphQLString },
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
const SetInputType = new GraphQLInputObjectType({
|
|
472
|
+
name: 'SetInput',
|
|
473
|
+
fields: {
|
|
474
|
+
status: { type: GraphQLString },
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
const MutationTypeWithCustomClear = new GraphQLObjectType({
|
|
479
|
+
name: 'Mutation',
|
|
480
|
+
fields: {
|
|
481
|
+
bulkEditCustomClear: {
|
|
482
|
+
type: GraphQLString,
|
|
483
|
+
args: {
|
|
484
|
+
relatedEntitiesToAdd: { type: RelatedEntitiesInputType },
|
|
485
|
+
relatedEntitiesToRemove: { type: RelatedEntitiesInputType },
|
|
486
|
+
customClearKey: { type: ClearableEntitiesInputType },
|
|
487
|
+
set: { type: SetInputType },
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
const schemaWithCustomClear = new GraphQLSchema({
|
|
494
|
+
query: new GraphQLObjectType({
|
|
495
|
+
name: 'Query',
|
|
496
|
+
fields: { dummy: { type: GraphQLString } },
|
|
497
|
+
}),
|
|
498
|
+
mutation: MutationTypeWithCustomClear,
|
|
499
|
+
types: [
|
|
500
|
+
RelatedEntitiesInputType,
|
|
501
|
+
ClearableEntitiesInputType,
|
|
502
|
+
SetInputType,
|
|
503
|
+
],
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
const customConfig: Partial<BulkEditPluginConfig> = {
|
|
507
|
+
clearKey: 'customClearKey',
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
const result = plugin(schemaWithCustomClear, [], customConfig) as string;
|
|
511
|
+
|
|
512
|
+
// Parse the result to verify the clearable flags were set with custom key
|
|
513
|
+
const fieldsMatch = result.match(/fields: (\{[\s\S]*?\})\};/);
|
|
514
|
+
expect(fieldsMatch).toBeTruthy();
|
|
515
|
+
|
|
516
|
+
const fieldsJson = JSON.parse(fieldsMatch![1]);
|
|
517
|
+
|
|
518
|
+
// Field that appears in customClearKey should have clearable: true
|
|
519
|
+
expect(fieldsJson.assigneeRemove).toHaveProperty('clearable', true);
|
|
520
|
+
expect(fieldsJson.assigneeRemove).toHaveProperty('clearValue', []);
|
|
521
|
+
});
|
|
379
522
|
});
|
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
import { PluginFunction } from '@graphql-codegen/plugin-helpers';
|
|
3
3
|
import { capitalCase, pascalCase } from 'change-case-all';
|
|
4
4
|
import { GraphQLFieldMap, GraphQLList, GraphQLObjectType } from 'graphql';
|
|
5
|
+
import { BulkEditFieldConfigMap } from './model';
|
|
5
6
|
|
|
6
7
|
export interface BulkEditPluginConfig {
|
|
7
8
|
addKey?: string;
|
|
8
9
|
removeKey?: string;
|
|
10
|
+
clearKey?: string;
|
|
9
11
|
setKey?: string;
|
|
10
12
|
filterKey?: string;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
interface Data {
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
15
|
export const plugin: PluginFunction<Partial<BulkEditPluginConfig>> = (
|
|
18
16
|
schema,
|
|
19
17
|
_documents,
|
|
@@ -21,6 +19,7 @@ export const plugin: PluginFunction<Partial<BulkEditPluginConfig>> = (
|
|
|
21
19
|
) => {
|
|
22
20
|
const addKey = config.addKey || 'relatedEntitiesToAdd';
|
|
23
21
|
const removeKey = config.removeKey || 'relatedEntitiesToRemove';
|
|
22
|
+
const clearKey = config.clearKey || 'relatedEntitiesToClear';
|
|
24
23
|
const setKey = config.setKey || 'set';
|
|
25
24
|
const filterKey = config.filterKey || 'filter';
|
|
26
25
|
|
|
@@ -39,7 +38,7 @@ export const plugin: PluginFunction<Partial<BulkEditPluginConfig>> = (
|
|
|
39
38
|
const configs = Object.keys(mutations).map((mutationName) => {
|
|
40
39
|
const mutation = mutations[mutationName];
|
|
41
40
|
|
|
42
|
-
let formFieldsConfig = {};
|
|
41
|
+
let formFieldsConfig: BulkEditFieldConfigMap = {};
|
|
43
42
|
|
|
44
43
|
mutation.args.map((arg) => {
|
|
45
44
|
switch (arg.name.toString()) {
|
|
@@ -75,10 +74,23 @@ export const plugin: PluginFunction<Partial<BulkEditPluginConfig>> = (
|
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
76
|
|
|
77
|
+
// Check for related entities to clear and set clearable and clearValue accordingly
|
|
78
|
+
if (mutation.args.some((a) => a.name === clearKey)) {
|
|
79
|
+
const clearArg = mutation.args.find((a) => a.name === clearKey);
|
|
80
|
+
|
|
81
|
+
if (clearArg) {
|
|
82
|
+
formFieldsConfig = resolveClearValues(
|
|
83
|
+
(typesMap[clearArg.type.toString()] as GraphQLObjectType).getFields(),
|
|
84
|
+
formFieldsConfig,
|
|
85
|
+
removeKey,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
78
90
|
if (Object.keys(formFieldsConfig).length > 0) {
|
|
79
91
|
return `export const ${pascalCase(
|
|
80
92
|
mutationName,
|
|
81
|
-
)}FormFieldsConfig = { mutation: '${mutationName}', keys: { add: '${addKey}', remove: '${removeKey}', set: '${setKey}', filter: '${filterKey}' }, fields: ${JSON.stringify(
|
|
93
|
+
)}FormFieldsConfig = { mutation: '${mutationName}', keys: { add: '${addKey}', remove: '${removeKey}', clear: '${clearKey}', set: '${setKey}', filter: '${filterKey}' }, fields: ${JSON.stringify(
|
|
82
94
|
formFieldsConfig,
|
|
83
95
|
null,
|
|
84
96
|
2,
|
|
@@ -95,19 +107,19 @@ function resolveFields(
|
|
|
95
107
|
fields: GraphQLFieldMap<any, any>,
|
|
96
108
|
action: string,
|
|
97
109
|
postfix = '',
|
|
98
|
-
):
|
|
99
|
-
const resultingFields:
|
|
110
|
+
): BulkEditFieldConfigMap {
|
|
111
|
+
const resultingFields: BulkEditFieldConfigMap = {};
|
|
100
112
|
Object.keys(fields).map((fieldName) => {
|
|
101
113
|
const field = fields[fieldName];
|
|
102
114
|
|
|
103
|
-
let type: string |
|
|
115
|
+
let type: string | BulkEditFieldConfigMap[] = field.type.toString();
|
|
104
116
|
|
|
105
117
|
try {
|
|
106
118
|
// Handle list of composite types
|
|
107
119
|
const fields = (field.type as GraphQLList<any>).ofType?.getFields?.();
|
|
108
120
|
|
|
109
121
|
if (fields && typeof fields === 'object') {
|
|
110
|
-
const compositeType:
|
|
122
|
+
const compositeType: BulkEditFieldConfigMap = {};
|
|
111
123
|
|
|
112
124
|
Object.keys(fields).forEach((key) => {
|
|
113
125
|
const name = fields[key].name;
|
|
@@ -139,3 +151,25 @@ function resolveFields(
|
|
|
139
151
|
|
|
140
152
|
return resultingFields;
|
|
141
153
|
}
|
|
154
|
+
|
|
155
|
+
// If relatedEntitiesToClear contains a field make the clearable field true on the corresponding relatedEntitiesToRemove field.
|
|
156
|
+
function resolveClearValues(
|
|
157
|
+
fields: GraphQLFieldMap<any, any>,
|
|
158
|
+
fieldMap: BulkEditFieldConfigMap,
|
|
159
|
+
action: string,
|
|
160
|
+
): BulkEditFieldConfigMap {
|
|
161
|
+
const resultingFields: BulkEditFieldConfigMap = { ...fieldMap };
|
|
162
|
+
|
|
163
|
+
Object.keys(fields).forEach((fieldName) => {
|
|
164
|
+
Object.keys(fieldMap).map((fieldMapFieldName) => {
|
|
165
|
+
const field = fieldMap[fieldMapFieldName];
|
|
166
|
+
|
|
167
|
+
if (field.originalFieldName === fieldName && field.action === action) {
|
|
168
|
+
resultingFields[fieldMapFieldName].clearable = true;
|
|
169
|
+
resultingFields[fieldMapFieldName].clearValue = [];
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return resultingFields;
|
|
175
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// TODO: Duplicate of libs/ui/src/components/BulkEdit/BulkEdit.models.ts - consider moving to a shared location
|
|
2
|
+
export interface BulkEditFieldConfig {
|
|
3
|
+
type: string | { [key: string]: unknown }[];
|
|
4
|
+
label: string;
|
|
5
|
+
originalFieldName: string;
|
|
6
|
+
action: string;
|
|
7
|
+
clearable?: boolean;
|
|
8
|
+
clearValue?: unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface BulkEditFieldConfigMap {
|
|
12
|
+
[key: string]: BulkEditFieldConfig;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BulkEditConfig {
|
|
16
|
+
mutation: string;
|
|
17
|
+
keys?: {
|
|
18
|
+
add: string;
|
|
19
|
+
remove: string;
|
|
20
|
+
clear: string;
|
|
21
|
+
set: string;
|
|
22
|
+
filter: string;
|
|
23
|
+
};
|
|
24
|
+
fields: BulkEditFieldConfigMap;
|
|
25
|
+
}
|