diff --git a/frontend/components/TeamsDropdown/TeamsDropdown.tsx b/frontend/components/TeamsDropdown/TeamsDropdown.tsx
index e38b1c1b13f3..bc59c6fb0c67 100644
--- a/frontend/components/TeamsDropdown/TeamsDropdown.tsx
+++ b/frontend/components/TeamsDropdown/TeamsDropdown.tsx
@@ -18,7 +18,7 @@ import {
import Icon from "components/Icon";
-interface INumberDropdownOption extends Omit {
+export interface INumberDropdownOption extends Omit {
value: number; // Redefine the value property to be just number
}
diff --git a/frontend/components/forms/fields/Dropdown/DropdownOptionTooltipWrapper/_styles.scss b/frontend/components/forms/fields/Dropdown/DropdownOptionTooltipWrapper/_styles.scss
index 7fcd24ad33ed..23bf82f07066 100644
--- a/frontend/components/forms/fields/Dropdown/DropdownOptionTooltipWrapper/_styles.scss
+++ b/frontend/components/forms/fields/Dropdown/DropdownOptionTooltipWrapper/_styles.scss
@@ -1,7 +1,8 @@
// Used with old react-select dropdown and
-// New react-select-5 ActionsDropdown.tsx
+// New react-select-5: ActionsDropdown.tsx, DropdownWrapper.tsx
.Select > .Select-menu-outer,
-.actions-dropdown {
+.actions-dropdown,
+.react-select__option {
.is-disabled * {
color: $ui-fleet-black-50;
}
diff --git a/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.stories.tsx b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.stories.tsx
new file mode 100644
index 000000000000..ee0d223c58ca
--- /dev/null
+++ b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.stories.tsx
@@ -0,0 +1,62 @@
+// stories/DropdownWrapper.stories.tsx
+
+import React from "react";
+import { Meta, Story } from "@storybook/react";
+import DropdownWrapper, {
+ IDropdownWrapper,
+ CustomOptionType,
+} from "./DropdownWrapper";
+
+// Define metadata for the story
+export default {
+ title: "Components/DropdownWrapper",
+ component: DropdownWrapper,
+ argTypes: {
+ onChange: { action: "changed" },
+ },
+} as Meta;
+
+// Define a template for the stories
+const Template: Story = (args) => (
+
+);
+
+// Sample options to be used in the dropdown
+const sampleOptions: CustomOptionType[] = [
+ { label: "Option 1", value: "option1", helpText: "Help text for option 1" },
+ {
+ label: "Option 2",
+ value: "option2",
+ tooltipContent: "Tooltip for option 2",
+ },
+ { label: "Option 3", value: "option3", isDisabled: true },
+];
+
+// Default story
+export const Default = Template.bind({});
+Default.args = {
+ options: sampleOptions,
+ name: "dropdown-example",
+ label: "Select an option",
+};
+
+// Disabled story
+export const Disabled = Template.bind({});
+Disabled.args = {
+ ...Default.args,
+ isDisabled: true,
+};
+
+// With Help Text story
+export const WithHelpText = Template.bind({});
+WithHelpText.args = {
+ ...Default.args,
+ helpText: "This is some help text for the dropdown",
+};
+
+// With Error story
+export const WithError = Template.bind({});
+WithError.args = {
+ ...Default.args,
+ error: "This is an error message",
+};
diff --git a/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tests.tsx b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tests.tsx
new file mode 100644
index 000000000000..2715876f8ba4
--- /dev/null
+++ b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tests.tsx
@@ -0,0 +1,102 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import DropdownWrapper, { CustomOptionType } from "./DropdownWrapper";
+
+const sampleOptions: CustomOptionType[] = [
+ {
+ label: "Option 1",
+ value: "option1",
+ tooltipContent: "Tooltip 1",
+ helpText: "Help text 1",
+ },
+ {
+ label: "Option 2",
+ value: "option2",
+ tooltipContent: "Tooltip 2",
+ helpText: "Help text 2",
+ },
+];
+
+describe("DropdownWrapper Component", () => {
+ const mockOnChange = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test("renders with help text", () => {
+ render(
+
+ );
+
+ expect(screen.getByText(/test dropdown/i)).toBeInTheDocument();
+ expect(screen.getByText(/this is a help text/i)).toBeInTheDocument();
+ });
+
+ test("calls onChange when an option is selected", async () => {
+ render(
+
+ );
+
+ // Open the dropdown
+ await userEvent.click(screen.getByText(/option 1/i));
+
+ // Select Option 2
+ await userEvent.click(screen.getByText(/option 2/i));
+
+ expect(mockOnChange).toHaveBeenCalledWith({
+ helpText: "Help text 2",
+ label: "Option 2",
+ tooltipContent: "Tooltip 2",
+ value: "option2",
+ });
+ });
+
+ test("renders error message when provided", () => {
+ render(
+
+ );
+
+ expect(screen.getByText(/this is an error message/i)).toBeInTheDocument();
+ });
+
+ test("displays no options message when no options are available", async () => {
+ render(
+
+ );
+
+ // Open dropdown
+ await userEvent.click(screen.getByText(/choose option/i));
+
+ expect(screen.getByText(/no results found/i)).toBeInTheDocument();
+ });
+});
diff --git a/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tsx b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tsx
new file mode 100644
index 000000000000..51c5c3cd695f
--- /dev/null
+++ b/frontend/components/forms/fields/DropdownWrapper/DropdownWrapper.tsx
@@ -0,0 +1,340 @@
+/**
+ * This is a new component built off react-select 5.4
+ * meant to replace Dropdown.jsx built off react-select 1.3
+ *
+ * See storybook component for current functionality
+ *
+ * Prototyped on UserForm.tsx but added and tested the following:
+ * Options: text, disabled, option helptext, option tooltip
+ * Other: label text, dropdown help text, dropdown error
+ */
+
+import classnames from "classnames";
+import React from "react";
+import Select, {
+ StylesConfig,
+ DropdownIndicatorProps,
+ OptionProps,
+ components,
+ PropsValue,
+ SingleValue,
+} from "react-select-5";
+
+import { COLORS } from "styles/var/colors";
+import { PADDING } from "styles/var/padding";
+
+import FormField from "components/forms/FormField";
+import DropdownOptionTooltipWrapper from "components/forms/fields/Dropdown/DropdownOptionTooltipWrapper";
+import Icon from "components/Icon";
+
+const getOptionBackgroundColor = (state: any) => {
+ return state.isSelected || state.isFocused
+ ? COLORS["ui-vibrant-blue-10"]
+ : "transparent";
+};
+
+export interface CustomOptionType {
+ label: string;
+ value: string;
+ tooltipContent?: string;
+ helpText?: string;
+ isDisabled?: boolean;
+}
+
+export interface IDropdownWrapper {
+ options: CustomOptionType[];
+ value?: PropsValue | string;
+ onChange: (newValue: SingleValue) => void;
+ name: string;
+ className?: string;
+ labelClassname?: string;
+ error?: string;
+ label?: JSX.Element | string;
+ helpText?: JSX.Element | string;
+ isSearchable?: boolean;
+ isDisabled?: boolean;
+ placeholder?: string;
+ menuPortalTarget?: HTMLElement | null;
+}
+
+const baseClass = "dropdown-wrapper";
+
+const DropdownWrapper = ({
+ options,
+ value,
+ onChange,
+ name,
+ className,
+ labelClassname,
+ error,
+ label,
+ helpText,
+ isSearchable,
+ isDisabled = false,
+ placeholder,
+ menuPortalTarget,
+}: IDropdownWrapper) => {
+ const wrapperClassNames = classnames(baseClass, className);
+
+ const handleChange = (newValue: SingleValue) => {
+ onChange(newValue);
+ };
+
+ // Ability to handle value of type string or CustomOptionType
+ const getCurrentValue = () => {
+ if (typeof value === "string") {
+ return options.find((option) => option.value === value) || null;
+ }
+ return value;
+ };
+
+ interface CustomOptionProps
+ extends Omit, "data"> {
+ data: CustomOptionType;
+ }
+
+ const CustomOption = (props: CustomOptionProps) => {
+ const { data, ...rest } = props;
+
+ const optionContent = (
+
+ {data.label}
+ {data.helpText && (
+ {data.helpText}
+ )}
+
+ );
+
+ return (
+
+ {data.tooltipContent ? (
+
+ {optionContent}
+
+ ) : (
+ optionContent
+ )}
+
+ );
+ };
+
+ const CustomDropdownIndicator = (
+ props: DropdownIndicatorProps
+ ) => {
+ const { isFocused, selectProps } = props;
+ const color =
+ isFocused || selectProps.menuIsOpen
+ ? "core-fleet-blue"
+ : "core-fleet-black";
+
+ return (
+
+
+
+ );
+ };
+
+ const customStyles: StylesConfig = {
+ container: (provided) => ({
+ ...provided,
+ width: "100%",
+ height: "40px",
+ }),
+ control: (provided, state) => ({
+ ...provided,
+ display: "flex",
+ flexDirection: "row",
+ width: "100%",
+ backgroundColor: COLORS["ui-off-white"],
+ paddingLeft: "8px", // TODO: Update to match styleguide of (16px) when updating rest of UI (8px)
+ paddingRight: "8px",
+ cursor: "pointer",
+ boxShadow: "none",
+ borderRadius: "4px",
+ borderColor: state.isFocused
+ ? COLORS["core-fleet-blue"]
+ : COLORS["ui-fleet-black-10"],
+ "&:hover": {
+ boxShadow: "none",
+ borderColor: COLORS["core-fleet-blue"],
+ ".dropdown-wrapper__single-value": {
+ color: COLORS["core-vibrant-blue-over"],
+ },
+ ".dropdown-wrapper__indicator path": {
+ stroke: COLORS["core-vibrant-blue-over"],
+ },
+ },
+ // When tabbing
+ // Relies on --is-focused for styling as &:focus-visible cannot be applied
+ "&.dropdown-wrapper__control--is-focused": {
+ ".dropdown-wrapper__single-value": {
+ color: COLORS["core-vibrant-blue-over"],
+ },
+ ".dropdown-wrapper__indicator path": {
+ stroke: COLORS["core-vibrant-blue-over"],
+ },
+ },
+ ...(state.isDisabled && {
+ ".dropdown-wrapper__single-value": {
+ color: COLORS["ui-fleet-black-50"],
+ },
+ ".dropdown-wrapper__indicator path": {
+ stroke: COLORS["ui-fleet-black-50"],
+ },
+ }),
+ "&:active": {
+ ".dropdown-wrapper__single-value": {
+ color: COLORS["core-vibrant-blue-down"],
+ },
+ ".dropdown-wrapper__indicator path": {
+ stroke: COLORS["core-vibrant-blue-down"],
+ },
+ },
+ ...(state.menuIsOpen && {
+ ".dropdown-wrapper__indicator svg": {
+ transform: "rotate(180deg)",
+ transition: "transform 0.25s ease",
+ },
+ }),
+ }),
+ singleValue: (provided) => ({
+ ...provided,
+ fontSize: "16px",
+ margin: 0,
+ padding: 0,
+ }),
+ dropdownIndicator: (provided) => ({
+ ...provided,
+ display: "flex",
+ padding: "2px",
+ svg: {
+ transition: "transform 0.25s ease",
+ },
+ }),
+ menu: (provided) => ({
+ ...provided,
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.1)",
+ borderRadius: "4px",
+ zIndex: 6,
+ overflow: "hidden",
+ border: 0,
+ marginTop: 0,
+ maxHeight: "none",
+ position: "absolute",
+ left: "0",
+ animation: "fade-in 150ms ease-out",
+ }),
+ menuList: (provided) => ({
+ ...provided,
+ padding: PADDING["pad-small"],
+ }),
+ valueContainer: (provided) => ({
+ ...provided,
+ padding: 0,
+ }),
+ option: (provided, state) => ({
+ ...provided,
+ padding: "10px 8px",
+ fontSize: "14px",
+ backgroundColor: getOptionBackgroundColor(state),
+ color: COLORS["core-fleet-black"],
+ "&:hover": {
+ backgroundColor: state.isDisabled
+ ? "transparent"
+ : COLORS["ui-vibrant-blue-10"],
+ },
+ "&:active": {
+ backgroundColor: state.isDisabled
+ ? "transparent"
+ : COLORS["ui-vibrant-blue-10"],
+ },
+ ...(state.isDisabled && {
+ color: COLORS["ui-fleet-black-50"],
+ fontStyle: "italic",
+ cursor: "not-allowed",
+ pointerEvents: "none",
+ }),
+ // Styles for custom option
+ ".dropdown-wrapper__option": {
+ display: "flex",
+ flexDirection: "column",
+ gap: "8px",
+ width: "100%",
+ },
+ ".dropdown-wrapper__help-text": {
+ fontSize: "12px",
+ whiteSpace: "normal",
+ color: COLORS["ui-fleet-black-50"],
+ fontStyle: "italic",
+ },
+ }),
+ menuPortal: (base) => ({ ...base, zIndex: 999 }), // Not hidden beneath scrollable sections
+ noOptionsMessage: (provided) => ({
+ ...provided,
+ textAlign: "left",
+ fontSize: "14px",
+ padding: "10px 8px",
+ }),
+ };
+
+ const renderLabel = () => {
+ const labelWrapperClasses = classnames(
+ `${baseClass}__label`,
+ labelClassname,
+ {
+ [`${baseClass}__label--error`]: !!error,
+ [`${baseClass}__label--disabled`]: isDisabled,
+ }
+ );
+
+ if (!label) {
+ return "";
+ }
+
+ return (
+
+ );
+ };
+
+ return (
+
+
+ );
+};
+
+export default DropdownWrapper;
diff --git a/frontend/components/forms/fields/DropdownWrapper/_styles.scss b/frontend/components/forms/fields/DropdownWrapper/_styles.scss
new file mode 100644
index 000000000000..2a92f5ced65a
--- /dev/null
+++ b/frontend/components/forms/fields/DropdownWrapper/_styles.scss
@@ -0,0 +1,14 @@
+// react-select's styles prop customizes the styling of
+// the internal components and not external elements like labels
+// See customStyles in DropdownWrappr.tsx
+// https://react-select.com/styles
+.dropdown-wrapper {
+ &__label {
+ &--error {
+ color: $ui-error;
+ }
+ &--disabled {
+ color: $ui-fleet-black-50;
+ }
+ }
+}
diff --git a/frontend/components/forms/fields/DropdownWrapper/index.tsx b/frontend/components/forms/fields/DropdownWrapper/index.tsx
new file mode 100644
index 000000000000..7e83f801949e
--- /dev/null
+++ b/frontend/components/forms/fields/DropdownWrapper/index.tsx
@@ -0,0 +1 @@
+export { default } from "./DropdownWrapper";
diff --git a/frontend/interfaces/role.ts b/frontend/interfaces/role.ts
deleted file mode 100644
index b645baa50db7..000000000000
--- a/frontend/interfaces/role.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import PropTypes from "prop-types";
-import { UserRole } from "./user";
-
-export default PropTypes.shape({
- disabled: PropTypes.bool,
- label: PropTypes.string,
- value: PropTypes.any, // eslint-disable-line react/forbid-prop-types
- helpText: PropTypes.string,
-});
-
-export interface IRole {
- disabled: boolean;
- label: string;
- value: UserRole;
- helpText?: string;
-}
diff --git a/frontend/pages/admin/TeamManagementPage/TeamDetailsWrapper/UsersPage/UsersPage.tsx b/frontend/pages/admin/TeamManagementPage/TeamDetailsWrapper/UsersPage/UsersPage.tsx
index 63bb85c823b8..a60b3f0661ed 100644
--- a/frontend/pages/admin/TeamManagementPage/TeamDetailsWrapper/UsersPage/UsersPage.tsx
+++ b/frontend/pages/admin/TeamManagementPage/TeamDetailsWrapper/UsersPage/UsersPage.tsx
@@ -1,10 +1,4 @@
-import React, {
- useCallback,
- useContext,
- useMemo,
- useState,
- useEffect,
-} from "react";
+import React, { useCallback, useContext, useMemo, useState } from "react";
import { useQuery } from "react-query";
import { Link } from "react-router";
diff --git a/frontend/pages/admin/UserManagementPage/UserManagementPage.tsx b/frontend/pages/admin/UserManagementPage/UserManagementPage.tsx
index 4f4190de7869..a12c06bb7cab 100644
--- a/frontend/pages/admin/UserManagementPage/UserManagementPage.tsx
+++ b/frontend/pages/admin/UserManagementPage/UserManagementPage.tsx
@@ -1,7 +1,5 @@
import React from "react";
import { InjectedRouter } from "react-router";
-import SandboxGate from "components/Sandbox/SandboxGate";
-import SandboxMessage from "components/Sandbox/SandboxMessage";
import UsersTable from "./components/UsersTable";
const baseClass = "user-management";
@@ -17,17 +15,7 @@ const UserManagementPage = ({ router }: IUserManagementProps): JSX.Element => {
Create new users, customize user permissions, and remove users from
Fleet.
- (
-
- )}
- >
-
-
+
);
};
diff --git a/frontend/pages/admin/UserManagementPage/components/SelectRoleForm/SelectRoleForm.tsx b/frontend/pages/admin/UserManagementPage/components/SelectRoleForm/SelectRoleForm.tsx
index a81d05df4421..c0236b5f8899 100644
--- a/frontend/pages/admin/UserManagementPage/components/SelectRoleForm/SelectRoleForm.tsx
+++ b/frontend/pages/admin/UserManagementPage/components/SelectRoleForm/SelectRoleForm.tsx
@@ -1,10 +1,9 @@
import React, { useState, useContext } from "react";
-
import { ITeam } from "interfaces/team";
import { UserRole } from "interfaces/user";
-// ignore TS error for now until these are rewritten in ts.
-// @ts-ignore
-import Dropdown from "components/forms/fields/Dropdown";
+import { SingleValue } from "react-select-5";
+import DropdownWrapper from "components/forms/fields/DropdownWrapper";
+import { CustomOptionType } from "components/forms/fields/DropdownWrapper/DropdownWrapper";
import { AppContext } from "context/app";
import { roleOptions } from "../../helpers/userManagementHelpers";
@@ -13,29 +12,19 @@ interface ISelectRoleFormProps {
currentTeam?: ITeam;
teams: ITeam[];
onFormChange: (teams: ITeam[]) => void;
- label: string | string[];
isApiOnly?: boolean;
}
const generateSelectedTeamData = (
allTeams: ITeam[],
- updatedTeam?: any
+ updatedTeam?: Partial
): ITeam[] => {
- const filtered = allTeams.map(
- (teamItem): ITeam => {
- const teamRole =
- teamItem.id === updatedTeam?.id ? updatedTeam.role : teamItem.role;
- return {
- description: teamItem.description,
- id: teamItem.id,
- host_count: teamItem.host_count,
- user_count: teamItem.user_count,
- name: teamItem.name,
- role: teamRole,
- };
- }
+ return allTeams.map(
+ (teamItem): ITeam => ({
+ ...teamItem,
+ role: teamItem.id === updatedTeam?.id ? updatedTeam.role! : teamItem.role,
+ })
);
- return filtered;
};
const SelectRoleForm = ({
@@ -43,33 +32,33 @@ const SelectRoleForm = ({
currentTeam,
teams,
onFormChange,
- label,
isApiOnly,
}: ISelectRoleFormProps): JSX.Element => {
const { isPremiumTier } = useContext(AppContext);
- const [selectedRole, setSelectedRole] = useState(
- defaultTeamRole.toLowerCase()
- );
-
- const updateSelectedRole = (newRoleValue: UserRole) => {
- const updatedTeam = { ...currentTeam };
-
- updatedTeam.role = newRoleValue;
+ const [selectedRole, setSelectedRole] = useState({
+ value: defaultTeamRole.toLowerCase(),
+ label: defaultTeamRole,
+ });
- onFormChange(generateSelectedTeamData(teams, updatedTeam));
-
- setSelectedRole(newRoleValue);
+ const updateSelectedRole = (newRoleValue: SingleValue) => {
+ if (newRoleValue) {
+ const updatedTeam = {
+ ...currentTeam,
+ role: newRoleValue.value as UserRole,
+ };
+ onFormChange(generateSelectedTeamData(teams, updatedTeam));
+ setSelectedRole(newRoleValue);
+ }
};
return (
- updateSelectedRole(newRoleValue)}
- testId={`${name}-checkbox`}
+ value={selectedRole}
+ onChange={updateSelectedRole}
+ isSearchable={false}
/>
);
};
diff --git a/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/SelectedTeamsForm.tsx b/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/SelectedTeamsForm.tsx
index 86ffa85ee5ad..4f8635f995a2 100644
--- a/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/SelectedTeamsForm.tsx
+++ b/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/SelectedTeamsForm.tsx
@@ -3,8 +3,9 @@ import React, { useState } from "react";
import { ITeam } from "interfaces/team";
import { UserRole } from "interfaces/user";
import Checkbox from "components/forms/fields/Checkbox";
-// @ts-ignore
-import Dropdown from "components/forms/fields/Dropdown";
+import { SingleValue } from "react-select-5";
+import DropdownWrapper from "components/forms/fields/DropdownWrapper";
+import { CustomOptionType } from "components/forms/fields/DropdownWrapper/DropdownWrapper";
import { roleOptions } from "../../helpers/userManagementHelpers";
interface ITeamCheckboxListItem extends ITeam {
@@ -62,7 +63,7 @@ const generateSelectedTeamData = (
const updateFormState = (
prevTeamItems: ITeamCheckboxListItem[],
teamId: number,
- newValue: UserRole | boolean | undefined
+ newValue: SingleValue | boolean | undefined
): ITeamCheckboxListItem[] => {
const prevItemIndex = prevTeamItems.findIndex((item) => item.id === teamId);
const prevItem = prevTeamItems[prevItemIndex];
@@ -70,7 +71,7 @@ const updateFormState = (
if (typeof newValue === "boolean") {
prevItem.isChecked = newValue;
} else {
- prevItem.role = newValue;
+ prevItem.role = newValue?.value as UserRole;
}
return [...prevTeamItems];
@@ -87,7 +88,7 @@ const useSelectedTeamState = (
const updateSelectedTeams = (
teamId: number,
- newValue: UserRole | boolean
+ newValue: CustomOptionType | boolean
) => {
setTeamsFormList((prevState) => {
const updatedTeamFormList = updateFormState(prevState, teamId, newValue);
@@ -127,15 +128,15 @@ const SelectedTeamsForm = ({
>
{name}
-
- updateSelectedTeams(teamItem.id, newValue)
+ isSearchable={false}
+ onChange={(newValue: SingleValue) =>
+ updateSelectedTeams(teamItem.id, newValue as CustomOptionType)
}
- testId={`${name}-checkbox`}
/>
);
diff --git a/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/_styles.scss b/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/_styles.scss
index 2fc392ae2124..dc2629b80fd2 100644
--- a/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/_styles.scss
+++ b/frontend/pages/admin/UserManagementPage/components/SelectedTeamsForm/_styles.scss
@@ -13,7 +13,7 @@
justify-content: space-between;
.form-field--dropdown {
- width: auto;
+ width: 154px; // Matches dropdown
}
}
diff --git a/frontend/pages/admin/UserManagementPage/components/UserForm/UserForm.tsx b/frontend/pages/admin/UserManagementPage/components/UserForm/UserForm.tsx
index 0e74b29c58d9..c89dc37dcccd 100644
--- a/frontend/pages/admin/UserManagementPage/components/UserForm/UserForm.tsx
+++ b/frontend/pages/admin/UserManagementPage/components/UserForm/UserForm.tsx
@@ -370,7 +370,6 @@ const UserForm = ({
>
) : (
;
-interface IRoleOptionsParams {
+export interface IRoleOptionsParams {
isPremiumTier?: boolean;
isApiOnly?: boolean;
}
@@ -58,20 +58,17 @@ const generateUpdateData = (
export const roleOptions = ({
isPremiumTier,
isApiOnly,
-}: IRoleOptionsParams): IRole[] => {
- const roles: IRole[] = [
+}: IRoleOptionsParams): CustomOptionType[] => {
+ const roles: CustomOptionType[] = [
{
- disabled: false,
label: "Observer",
value: "observer",
},
{
- disabled: false,
label: "Maintainer",
value: "maintainer",
},
{
- disabled: false,
label: "Admin",
value: "admin",
},
@@ -79,14 +76,12 @@ export const roleOptions = ({
if (isPremiumTier) {
roles.splice(1, 0, {
- disabled: false,
label: "Observer+",
value: "observer_plus",
});
if (isApiOnly) {
roles.splice(3, 0, {
- disabled: false,
label: "GitOps",
value: "gitops",
});