From e0ce2f13a9683aafb8d2042363ea0a9a50661e94 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Sun, 30 Jun 2024 17:04:24 +0000 Subject: [PATCH] fix(web): fix SectionSelect setting wrong value SectionSelect was trying to set default value. This introduced an issue when provided value was replaced with default one. Settings defaults is not a Select's concern so it's moved out of component now. --- web/src/components/CompareInputForm.tsx | 48 +++++++++++++++++------ web/src/components/SectionSelect.tsx | 52 +++++++++++-------------- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/web/src/components/CompareInputForm.tsx b/web/src/components/CompareInputForm.tsx index 9e90baf0..b07c562b 100644 --- a/web/src/components/CompareInputForm.tsx +++ b/web/src/components/CompareInputForm.tsx @@ -5,7 +5,7 @@ * */ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Button, Card } from "react-daisyui"; import SectionSelect from "../components/SectionSelect"; import { @@ -14,21 +14,41 @@ import { faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import _ from "lodash"; type CompareInputFormProps = { sections: Section[]; onSubmit: (sections: Section[]) => void; }; -export default function CompareInputForm(props: CompareInputFormProps) { - const [selectedSections, setSelectedSections] = useState([{}]); +export default function CompareInputForm({ + sections, + onSubmit +}: CompareInputFormProps) { + const [selectedSections, setSelectedSections] = useState([]); + + useEffect(() => { + setSelectedSections((prevSelectedSections) => { + const newSelectedSections = prevSelectedSections.map((section) => { + if (_.isEmpty(section)) { + return { ...sections[0] }; + } + return section; + }); + return newSelectedSections; + }); + }, [selectedSections, sections, setSelectedSections]); const updateSectionAt = (index: number, update: any) => { - setSelectedSections((prevSections) => [ - ...prevSections.slice(0, index), - { ...props.sections[0], ...prevSections[index], ...update }, - ...prevSections.slice(index + 1) - ]); + setSelectedSections((prevSections) => + prevSections + ? [ + ...prevSections.slice(0, index), + { ...sections[0], ...prevSections[index], ...update }, + ...prevSections.slice(index + 1) + ] + : [{ ...sections[0], ...update }] + ); }; return ( @@ -38,13 +58,13 @@ export default function CompareInputForm(props: CompareInputFormProps) { Compare sections Choose sections you wish to compare. - {selectedSections.map((section, index) => ( + {selectedSections?.map((section, index) => (
updateSectionAt(index, section) @@ -88,7 +108,13 @@ export default function CompareInputForm(props: CompareInputFormProps) { size="sm" color="accent" onClick={() => { - props.onSubmit(selectedSections); + if ( + !selectedSections || + selectedSections?.length < 2 + ) { + return; + } + onSubmit(selectedSections); }} > & { onSelected?: (section: Section) => void; disabled?: boolean | boolean[]; }; - -export default function SectionSelect(props: SectionSelectorProps) { +export default function SectionSelect({ + sections, + selectedSection, + onSelected, + disabled +}: SectionSelectorProps) { const updateSection = useCallback( (update: any) => { - if (props.onSelected) - props.onSelected({ ...props.selectedSection, ...update }); + if (onSelected) onSelected({ ...selectedSection, ...update }); }, - [props.onSelected, props.sections] + [onSelected, selectedSection] ); - useEffect(() => { - if (props.onSelected) - props.onSelected({ - ...props.sections[0], - ...props.selectedSection - }); - }, [props.sections]); - interface IOption { value?: string; label?: string; @@ -121,18 +116,17 @@ export default function SectionSelect(props: SectionSelectorProps) { const isDisabled = useCallback( (n: number) => { - if (props.disabled == undefined) { + if (disabled == undefined) { return false; } - if (typeof props.disabled == "boolean") { - return props.disabled as boolean; + if (typeof disabled == "boolean") { + return disabled as boolean; } return ( - (props.disabled as boolean[]).length > n && - (props.disabled as boolean[])[n] + (disabled as boolean[]).length > n && (disabled as boolean[])[n] ); }, - [props.disabled] + [disabled] ); return ( @@ -141,18 +135,18 @@ export default function SectionSelect(props: SectionSelectorProps) { unstyled={true} components={makeComponents(faCodeBranch)} styles={makeStyles(isDisabled(0))} - value={makeValue(props.selectedSection?.branch)} - options={SectionUtils.branches(props.sections).map(makeValue)} + value={makeValue(selectedSection?.branch)} + options={SectionUtils.branches(sections).map(makeValue)} onChange={(value) => updateSection({ branch: value?.value })} /> unstyled={true} components={makeComponents(faCubes)} styles={makeStyles(isDisabled(1))} - value={makeValue(props.selectedSection?.repository)} + value={makeValue(selectedSection?.repository)} options={SectionUtils.reposForBranch( - props.sections, - props.selectedSection?.branch + sections, + selectedSection?.branch ).map(makeValue)} onChange={(value) => updateSection({ repository: value?.value }) @@ -162,11 +156,11 @@ export default function SectionSelect(props: SectionSelectorProps) { unstyled={true} components={makeComponents(faMicrochip)} styles={makeStyles(isDisabled(2))} - value={makeValue(props.selectedSection?.architecture)} + value={makeValue(selectedSection?.architecture)} options={SectionUtils.architecturesForBranchAndRepo( - props.sections, - props.selectedSection?.branch, - props.selectedSection?.repository + sections, + selectedSection?.branch, + selectedSection?.repository ).map(makeValue)} onChange={(value) => updateSection({ architecture: value?.value })