Skip to content

Commit f23e699

Browse files
committed
Validate client parameters.
1 parent 5f51558 commit f23e699

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

tools/diagnostics-app/src/app/views/client-params.tsx

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,28 @@ const typeForValue = (value: unknown) => {
2222
return typeof value;
2323
};
2424

25-
const jsonToObjectArray = (json: Object) => {
25+
const jsonToObjectArray = (json: Object): ParameterEntry[] => {
2626
const entrySet = Object.entries(json);
2727
return entrySet.map(([key, value]) => {
28-
const type = typeForValue(value);
28+
const type = typeForValue(value) as ParameterType;
2929
return {
3030
key,
3131
// Only arrays and objects need special cases here since JS will take care of the rest.
32-
value: type === 'array' || type === 'object' ? JSON.stringify(value) : value,
32+
value: type === 'array' || type === 'object' ? JSON.stringify(value) : String(value),
3333
type
3434
};
3535
});
3636
};
3737

38+
type ParameterType = 'string' | 'number' | 'boolean' | 'array' | 'object';
39+
40+
interface ParameterEntry {
41+
key: string;
42+
type: ParameterType;
43+
value: string;
44+
error?: string;
45+
}
46+
3847
// A simple set of mappers for converting a string to the correct value for saving
3948
const CONVERTERS = {
4049
string: (v: string) => v,
@@ -47,50 +56,69 @@ const CONVERTERS = {
4756
function ClientParamsPage() {
4857
const [params, setParams] = useState(jsonToObjectArray(getParams()));
4958

50-
const convertValueForSave = (t: 'string' | 'number' | 'boolean' | 'array' | 'object', stringValue: string) =>
51-
CONVERTERS[t](stringValue);
59+
const convertValueForSave = (t: ParameterType, stringValue: string) => CONVERTERS[t](stringValue);
5260

5361
const onSubmit = (e: FormEvent<HTMLFormElement>) => {
5462
e.preventDefault();
5563
e.stopPropagation();
5664

57-
const newParams = params.reduce(
58-
(curr: any, item: { key: any; type: 'string' | 'number' | 'boolean' | 'array' | 'object'; value: string }) => ({
59-
...curr,
60-
[`${item.key}`]: convertValueForSave(item.type, item.value)
61-
}),
62-
{}
63-
);
64-
setParamsGlobal(newParams);
65+
try {
66+
const newParams = params.reduce<Record<string, any>>(
67+
(curr: any, item: { key: string; type: string; value: string }) => ({
68+
...curr,
69+
[`${item.key}`]: convertValueForSave(item.type as ParameterType, item.value)
70+
}),
71+
{}
72+
);
73+
setParamsGlobal(newParams);
74+
} catch (e) {}
6575
};
6676

67-
const replace = (idx: number, val: any) => setParams((a: any[]) => a.map((entity, i) => (i === idx ? val : entity)));
77+
const validate = (val: ParameterEntry) => {
78+
if (val.type == 'object' || val.type == 'array') {
79+
try {
80+
JSON.parse(val.value);
81+
return val;
82+
} catch (e: any) {
83+
return {
84+
...val,
85+
error: e.message
86+
};
87+
}
88+
} else {
89+
return val;
90+
}
91+
};
92+
93+
const replace = (idx: number, val: ParameterEntry) => {
94+
setParams((a: any[]) => a.map((entity, i) => (i === idx ? validate(val) : entity)));
95+
};
6896

6997
const removeIdx = (idx: number) =>
7098
setParams((a: any[]) => a.map((entity, i) => i !== idx && entity).filter((entity) => entity !== false));
7199

72100
const addRow = () => {
73-
setParams((a: any[]) => [...a, { key: '', value: '' }]);
101+
setParams((a: any[]) => [...a, { key: '', value: '', type: 'string' }]);
74102
};
75103

76-
const changeValue = (idx: number, value: string, currKey: string, type: string) => {
104+
const changeValue = (idx: number, value: string, currKey: string, type: ParameterType) => {
77105
replace(idx, { key: currKey, value, type });
78106
};
79107

80-
const changeKey = (idx: number, key: string, currValue: unknown, type: string) => {
108+
const changeKey = (idx: number, key: string, currValue: string, type: ParameterType) => {
81109
replace(idx, { key, value: currValue, type });
82110
};
83111

84-
const changeType = (idx: number, key: string, value: unknown, newType: string) => {
112+
const changeType = (idx: number, key: string, value: string, newType: ParameterType) => {
85113
replace(idx, { key, value, type: newType });
86114
};
87115

88116
return (
89117
<NavigationPage title="Client Parameters">
90118
<S.MainContainer>
91119
<form onSubmit={onSubmit}>
92-
{params.map(({ key, value, type }: { key: string; value: string; type: string }, idx: number) => (
93-
<S.CenteredGrid container>
120+
{params.map(({ key, value, type, error }, idx: number) => (
121+
<S.CenteredGrid container key={idx}>
94122
<S.CenteredGrid item xs={12} md={10}>
95123
<TextField
96124
label="Key"
@@ -103,6 +131,8 @@ function ClientParamsPage() {
103131
label="Value"
104132
value={value}
105133
sx={{ margin: '10px' }}
134+
error={!!error}
135+
title={error}
106136
onChange={(v: { target: { value: string } }) => changeValue(idx, v.target.value, key, type)}
107137
/>
108138
<FormControl sx={{ margin: '10px', width: '125px', minWidth: '95px' }}>
@@ -111,7 +141,9 @@ function ClientParamsPage() {
111141
labelId="demo-simple-select-label"
112142
value={type}
113143
label="Type"
114-
onChange={(v: { target: { value: string } }) => changeType(idx, key, value, v.target.value)}>
144+
onChange={(v: { target: { value: string } }) =>
145+
changeType(idx, key, value, v.target.value as ParameterType)
146+
}>
115147
<MenuItem value={'string'}>String</MenuItem>
116148
<MenuItem value={'number'}>Number</MenuItem>
117149
<MenuItem value={'array'}>Array</MenuItem>
@@ -131,7 +163,7 @@ function ClientParamsPage() {
131163
</IconButton>
132164
</S.CenteredGrid>
133165
<Button type="submit" sx={{ margin: '10px' }} variant="contained">
134-
Submit
166+
Save
135167
</Button>
136168
</form>
137169
</S.MainContainer>

0 commit comments

Comments
 (0)