fix: Step case overwriting prevention by hypothetical ID (#396)
This commit is contained in:
@@ -60,7 +60,7 @@ export default function CaseEditor({
|
|||||||
const [testCase, setTestCase] = useState<CaseType>(defaultTestCase);
|
const [testCase, setTestCase] = useState<CaseType>(defaultTestCase);
|
||||||
const [isTitleInvalid] = useState<boolean>(false);
|
const [isTitleInvalid] = useState<boolean>(false);
|
||||||
const [isUpdating, setIsUpdating] = useState<boolean>(false);
|
const [isUpdating, setIsUpdating] = useState<boolean>(false);
|
||||||
const [plusCount, setPlusCount] = useState<number>(0);
|
const [idCounter, setIdCounter] = useState<number>(0);
|
||||||
const [isDirty, setIsDirty] = useState(false);
|
const [isDirty, setIsDirty] = useState(false);
|
||||||
const [selectedTags, setSelectedTags] = useState<{ id: number; name: string }[]>([]);
|
const [selectedTags, setSelectedTags] = useState<{ id: number; name: string }[]>([]);
|
||||||
|
|
||||||
@@ -68,9 +68,14 @@ export default function CaseEditor({
|
|||||||
useFormGuard(isDirty, messages.areYouSureLeave);
|
useFormGuard(isDirty, messages.areYouSureLeave);
|
||||||
|
|
||||||
const onPlusClick = async (newStepNo: number) => {
|
const onPlusClick = async (newStepNo: number) => {
|
||||||
|
if (!testCase.Steps) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setIsDirty(true);
|
setIsDirty(true);
|
||||||
|
const nextId = idCounter + 1;
|
||||||
const newStep: StepType = {
|
const newStep: StepType = {
|
||||||
id: plusCount,
|
// hypothetical ID
|
||||||
|
id: nextId,
|
||||||
step: '',
|
step: '',
|
||||||
result: '',
|
result: '',
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
@@ -78,66 +83,65 @@ export default function CaseEditor({
|
|||||||
caseSteps: {
|
caseSteps: {
|
||||||
stepNo: newStepNo,
|
stepNo: newStepNo,
|
||||||
},
|
},
|
||||||
uid: `uid${plusCount}`,
|
uid: `uid${nextId}`,
|
||||||
editState: 'new',
|
editState: 'new',
|
||||||
};
|
};
|
||||||
setPlusCount(plusCount + 1);
|
|
||||||
|
|
||||||
if (testCase.Steps) {
|
const updatedSteps = testCase.Steps.map((step) => {
|
||||||
const updatedSteps = testCase.Steps.map((step) => {
|
if (step.caseSteps.stepNo >= newStepNo) {
|
||||||
if (step.caseSteps.stepNo >= newStepNo) {
|
return {
|
||||||
return {
|
...step,
|
||||||
...step,
|
editState: step.editState === 'notChanged' ? 'changed' : step.editState,
|
||||||
editState: step.editState === 'notChanged' ? 'changed' : step.editState,
|
caseSteps: {
|
||||||
caseSteps: {
|
...step.caseSteps,
|
||||||
...step.caseSteps,
|
stepNo: step.caseSteps.stepNo + 1,
|
||||||
stepNo: step.caseSteps.stepNo + 1,
|
},
|
||||||
},
|
};
|
||||||
};
|
}
|
||||||
}
|
return step;
|
||||||
return step;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
updatedSteps.push(newStep);
|
updatedSteps.push(newStep);
|
||||||
|
|
||||||
setTestCase({
|
setTestCase({
|
||||||
...testCase,
|
...testCase,
|
||||||
Steps: updatedSteps,
|
Steps: updatedSteps,
|
||||||
});
|
});
|
||||||
}
|
setIdCounter(nextId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteClick = async (stepId: number) => {
|
const onDeleteClick = async (stepId: number) => {
|
||||||
setIsDirty(true);
|
setIsDirty(true);
|
||||||
|
if (!testCase.Steps) {
|
||||||
// find deletedStep's stepNo
|
return;
|
||||||
if (testCase.Steps) {
|
|
||||||
const deletedStep = testCase.Steps.find((step) => step.id === stepId);
|
|
||||||
if (!deletedStep) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const deletedStepNo = deletedStep.caseSteps.stepNo;
|
|
||||||
deletedStep.editState = 'deleted';
|
|
||||||
|
|
||||||
const updatedSteps = testCase.Steps.map((step) => {
|
|
||||||
if (step.caseSteps.stepNo > deletedStepNo) {
|
|
||||||
return {
|
|
||||||
...step,
|
|
||||||
editState: step.editState === 'notChanged' ? 'changed' : step.editState,
|
|
||||||
caseSteps: {
|
|
||||||
...step.caseSteps,
|
|
||||||
stepNo: step.caseSteps.stepNo - 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return step;
|
|
||||||
});
|
|
||||||
|
|
||||||
setTestCase({
|
|
||||||
...testCase,
|
|
||||||
Steps: updatedSteps,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
// find deletedStep's stepNo
|
||||||
|
|
||||||
|
const deletedStep = testCase.Steps.find((step) => step.id === stepId);
|
||||||
|
if (!deletedStep) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const deletedStepNo = deletedStep.caseSteps.stepNo;
|
||||||
|
deletedStep.editState = 'deleted';
|
||||||
|
|
||||||
|
const updatedSteps = testCase.Steps.map((step) => {
|
||||||
|
if (step.caseSteps.stepNo > deletedStepNo) {
|
||||||
|
return {
|
||||||
|
...step,
|
||||||
|
editState: step.editState === 'notChanged' ? 'changed' : step.editState,
|
||||||
|
caseSteps: {
|
||||||
|
...step.caseSteps,
|
||||||
|
stepNo: step.caseSteps.stepNo - 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return step;
|
||||||
|
});
|
||||||
|
|
||||||
|
setTestCase({
|
||||||
|
...testCase,
|
||||||
|
Steps: updatedSteps,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrop = (event: DragEvent<HTMLElement>) => {
|
const handleDrop = (event: DragEvent<HTMLElement>) => {
|
||||||
@@ -201,18 +205,20 @@ export default function CaseEditor({
|
|||||||
changeStep.editState = 'changed';
|
changeStep.editState = 'changed';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testCase.Steps) {
|
if (!testCase.Steps) {
|
||||||
setTestCase({
|
return;
|
||||||
...testCase,
|
|
||||||
Steps: testCase.Steps.map((step) => {
|
|
||||||
if (step.id === stepId) {
|
|
||||||
return changeStep;
|
|
||||||
} else {
|
|
||||||
return step;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTestCase({
|
||||||
|
...testCase,
|
||||||
|
Steps: testCase.Steps.map((step) => {
|
||||||
|
if (step.id === stepId) {
|
||||||
|
return changeStep;
|
||||||
|
} else {
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -223,6 +229,11 @@ export default function CaseEditor({
|
|||||||
data.Steps.forEach((step: StepType) => {
|
data.Steps.forEach((step: StepType) => {
|
||||||
step.editState = 'notChanged';
|
step.editState = 'notChanged';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// set idCounter to the max step id to avoid id conflict for new steps
|
||||||
|
// id is not reflected on database
|
||||||
|
const maxStepId = data.Steps.reduce((maxId: number, step: StepType) => Math.max(maxId, step.id), 0);
|
||||||
|
setIdCounter(maxStepId);
|
||||||
setTestCase(data);
|
setTestCase(data);
|
||||||
if (data.Tags) {
|
if (data.Tags) {
|
||||||
setSelectedTags(Array.isArray(data.Tags) ? data.Tags : []);
|
setSelectedTags(Array.isArray(data.Tags) ? data.Tags : []);
|
||||||
|
|||||||
Reference in New Issue
Block a user