Skip to content

Commit

Permalink
(fix) O3-4442: Duplicate Subquestion IDs in ObsGroup should trigger v…
Browse files Browse the repository at this point in the history
…alidation (#392)

* prevent duplicate subquestion IDs in obsGroup using sibling-based check

* check for duplicate in sub questions

* check for duplicate in sub questions

---------

Co-authored-by: Nethmi Rodrigo <[email protected]>
  • Loading branch information
Bharath-K-Shetty and NethmiRodrigo authored Feb 13, 2025
1 parent 023276a commit f615d65
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ const Question: React.FC<QuestionProps> = ({ checkIfQuestionIdExists }) => {
setFormField({ ...formField, id: camelCasedLabel });
};

const isQuestionIdValid = useCallback(() => {
const isQuestionIdDuplicate = useCallback(() => {
return checkIfQuestionIdExists(formField.id);
}, [formField.id, checkIfQuestionIdExists]);

return (
<>
<TextInput
id="questionId"
invalid={formField?.id ? isQuestionIdValid() : false}
invalid={!!formField?.id && isQuestionIdDuplicate()}
invalidText={t('questionIdExists', 'This question ID already exists in your schema')}
labelText={
<div className={styles.questionIdLabel}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,32 @@ const QuestionModalContent: React.FC<QuestionModalProps> = ({
const { t } = useTranslation();
const { formField, setFormField } = useFormField();

const getAllQuestionIds = useCallback((questions?: FormField[]): string[] => {
if (!questions) return [];
return flattenDeep(questions.map((question) => [question.id, getAllQuestionIds(question.questions)]));
}, []);

const checkIfQuestionIdExists = useCallback(
(idToTest: string): boolean => {
if (formFieldProp) return false;
const nestedIds = schema?.pages?.map((page) => {
return page?.sections?.map((section) => {
return section?.questions?.map((question) => {
question.questions?.map((nestedQuestion) => {
return nestedQuestion.id;
});
return question.id;
});
});
});
const questionIds: Array<string> = flattenDeep(nestedIds);
return questionIds.includes(idToTest);
// Get all IDs from the schema
const schemaIds: string[] =
schema?.pages?.flatMap((page) => page?.sections?.flatMap((section) => getAllQuestionIds(section.questions))) ||
[];

// Get all IDs from the current formField's questions array
const formFieldIds: string[] = formField?.questions ? getAllQuestionIds(formField.questions) : [];

// Combine both arrays, along with the parent question ID and count occurrences of the ID
const allIds = [...schemaIds, ...formFieldIds];
if (!formFieldProp || formFieldProp.id !== formField.id) {
allIds.push(formField.id);
}
const occurrences = allIds.filter((id) => id === idToTest).length;

// Return true if ID occurs more than once
return occurrences > 1;
},
[formFieldProp, schema],
[schema, getAllQuestionIds, formField, formFieldProp],
);

const addObsGroupQuestion = useCallback(() => {
Expand Down Expand Up @@ -180,7 +189,7 @@ const QuestionModalContent: React.FC<QuestionModalProps> = ({
disabled={
!formField ||
!formField.id ||
checkIfQuestionIdExists(formField.id) ||
(!formField.questions && checkIfQuestionIdExists(formField.id)) ||
!formField.questionOptions?.rendering
}
onClick={saveQuestion}
Expand Down

0 comments on commit f615d65

Please sign in to comment.