Skip to content

Commit 96af141

Browse files
authored
Merge pull request #27 from PADAS/25-multi-select-checkbox
Add support for multi-select checkbox
2 parents 4df05d6 + 7c40aa7 commit 96af141

File tree

5 files changed

+88
-13
lines changed

5 files changed

+88
-13
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@earthranger/react-native-jsonforms-formatter",
3-
"version": "2.0.0-beta.5",
3+
"version": "2.0.0-beta.8",
44
"description": "Converts JTD into JSON Schema ",
55
"main": "./dist/bundle.js",
66
"types": "./dist/index.d.ts",

src/common/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface V2BaseProperty {
4040
minimum?: number;
4141
maximum?: number;
4242
format?: 'date-time' | 'date' | 'time' | 'uri';
43-
anyOf?: Array<{ $ref: string }>;
43+
anyOf?: Array<{ $ref: string } | { oneOf: Array<{ const: any; title?: string }> }>;
4444
items?: V2BaseProperty;
4545
properties?: Record<string, V2BaseProperty>;
4646
required?: string[];

src/v2/generateUISchema.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,60 @@ import {
1111
groupFieldsBySection
1212
} from './utils';
1313

14+
/**
15+
* Validates V2 schema structure for known issues
16+
*/
17+
const validateV2Schema = (schema: V2Schema): void => {
18+
const invalidFields: string[] = [];
19+
const supportedFieldTypes = ['TEXT', 'NUMERIC', 'DATE_TIME', 'CHOICE_LIST', 'LOCATION', 'COLLECTION', 'ATTACHMENT'];
20+
21+
// Check each field for validity
22+
Object.entries(schema.json.properties).forEach(([fieldName, property]) => {
23+
const uiField = schema.ui.fields[fieldName];
24+
25+
// Skip deprecated fields without UI definitions (they won't be rendered anyway)
26+
if (!uiField && property.deprecated) {
27+
return;
28+
}
29+
30+
if (!uiField) {
31+
invalidFields.push(`${fieldName}: missing UI field definition`);
32+
return;
33+
}
34+
35+
// Check for unsupported field types
36+
if (!supportedFieldTypes.includes(uiField.type)) {
37+
invalidFields.push(`${fieldName}: unsupported field type '${uiField.type}'`);
38+
return;
39+
}
40+
41+
// Check CHOICE_LIST fields for valid structure (not content)
42+
if (uiField.type === 'CHOICE_LIST') {
43+
let hasValidStructure = false;
44+
45+
if (property.type === 'array' && property.items?.anyOf) {
46+
// Check for oneOf arrays in anyOf items for array types (no $ref support)
47+
hasValidStructure = property.items.anyOf.some((anyOfItem: any) =>
48+
anyOfItem.oneOf && Array.isArray(anyOfItem.oneOf) // Empty arrays are valid
49+
);
50+
} else if (property.anyOf) {
51+
// Check direct anyOf structure for string types (no $ref support)
52+
hasValidStructure = property.anyOf.some((anyOfItem: any) =>
53+
anyOfItem.oneOf && Array.isArray(anyOfItem.oneOf) // Empty arrays are valid
54+
);
55+
}
56+
57+
if (!hasValidStructure) {
58+
invalidFields.push(`${fieldName}: CHOICE_LIST field requires embedded oneOf arrays - $ref not supported`);
59+
}
60+
}
61+
});
62+
63+
if (invalidFields.length > 0) {
64+
throw new Error(`Invalid V2 schema structure: ${invalidFields.join(', ')}`);
65+
}
66+
};
67+
1468
/**
1569
* Generates a JSONForms-compatible UI schema from a EarthRanger V2 schema format
1670
*
@@ -21,8 +75,12 @@ import {
2175
*
2276
* @param schema - EarthRanger V2 schema with json and ui properties
2377
* @returns JSONForms UI schema with single-column VerticalLayout for React Native
78+
* @throws Error if schema has invalid structure or unsupported field configurations
2479
*/
2580
export const generateUISchema = (schema: V2Schema): JSONFormsUISchema => {
81+
// Validate schema structure first
82+
validateV2Schema(schema);
83+
2684
// Get all visible (non-deprecated) fields
2785
const visibleFields = getVisibleFields(schema);
2886

src/v2/mockData.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ export const mockV2Schema = {
2929
"type": "string",
3030
"anyOf": [
3131
{
32-
"$ref": "http://localhost:3000/api/v2.0/schemas/choices.json?field=patrol_activity"
32+
"oneOf": [
33+
{ "const": "routine", "title": "Routine Patrol" },
34+
{ "const": "emergency", "title": "Emergency Response" },
35+
{ "const": "investigation", "title": "Investigation" }
36+
]
3337
}
3438
]
3539
},
@@ -84,7 +88,12 @@ export const mockV2Schema = {
8488
"type": "string",
8589
"anyOf": [
8690
{
87-
"$ref": "http://localhost:3000/api/v2.0/schemas/choices.json?field=item_condition"
91+
"oneOf": [
92+
{ "const": "excellent", "title": "Excellent" },
93+
{ "const": "good", "title": "Good" },
94+
{ "const": "fair", "title": "Fair" },
95+
{ "const": "poor", "title": "Poor" }
96+
]
8897
}
8998
]
9099
}

src/v2/utils.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,26 @@ export const createControl = (
5858
break;
5959

6060
case 'CHOICE_LIST':
61-
if (uiField.inputType === 'DROPDOWN') {
62-
control.options!.format = 'dropdown';
63-
if (uiField.placeholder) {
64-
control.options!.placeholder = uiField.placeholder;
61+
// Handle multiple choice (array type) first
62+
if (property.type === 'array') {
63+
control.options!.multi = true;
64+
// For arrays, use appropriate multi-select format
65+
if (uiField.inputType === 'DROPDOWN') {
66+
control.options!.format = 'dropdown';
67+
} else if (uiField.inputType === 'LIST') {
68+
control.options!.format = 'checkbox';
69+
}
70+
} else {
71+
// Single select
72+
if (uiField.inputType === 'DROPDOWN') {
73+
control.options!.format = 'dropdown';
74+
} else if (uiField.inputType === 'LIST') {
75+
control.options!.format = 'radio';
6576
}
66-
} else if (uiField.inputType === 'LIST') {
67-
control.options!.format = 'radio';
6877
}
6978

70-
// Handle multiple choice (array type)
71-
if (property.type === 'array') {
72-
control.options!.multi = true;
79+
if (uiField.placeholder) {
80+
control.options!.placeholder = uiField.placeholder;
7381
}
7482
break;
7583

0 commit comments

Comments
 (0)