Skip to content

Commit

Permalink
🐛 Address targets falling out of sync after label selection changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 committed Jul 17, 2024
1 parent 2ee9fe9 commit ae233dc
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 58 deletions.
40 changes: 26 additions & 14 deletions client/src/app/pages/applications/analysis-wizard/set-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ import { DEFAULT_SELECT_MAX_HEIGHT } from "@app/Constants";
import { useFetchTargets } from "@app/queries/targets";
import defaultSources from "./sources";
import { QuestionCircleIcon } from "@patternfly/react-icons";
import {
findLabelBySelector,
isLabelInFormLabels,
updateSelectedTargetsBasedOnLabels,
} from "./utils";

export const SetOptions: React.FC = () => {
const { t } = useTranslation();
Expand All @@ -41,6 +46,7 @@ export const SetOptions: React.FC = () => {
excludedRulesTags,
autoTaggingEnabled,
advancedAnalysisEnabled,
selectedTargets,
} = watch();

const [isSelectTargetsOpen, setSelectTargetsOpen] = React.useState(false);
Expand Down Expand Up @@ -119,27 +125,33 @@ export const SetOptions: React.FC = () => {
isOpen={isSelectTargetsOpen}
onSelect={(_, selection) => {
const selectionWithLabelSelector = `konveyor.io/target=${selection}`;
const matchingLabel =
defaultTargetsAndTargetsLabels.find(
(label) => label.label === selectionWithLabelSelector
) || "";

const formLabelLabels = formLabels.map(
(formLabel) => formLabel.label
const matchingLabel = findLabelBySelector(
defaultTargetsAndTargetsLabels,
selectionWithLabelSelector
);
let updatedFormLabels = [];
if (
matchingLabel &&
!formLabelLabels.includes(matchingLabel.label)
!isLabelInFormLabels(formLabels, matchingLabel.label)
) {
onChange([...formLabels, matchingLabel]);
updatedFormLabels = [...formLabels, matchingLabel];
onChange(updatedFormLabels);
} else {
onChange(
formLabels.filter(
(formLabel) =>
formLabel.label !== selectionWithLabelSelector
)
updatedFormLabels = formLabels.filter(
(formLabel) =>
formLabel.label !== selectionWithLabelSelector
);
onChange(updatedFormLabels);
}

const updatedSelectedTargets =
updateSelectedTargetsBasedOnLabels(
updatedFormLabels,
selectedTargets,
targets
);
setValue("selectedTargets", updatedSelectedTargets);

onBlur();
setSelectTargetsOpen(!isSelectTargetsOpen);
}}
Expand Down
49 changes: 6 additions & 43 deletions client/src/app/pages/applications/analysis-wizard/set-targets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { useFetchTargets } from "@app/queries/targets";
import { Application, TagCategory, Target } from "@app/api/models";
import { useFetchTagCategories } from "@app/queries/tags";
import { SimpleSelectCheckbox } from "@app/components/SimpleSelectCheckbox";
import { getUpdatedFormLabels, updateSelectedTargets } from "./utils";
interface SetTargetsProps {
applications: Application[];
}
Expand Down Expand Up @@ -101,61 +102,23 @@ export const SetTargets: React.FC<SetTargetsProps> = ({ applications }) => {
selectedLabelName: string,
target: Target
) => {
const updatedSelectedTargets = getUpdatedSelectedTargets(
isSelecting,
target
const updatedSelectedTargets = updateSelectedTargets(
target.id,
selectedTargets
);

const updatedFormLabels = getUpdatedFormLabels(
isSelecting,
selectedLabelName,
target
target,
formLabels
);

setValue("formLabels", updatedFormLabels);
setValue("selectedTargets", updatedSelectedTargets);
};

const getUpdatedSelectedTargets = (isSelecting: boolean, target: Target) => {
const { selectedTargets } = values;
if (isSelecting) {
return [...selectedTargets, target.id];
}
return selectedTargets.filter((id) => id !== target.id);
};

const getUpdatedFormLabels = (
isSelecting: boolean,
selectedLabelName: string,
target: Target
) => {
const { formLabels } = values;
if (target.custom) {
const customTargetLabelNames = target.labels?.map((label) => label.name);
const otherSelectedLabels = formLabels?.filter(
(formLabel) => !customTargetLabelNames?.includes(formLabel.name)
);
return isSelecting && target.labels
? [...otherSelectedLabels, ...target.labels]
: otherSelectedLabels;
} else {
const otherSelectedLabels = formLabels?.filter(
(formLabel) => formLabel.name !== selectedLabelName
);
if (isSelecting) {
const matchingLabel = target.labels?.find(
(label) => label.name === selectedLabelName
);
return matchingLabel
? [...otherSelectedLabels, matchingLabel]
: otherSelectedLabels;
}
return otherSelectedLabels;
}
};

const allProviders = targets.flatMap((target) => target.provider);

const languageOptions = Array.from(new Set(allProviders));

return (
Expand Down
79 changes: 78 additions & 1 deletion client/src/app/pages/applications/analysis-wizard/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { Application } from "@app/api/models";
import { Application, Target, TargetLabel } from "@app/api/models";
import { AnalysisMode, ANALYSIS_MODES } from "./schema";

export const isApplicationBinaryEnabled = (
Expand Down Expand Up @@ -60,3 +60,80 @@ export const useAnalyzableApplicationsByMode = (
),
[applications]
);

export const updateSelectedTargets = (
targetId: number,
selectedTargetIDs: number[]
) => {
const isSelected = selectedTargetIDs.includes(targetId);
return isSelected
? selectedTargetIDs.filter((id) => id !== targetId)
: [...selectedTargetIDs, targetId];
};

export const getUpdatedFormLabels = (
isSelecting: boolean,
selectedLabelName: string,
target: Target,
formLabels: TargetLabel[]
) => {
if (target.custom) {
const customTargetLabelNames = target.labels?.map((label) => label.name);
const otherSelectedLabels = formLabels?.filter(
(formLabel) => !customTargetLabelNames?.includes(formLabel.name)
);
return isSelecting && target.labels
? [...otherSelectedLabels, ...target.labels]
: otherSelectedLabels;
} else {
const otherSelectedLabels = formLabels?.filter(
(formLabel) => formLabel.name !== selectedLabelName
);
if (isSelecting) {
const matchingLabel = target.labels?.find(
(label) => label.name === selectedLabelName
);
return matchingLabel
? [...otherSelectedLabels, matchingLabel]
: otherSelectedLabels;
}
return otherSelectedLabels;
}
};
export const findLabelBySelector = (labels: TargetLabel[], selector: string) =>
labels.find((label) => label.label === selector) || "";

export const isLabelInFormLabels = (formLabels: TargetLabel[], label: string) =>
formLabels.some((formLabel) => formLabel.label === label);

export const labelToTargetId = (labelName: string, targets: Target[]) => {
const target = targets.find(
(t) => t.labels?.some((l) => l.name === labelName)
);
return target ? target.id : null;
};

export const updateSelectedTargetsBasedOnLabels = (
currentFormLabels: TargetLabel[],
selectedTargets: number[],
targets: Target[]
) => {
const newSelectedTargets = currentFormLabels.reduce(
(acc: number[], formLabel) => {
const targetId = labelToTargetId(formLabel.name, targets);
if (targetId && !acc.includes(targetId)) {
acc.push(targetId);
}
return acc;
},
[]
);

const filteredSelectedTargets = selectedTargets.filter((targetId) =>
currentFormLabels.some(
(formLabel) => labelToTargetId(formLabel.name, targets) === targetId
)
);

return [...new Set([...newSelectedTargets, ...filteredSelectedTargets])];
};

0 comments on commit ae233dc

Please sign in to comment.