1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-09 15:55:23 +02:00

refactor(ui): replace ng selectors with react-select [EE-3608] (#7203)

Co-authored-by: LP B <xAt0mZ@users.noreply.github.com>
This commit is contained in:
Chaim Lev-Ari 2022-09-21 10:10:58 +03:00 committed by GitHub
parent 1e21961e6a
commit ceaee4e175
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 1188 additions and 625 deletions

View file

@ -0,0 +1,84 @@
import { User as UserIcon, Users as TeamIcon } from 'react-feather';
import { OptionProps, components, MultiValueGenericProps } from 'react-select';
import { Select } from '@@/form-components/ReactSelect';
type Option = { Type: 'user' | 'team'; Id: number; Name: string };
interface Props {
value: Option[];
onChange(value: readonly Option[]): void;
options: Option[];
}
export function PorAccessManagementUsersSelector({
options,
value,
onChange,
}: Props) {
return (
<div className="form-group">
<label
className="col-sm-3 col-lg-2 control-label text-left"
htmlFor="users-selector"
>
Select user(s) and/or team(s)
</label>
<div className="col-sm-9 col-lg-4">
{options.length === 0 ? (
<span className="small text-muted">No users or teams available.</span>
) : (
<Select
isMulti
getOptionLabel={(option) => option.Name}
getOptionValue={(option) => `${option.Id}-${option.Type}`}
options={options}
value={value}
closeMenuOnSelect={false}
onChange={onChange}
data-cy="component-selectUser"
inputId="users-selector"
placeholder="Select one or more users and/or teams"
components={{ MultiValueLabel, Option: OptionComponent }}
/>
)}
</div>
</div>
);
}
function isOption(option: unknown): option is Option {
return !!option && typeof option === 'object' && 'Type' in option;
}
function OptionComponent({ data, ...props }: OptionProps<Option, true>) {
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<components.Option data={data} {...props}>
{isOption(data) && <Label option={data} />}
</components.Option>
);
}
function MultiValueLabel({
data,
...props
}: MultiValueGenericProps<Option, true>) {
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<components.MultiValueLabel data={data} {...props}>
{isOption(data) && <Label option={data} />}
</components.MultiValueLabel>
);
}
function Label({ option }: { option: Option }) {
const Icon = option.Type === 'user' ? UserIcon : TeamIcon;
return (
<div className="flex gap-1 items-center">
<Icon />
<span>{option.Name}</span>
</div>
);
}

View file

@ -0,0 +1,33 @@
import { Team } from '@/react/portainer/users/teams/types';
import { Select } from '@@/form-components/ReactSelect';
interface Props {
value: Team[];
onChange(value: readonly Team[]): void;
options: Team[];
inputId?: string;
}
// to be removed with the angularjs app/portainer/components/accessControlForm
export function PorAccessControlFormTeamSelector({
value,
onChange,
options,
inputId,
}: Props) {
return (
<Select
isMulti
getOptionLabel={(option) => option.Name}
getOptionValue={(option) => String(option.Id)}
options={options}
value={value}
closeMenuOnSelect={false}
onChange={onChange}
data-cy="portainer-selectTeamAccess"
inputId={inputId}
placeholder="Select one or more teams"
/>
);
}

View file

@ -0,0 +1,33 @@
import { User } from '@/portainer/users/types';
import { Select } from '@@/form-components/ReactSelect';
interface Props {
value: User[];
onChange(value: readonly User[]): void;
options: User[];
inputId?: string;
}
// to be removed with the angularjs app/portainer/components/accessControlForm
export function PorAccessControlFormUserSelector({
value,
onChange,
options,
inputId,
}: Props) {
return (
<Select
isMulti
getOptionLabel={(option) => option.Username}
getOptionValue={(option) => String(option.Id)}
options={options}
value={value}
closeMenuOnSelect={false}
onChange={onChange}
data-cy="portainer-selectUserAccess"
inputId={inputId}
placeholder="Select one or more teams"
/>
);
}