-
-
Notifications
You must be signed in to change notification settings - Fork 734
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Project select bug with duplicate values (#6405)
Project select fix for Executive Dashboard and Playground Extract the select to it's own component and move to `common` Re-use for both Dashboard and Playground Adds the id in parenthesis when there are duplicate names <img width="1406" alt="Screenshot 2024-03-01 at 12 04 22" src="https://github.com/Unleash/unleash/assets/104830839/379ea11f-d627-493e-8088-a739d58fba61"> <img width="1434" alt="Screenshot 2024-03-01 at 12 36 46" src="https://github.com/Unleash/unleash/assets/104830839/9c5cf863-002c-4630-ac3a-4a869303a308"> --------- Signed-off-by: andreas-unleash <[email protected]>
- Loading branch information
1 parent
a4a604a
commit 7b67f21
Showing
5 changed files
with
198 additions
and
214 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
frontend/src/component/common/ProjectSelect/ProjectSelect.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { ComponentProps, Dispatch, SetStateAction, VFC } from 'react'; | ||
import { Autocomplete, SxProps, TextField } from '@mui/material'; | ||
import { renderOption } from 'component/playground/Playground/PlaygroundForm/renderOption'; | ||
import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||
|
||
interface IOption { | ||
label: string; | ||
id: string; | ||
} | ||
|
||
export const allOption = { label: 'ALL', id: '*' }; | ||
|
||
interface IProjectSelectProps { | ||
selectedProjects: string[]; | ||
onChange: Dispatch<SetStateAction<string[]>>; | ||
dataTestId?: string; | ||
sx?: SxProps; | ||
disabled?: boolean; | ||
} | ||
|
||
function findAllIndexes(arr: string[], name: string): number[] { | ||
const indexes: number[] = []; | ||
arr.forEach((currentValue, index) => { | ||
if (currentValue === name) { | ||
indexes.push(index); | ||
} | ||
}); | ||
return indexes; | ||
} | ||
|
||
export const ProjectSelect: VFC<IProjectSelectProps> = ({ | ||
selectedProjects, | ||
onChange, | ||
dataTestId, | ||
sx, | ||
disabled, | ||
}) => { | ||
const { projects: availableProjects } = useProjects(); | ||
|
||
const projectNames = availableProjects.map(({ name }) => name); | ||
|
||
const projectsOptions = [ | ||
allOption, | ||
...availableProjects.map(({ name, id }) => { | ||
const indexes = findAllIndexes(projectNames, name); | ||
const isDuplicate = indexes.length > 1; | ||
|
||
return { | ||
label: isDuplicate ? `${name} - (${id})` : name, | ||
id, | ||
}; | ||
}), | ||
]; | ||
|
||
const isAllProjects = | ||
selectedProjects && | ||
(selectedProjects.length === 0 || | ||
(selectedProjects.length === 1 && selectedProjects[0] === '*')); | ||
|
||
const onProjectsChange: ComponentProps<typeof Autocomplete>['onChange'] = ( | ||
event, | ||
value, | ||
reason, | ||
) => { | ||
const newProjects = value as IOption | IOption[]; | ||
if (reason === 'clear' || newProjects === null) { | ||
return onChange([allOption.id]); | ||
} | ||
if (Array.isArray(newProjects)) { | ||
if (newProjects.length === 0) { | ||
return onChange([allOption.id]); | ||
} | ||
if ( | ||
newProjects.find(({ id }) => id === allOption.id) !== undefined | ||
) { | ||
return onChange([allOption.id]); | ||
} | ||
return onChange(newProjects.map(({ id }) => id)); | ||
} | ||
if (newProjects.id === allOption.id) { | ||
return onChange([allOption.id]); | ||
} | ||
|
||
return onChange([newProjects.id]); | ||
}; | ||
|
||
return ( | ||
<Autocomplete | ||
disablePortal | ||
id='projects' | ||
limitTags={3} | ||
multiple={!isAllProjects} | ||
options={projectsOptions} | ||
sx={sx} | ||
renderInput={(params) => <TextField {...params} label='Projects' />} | ||
renderOption={renderOption} | ||
getOptionLabel={({ label }) => label} | ||
disableCloseOnSelect | ||
size='small' | ||
disabled={disabled} | ||
value={ | ||
isAllProjects | ||
? allOption | ||
: projectsOptions.filter(({ id }) => | ||
selectedProjects.includes(id), | ||
) | ||
} | ||
onChange={onProjectsChange} | ||
data-testid={dataTestId ? dataTestId : 'PROJECT_SELECT'} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 0 additions & 113 deletions
113
frontend/src/component/executiveDashboard/ProjectSelect/ProjectSelect.tsx
This file was deleted.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
frontend/src/component/executiveDashboard/hooks/useFilteredTrends.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.