Skip to content

Commit b1a217e

Browse files
authored
Issue #801: Added regex pattern to ValueSet Name, Value Name, Entity/Attribute Name & UniqueName fields and custo… (#822)
…m error checking for those fields
2 parents 074a094 + c45cc2a commit b1a217e

2 files changed

Lines changed: 53 additions & 6 deletions

File tree

frontends/mdr-frontend/src/components/Dialog/Dialog.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ export interface DialogField {
4444
help?: string; // potential help text
4545
accept?: string;
4646
inputMode?: InputMode;
47-
pattern?: string;
47+
patternRegex?: string;
48+
patternDeny?: string;
49+
patternErr?: string;
4850
}
4951

5052
export interface DialogItem {
@@ -92,6 +94,10 @@ export const CrudDialog: React.FC<CrudDialogProps> = ({
9294
nextParams.BaseDataModelId = null;
9395
}
9496
}
97+
// # Disabled pattern validation here; now handled on handleCreateOrEdit
98+
// if (field.pattern && createParams[field.name] && !new RegExp(field.pattern).test(createParams[field.name])) {
99+
// setCreateError(`The following fields have invalid values:\n > ${field.patternErr}`);
100+
// }
95101
return nextParams;
96102
});
97103
};
@@ -111,6 +117,16 @@ export const CrudDialog: React.FC<CrudDialogProps> = ({
111117
setCreateError(`Please complete all required fields: ${missingFields.join(", ")}`);
112118
return;
113119
}
120+
121+
let patternErrors: any = [];
122+
const regexFields = fields.filter((f) => f.patternRegex && createParams[f.name] && !new RegExp(f.patternRegex).test(createParams[f.name]));
123+
patternErrors = [...patternErrors, ...regexFields];
124+
const deniedFields = fields.filter((f) => f.patternDeny && createParams[f.name] && new RegExp(f.patternDeny).test(createParams[f.name]));
125+
patternErrors = [...patternErrors, ...deniedFields];
126+
if (patternErrors.length) {
127+
setCreateError(`The following fields have invalid values:\n > ${patternErrors.map((f: any) => f.patternErr).join("\n > ")}`);
128+
return;
129+
}
114130

115131
setDisableSubmitForm(true);
116132
if (isEditMode && itemToEdit) {
@@ -228,7 +244,7 @@ export const CrudDialog: React.FC<CrudDialogProps> = ({
228244
{createError && (
229245
<>
230246
<br /><br />
231-
<Text color="red" size="2" mb="3">
247+
<Text color="red" size="2" mb="3" style={{ whiteSpace: "pre-line" }}>
232248
{createError}
233249
</Text>
234250
</>
@@ -297,7 +313,8 @@ export const CrudDialog: React.FC<CrudDialogProps> = ({
297313
placeholder={`Enter ${field.label.toLowerCase()}`}
298314
onChange={(e) => handleFieldValueChange(field, e.target.value) }
299315
inputMode={field.inputMode}
300-
pattern={field.pattern}
316+
pattern={field.patternRegex}
317+
title={field.patternErr ?? ""}
301318
readOnly={field.readOnly || (isEditMode && field.name === "CreationDate")}
302319
/>
303320
)}

frontends/mdr-frontend/src/components/ModelExplorer/CreateOptFields.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { DialogField } from "../Dialog/Dialog";
22

3+
4+
const PatternDenyRegex = "[ ,:~]";
5+
const PatternDenyErr = " cannot contain spaces, commas, colons, or tildes.";
36
const capitalize = (s: string): string => { return s?.length ? s.charAt(0).toUpperCase() + s.slice(1) : ""; }
47

58
/** Dev Note: Once we get actual user data we should use that for Contributor and ContributorOrganization */
@@ -13,12 +16,21 @@ export const entityCreateFields = (model: any): DialogField[] => {
1316
hidden: true,
1417
defaultValue: model?.Id,
1518
},
16-
{ name: "Name", type: "text" as const, label: "Name", required: true },
19+
{
20+
name: "Name",
21+
type: "text" as const,
22+
label: "Name",
23+
required: true,
24+
patternDeny: PatternDenyRegex,
25+
patternErr: "Name" + PatternDenyErr,
26+
},
1727
{
1828
name: "UniqueName",
1929
type: "text" as const,
2030
label: "Unique Name",
2131
required: true,
32+
patternDeny: PatternDenyRegex,
33+
patternErr: "Unique Name" + PatternDenyErr,
2234
},
2335
{ name: "Description", type: "text" as const, label: "Description" },
2436
{
@@ -90,12 +102,21 @@ export const attributeCreateFields = (model: any, valueSetId: string | number |
90102
hidden: true,
91103
defaultValue: valueSetId?.toString(),
92104
},
93-
{ name: "Name", type: "text" as const, label: "Name", required: true },
105+
{
106+
name: "Name",
107+
type: "text" as const,
108+
label: "Name",
109+
required: true,
110+
patternDeny: PatternDenyRegex,
111+
patternErr: "Name" + PatternDenyErr,
112+
},
94113
{
95114
name: "UniqueName",
96115
type: "text" as const,
97116
label: "Unique Name",
98117
required: true,
118+
patternDeny: PatternDenyRegex,
119+
patternErr: "Unique Name" + PatternDenyErr,
99120
},
100121
{
101122
name: "DataType",
@@ -173,7 +194,14 @@ export const valueSetCreateFields = (model: any): DialogField[] => {
173194
hidden: true,
174195
defaultValue: model?.Id,
175196
},
176-
{ name: "Name", type: "text" as const, label: "Name", required: true },
197+
{
198+
name: "Name",
199+
type: "text" as const,
200+
label: "Name",
201+
required: true,
202+
patternDeny: PatternDenyRegex,
203+
patternErr: "Name" + PatternDenyErr,
204+
},
177205
{ name: "Description", type: "text" as const, label: "Description" },
178206
{
179207
name: "Use Considerations",
@@ -223,6 +251,8 @@ export const valueCreateFields = (model: any): DialogField[] => {
223251
type: "text" as const,
224252
label: "Value Name",
225253
required: true,
254+
patternDeny: PatternDenyRegex,
255+
patternErr: "Value Name" + PatternDenyErr,
226256
},
227257
{ name: "Description", type: "text" as const, label: "Description" },
228258
{

0 commit comments

Comments
 (0)