move keycloak select to ui-shared and fix typeahead (#30209)
* move keycloak select to ui-shared and fix typeahead Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * Fix the account console test Signed-off-by: Hynek Mlnarik <hmlnarik@redhat.com> * Fix cypress tests Signed-off-by: Hynek Mlnarik <hmlnarik@redhat.com> * fix for when value is an array Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fix for when value is an array Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * add support for array selecting single value Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fixed saying open once clicked outside and value Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * small issue when pressing enter Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> Signed-off-by: Hynek Mlnarik <hmlnarik@redhat.com> Co-authored-by: Hynek Mlnarik <hmlnarik@redhat.com>
This commit is contained in:
parent
28fd38d13d
commit
d2e8092c7f
48 changed files with 258 additions and 251 deletions
|
@ -63,10 +63,10 @@ test.describe("Personal info with userprofile enabled", () => {
|
||||||
test("render long select options as typeahead", async ({ page }) => {
|
test("render long select options as typeahead", async ({ page }) => {
|
||||||
await login(page, user, "jdoe", realm);
|
await login(page, user, "jdoe", realm);
|
||||||
|
|
||||||
await page.getByText("Alternate Language").click();
|
await page.locator("#alternatelang").click();
|
||||||
await page.waitForSelector("text=Italiano");
|
await page.waitForSelector("text=Italiano");
|
||||||
|
|
||||||
await page.getByText("Alternate Language").click();
|
await page.locator("#alternatelang").click();
|
||||||
await page.locator("*:focus").press("Control+A");
|
await page.locator("*:focus").press("Control+A");
|
||||||
await page.locator("*:focus").pressSequentially("S");
|
await page.locator("*:focus").pressSequentially("S");
|
||||||
await expect(page.getByText("Italiano")).toHaveCount(0);
|
await expect(page.getByText("Italiano")).toHaveCount(0);
|
||||||
|
|
|
@ -9,8 +9,8 @@ export default defineConfig({
|
||||||
video: isCI,
|
video: isCI,
|
||||||
projectId: "j4yhox",
|
projectId: "j4yhox",
|
||||||
chromeWebSecurity: false,
|
chromeWebSecurity: false,
|
||||||
viewportWidth: 1360,
|
viewportWidth: 1920,
|
||||||
viewportHeight: 768,
|
viewportHeight: 1200,
|
||||||
defaultCommandTimeout: 30000,
|
defaultCommandTimeout: 30000,
|
||||||
numTestsKeptInMemory: 30,
|
numTestsKeptInMemory: 30,
|
||||||
experimentalMemoryManagement: true,
|
experimentalMemoryManagement: true,
|
||||||
|
|
|
@ -371,7 +371,7 @@ describe("User profile tabs", () => {
|
||||||
createUserPage
|
createUserPage
|
||||||
.goToCreateUser()
|
.goToCreateUser()
|
||||||
.assertAttributeLabel(attrName, attrName)
|
.assertAttributeLabel(attrName, attrName)
|
||||||
.assertAttributeSelect(attrName, supportedOptions, "Choose...")
|
.assertAttributeSelect(attrName, supportedOptions, "Select an option")
|
||||||
.setUsername(userName)
|
.setUsername(userName)
|
||||||
.setAttributeValueOnSelect(attrName, opt1)
|
.setAttributeValueOnSelect(attrName, opt1)
|
||||||
.create()
|
.create()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
import { Button, SelectOption, TextInput } from "@patternfly/react-core";
|
import { Button, SelectOption, TextInput } from "@patternfly/react-core";
|
||||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||||
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
||||||
|
@ -6,14 +7,9 @@ import { camelCase } from "lodash-es";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
|
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { defaultContextAttributes } from "../utils";
|
import { defaultContextAttributes } from "../utils";
|
||||||
|
|
||||||
import "./key-based-attribute-input.css";
|
import "./key-based-attribute-input.css";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type AttributeType = {
|
export type AttributeType = {
|
||||||
key?: string;
|
key?: string;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { DecisionStrategy } from "@keycloak/keycloak-admin-client/lib/defs/polic
|
||||||
import {
|
import {
|
||||||
FormErrorText,
|
FormErrorText,
|
||||||
HelpItem,
|
HelpItem,
|
||||||
|
SelectVariant,
|
||||||
TextAreaControl,
|
TextAreaControl,
|
||||||
TextControl,
|
TextControl,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
@ -39,7 +40,6 @@ import {
|
||||||
} from "../routes/PermissionDetails";
|
} from "../routes/PermissionDetails";
|
||||||
import { ResourcesPolicySelect } from "./ResourcesPolicySelect";
|
import { ResourcesPolicySelect } from "./ResourcesPolicySelect";
|
||||||
import { ScopeSelect } from "./ScopeSelect";
|
import { ScopeSelect } from "./ScopeSelect";
|
||||||
import { SelectVariant } from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
type FormFields = PolicyRepresentation & {
|
type FormFields = PolicyRepresentation & {
|
||||||
resourceType: string;
|
resourceType: string;
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {
|
||||||
KeycloakSelect,
|
KeycloakSelect,
|
||||||
SelectVariant,
|
SelectVariant,
|
||||||
Variant,
|
Variant,
|
||||||
} from "../../components/select/KeycloakSelect";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { useFetch } from "../../utils/useFetch";
|
import { useFetch } from "../../utils/useFetch";
|
||||||
import useToggle from "../../utils/useToggle";
|
import useToggle from "../../utils/useToggle";
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
import { useFetch } from "../../utils/useFetch";
|
import { useFetch } from "../../utils/useFetch";
|
||||||
|
|
||||||
type Scope = {
|
type Scope = {
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
|
import { SelectOption } from "@patternfly/react-core";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { useFetch } from "../../utils/useFetch";
|
import { useFetch } from "../../utils/useFetch";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
import { SelectOption } from "@patternfly/react-core";
|
|
||||||
|
|
||||||
type ScopeSelectProps = {
|
type ScopeSelectProps = {
|
||||||
clientId: string;
|
clientId: string;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation";
|
import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation";
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
|
@ -17,7 +18,6 @@ import {
|
||||||
} from "@patternfly/react-icons";
|
} from "@patternfly/react-icons";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ClientScopeType,
|
ClientScopeType,
|
||||||
clientScopeTypesDropdown,
|
clientScopeTypesDropdown,
|
||||||
|
@ -26,7 +26,6 @@ import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState
|
||||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||||
import useToggle from "../../utils/useToggle";
|
import useToggle from "../../utils/useToggle";
|
||||||
import { getProtocolName } from "../utils";
|
import { getProtocolName } from "../utils";
|
||||||
import { KeycloakSelect } from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
import "./client-scopes.css";
|
import "./client-scopes.css";
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,12 @@ import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/
|
||||||
import type ProtocolMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/protocolMapperRepresentation";
|
import type ProtocolMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/protocolMapperRepresentation";
|
||||||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||||
import type { ProtocolMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
|
import type { ProtocolMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
useHelp,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ClipboardCopy,
|
ClipboardCopy,
|
||||||
Form,
|
Form,
|
||||||
|
@ -23,7 +29,6 @@ import { QuestionCircleIcon } from "@patternfly/react-icons";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { HelpItem, useHelp } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||||
import { UserSelect } from "../../components/users/UserSelect";
|
import { UserSelect } from "../../components/users/UserSelect";
|
||||||
|
@ -35,10 +40,6 @@ import { useFetch } from "../../utils/useFetch";
|
||||||
import { GeneratedCodeTab } from "./GeneratedCodeTab";
|
import { GeneratedCodeTab } from "./GeneratedCodeTab";
|
||||||
|
|
||||||
import "./evaluate.css";
|
import "./evaluate.css";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type EvaluateScopesProps = {
|
export type EvaluateScopesProps = {
|
||||||
clientId: string;
|
clientId: string;
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { convertToName } from "./DynamicComponents";
|
import { convertToName } from "./DynamicComponents";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { KeycloakSelect, SelectVariant } from "../select/KeycloakSelect";
|
|
||||||
|
|
||||||
export const ListComponent = ({
|
export const ListComponent = ({
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { KeycloakSelect, SelectVariant } from "../select/KeycloakSelect";
|
|
||||||
import { convertToName } from "./DynamicComponents";
|
import { convertToName } from "./DynamicComponents";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
|
@ -9,7 +10,6 @@ import { UseControllerProps, useController } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useToggle from "../../utils/useToggle";
|
import useToggle from "../../utils/useToggle";
|
||||||
import { DefaultValue } from "./KeyValueInput";
|
import { DefaultValue } from "./KeyValueInput";
|
||||||
import { KeycloakSelect } from "../select/KeycloakSelect";
|
|
||||||
|
|
||||||
type KeySelectProp = UseControllerProps & {
|
type KeySelectProp = UseControllerProps & {
|
||||||
selectItems: DefaultValue[];
|
selectItems: DefaultValue[];
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import { SelectOption, TextInput } from "@patternfly/react-core";
|
import { SelectOption, TextInput } from "@patternfly/react-core";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { UseControllerProps, useController } from "react-hook-form";
|
import { UseControllerProps, useController } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { KeycloakSelect } from "../select/KeycloakSelect";
|
|
||||||
import { DefaultValue } from "./KeyValueInput";
|
import { DefaultValue } from "./KeyValueInput";
|
||||||
|
|
||||||
type ValueSelectProps = UseControllerProps & {
|
type ValueSelectProps = UseControllerProps & {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import {
|
||||||
import { useTranslation } from "react-i18next";
|
KeycloakSelect,
|
||||||
|
KeycloakSelectProps,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
SelectOption,
|
SelectOption,
|
||||||
Split,
|
Split,
|
||||||
|
@ -7,11 +10,8 @@ import {
|
||||||
TextInput,
|
TextInput,
|
||||||
TextInputProps,
|
TextInputProps,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import {
|
import { useEffect, useMemo, useState } from "react";
|
||||||
KeycloakSelect,
|
import { useTranslation } from "react-i18next";
|
||||||
KeycloakSelectProps,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type Unit = "second" | "minute" | "hour" | "day";
|
export type Unit = "second" | "minute" | "hour" | "day";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import type { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import type { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
|
import {
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
label,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Alert,
|
Alert,
|
||||||
|
@ -18,11 +23,8 @@ import { ReactNode, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Form } from "react-router-dom";
|
import { Form } from "react-router-dom";
|
||||||
import { SelectVariant, label } from "@keycloak/keycloak-ui-shared";
|
|
||||||
|
|
||||||
import { useAlerts } from "../alert/Alerts";
|
import { useAlerts } from "../alert/Alerts";
|
||||||
import { UserAttribute } from "./UserDataTable";
|
import { UserAttribute } from "./UserDataTable";
|
||||||
import { KeycloakSelect } from "../select/KeycloakSelect";
|
|
||||||
|
|
||||||
type UserDataTableAttributeSearchFormProps = {
|
type UserDataTableAttributeSearchFormProps = {
|
||||||
activeFilters: UserAttribute[];
|
activeFilters: UserAttribute[];
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import type AdminEventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/adminEventRepresentation";
|
import type AdminEventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/adminEventRepresentation";
|
||||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
TextControl,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
|
@ -32,10 +36,6 @@ import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
import DropdownPanel from "../components/dropdown-panel/DropdownPanel";
|
import DropdownPanel from "../components/dropdown-panel/DropdownPanel";
|
||||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
import {
|
import {
|
||||||
Action,
|
Action,
|
||||||
KeycloakDataTable,
|
KeycloakDataTable,
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import type EventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/eventRepresentation";
|
import type EventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/eventRepresentation";
|
||||||
import type EventType from "@keycloak/keycloak-admin-client/lib/defs/eventTypes";
|
import type EventType from "@keycloak/keycloak-admin-client/lib/defs/eventTypes";
|
||||||
import type { RealmEventsConfigRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/realmEventsConfigRepresentation";
|
import type { RealmEventsConfigRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/realmEventsConfigRepresentation";
|
||||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
TextControl,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
|
@ -37,10 +41,6 @@ import {
|
||||||
RoutableTabs,
|
RoutableTabs,
|
||||||
useRoutableTab,
|
useRoutableTab,
|
||||||
} from "../components/routable-tabs/RoutableTabs";
|
} from "../components/routable-tabs/RoutableTabs";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
|
|
@ -2,17 +2,15 @@ import type IdentityProviderMapperRepresentation from "@keycloak/keycloak-admin-
|
||||||
import type { IdentityProviderMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperTypeRepresentation";
|
import type { IdentityProviderMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperTypeRepresentation";
|
||||||
import {
|
import {
|
||||||
HelpItem,
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
SelectControl,
|
SelectControl,
|
||||||
|
SelectVariant,
|
||||||
TextControl,
|
TextControl,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, UseFormReturn } from "react-hook-form";
|
import { Controller, UseFormReturn } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
||||||
|
|
||||||
type AddMapperFormProps = {
|
type AddMapperFormProps = {
|
||||||
|
|
|
@ -3,7 +3,9 @@ import type IdentityProviderRepresentation from "@keycloak/keycloak-admin-client
|
||||||
import {
|
import {
|
||||||
FormErrorText,
|
FormErrorText,
|
||||||
HelpItem,
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
SelectControl,
|
SelectControl,
|
||||||
|
SelectVariant,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
FormGroup,
|
FormGroup,
|
||||||
|
@ -16,10 +18,6 @@ import { useState } from "react";
|
||||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
import { useFetch } from "../../utils/useFetch";
|
import { useFetch } from "../../utils/useFetch";
|
||||||
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
|
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
|
||||||
import type { FieldProps } from "../component/FormGroupField";
|
import type { FieldProps } from "../component/FormGroupField";
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ExpandableSection,
|
ExpandableSection,
|
||||||
Form,
|
Form,
|
||||||
|
@ -8,9 +13,6 @@ import {
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { HelpItem, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { KeycloakSelect } from "../../components/select/KeycloakSelect";
|
|
||||||
import { FormGroupField } from "../component/FormGroupField";
|
import { FormGroupField } from "../component/FormGroupField";
|
||||||
import { SwitchField } from "../component/SwitchField";
|
import { SwitchField } from "../component/SwitchField";
|
||||||
import { TextField } from "../component/TextField";
|
import { TextField } from "../component/TextField";
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import { sortProviders } from "../../util";
|
||||||
import { ClientIdSecret } from "../component/ClientIdSecret";
|
import { ClientIdSecret } from "../component/ClientIdSecret";
|
||||||
import { SwitchField } from "../component/SwitchField";
|
import { SwitchField } from "../component/SwitchField";
|
||||||
import { sortProviders } from "../../util";
|
|
||||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
|
||||||
import { TextField } from "../component/TextField";
|
import { TextField } from "../component/TextField";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
const clientAuthentications = [
|
const clientAuthentications = [
|
||||||
"client_secret_post",
|
"client_secret_post",
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { HelpItem, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||||
import { KeycloakSelect } from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
const comparisonValues = ["exact", "minimum", "maximum", "better"];
|
const comparisonValues = ["exact", "minimum", "maximum", "better"];
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import type { ConfigPropertyRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigInfoRepresentation";
|
import type { ConfigPropertyRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigInfoRepresentation";
|
||||||
import type ClientProfileRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientProfileRepresentation";
|
import type ClientProfileRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientProfileRepresentation";
|
||||||
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
@ -18,10 +22,6 @@ import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { DynamicComponents } from "../components/dynamic/DynamicComponents";
|
import { DynamicComponents } from "../components/dynamic/DynamicComponents";
|
||||||
import { FormAccess } from "../components/form/FormAccess";
|
import { FormAccess } from "../components/form/FormAccess";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
import { useFetch } from "../utils/useFetch";
|
import { useFetch } from "../utils/useFetch";
|
||||||
|
|
|
@ -2,7 +2,11 @@ import type { ConfigPropertyRepresentation } from "@keycloak/keycloak-admin-clie
|
||||||
import type ClientPolicyConditionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyConditionRepresentation";
|
import type ClientPolicyConditionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyConditionRepresentation";
|
||||||
import type ClientPolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyRepresentation";
|
import type ClientPolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyRepresentation";
|
||||||
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
@ -20,10 +24,6 @@ import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { DynamicComponents } from "../components/dynamic/DynamicComponents";
|
import { DynamicComponents } from "../components/dynamic/DynamicComponents";
|
||||||
import { FormAccess } from "../components/form/FormAccess";
|
import { FormAccess } from "../components/form/FormAccess";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type {
|
||||||
PartialImportResult,
|
PartialImportResult,
|
||||||
} from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
} from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
Button,
|
Button,
|
||||||
|
@ -30,7 +31,6 @@ import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { JsonFileUpload } from "../components/json-file-upload/JsonFileUpload";
|
import { JsonFileUpload } from "../components/json-file-upload/JsonFileUpload";
|
||||||
import { KeycloakSelect } from "../components/select/KeycloakSelect";
|
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
|
@ -9,13 +14,7 @@ import {
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { FormAccess } from "../components/form/FormAccess";
|
import { FormAccess } from "../components/form/FormAccess";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
import { convertToFormValues } from "../util";
|
import { convertToFormValues } from "../util";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
|
import {
|
||||||
|
FormPanel,
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
|
@ -17,8 +23,6 @@ import {
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Controller, useForm, useWatch } from "react-hook-form";
|
import { Controller, useForm, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FormPanel, HelpItem } from "@keycloak/keycloak-ui-shared";
|
|
||||||
|
|
||||||
import { FormAccess } from "../components/form/FormAccess";
|
import { FormAccess } from "../components/form/FormAccess";
|
||||||
import {
|
import {
|
||||||
TimeSelector,
|
TimeSelector,
|
||||||
|
@ -30,10 +34,6 @@ import { beerify, convertToFormValues, sortProviders } from "../util";
|
||||||
import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled";
|
import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled";
|
||||||
|
|
||||||
import "./realm-settings-section.css";
|
import "./realm-settings-section.css";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
type RealmSettingsSessionsTabProps = {
|
type RealmSettingsSessionsTabProps = {
|
||||||
realm: RealmRepresentation;
|
realm: RealmRepresentation;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||||
import type { KeyMetadataRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/keyMetadataRepresentation";
|
import type { KeyMetadataRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/keyMetadataRepresentation";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
|
@ -15,10 +16,6 @@ import { useAdminClient } from "../../admin-client";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||||
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { emptyFormatter } from "../../util";
|
import { emptyFormatter } from "../../util";
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
|
@ -28,10 +29,6 @@ import { useWhoAmI } from "../../context/whoami/WhoAmI";
|
||||||
import { DEFAULT_LOCALE } from "../../i18n/i18n";
|
import { DEFAULT_LOCALE } from "../../i18n/i18n";
|
||||||
import { localeToDisplayName } from "../../util";
|
import { localeToDisplayName } from "../../util";
|
||||||
import useLocaleSort, { mapByKey } from "../../utils/useLocaleSort";
|
import useLocaleSort, { mapByKey } from "../../utils/useLocaleSort";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
type EffectiveMessageBundlesProps = {
|
type EffectiveMessageBundlesProps = {
|
||||||
defaultSupportedLocales: string[];
|
defaultSupportedLocales: string[];
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
Button,
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
Divider,
|
Divider,
|
||||||
|
Dropdown,
|
||||||
|
DropdownItem,
|
||||||
|
DropdownList,
|
||||||
Form,
|
Form,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
|
MenuToggle,
|
||||||
|
SelectGroup,
|
||||||
|
SelectOption,
|
||||||
Text,
|
Text,
|
||||||
TextContent,
|
TextContent,
|
||||||
TextInput,
|
TextInput,
|
||||||
TextVariants,
|
TextVariants,
|
||||||
ToolbarItem,
|
ToolbarItem,
|
||||||
SelectGroup,
|
|
||||||
SelectOption,
|
|
||||||
Dropdown,
|
|
||||||
MenuToggle,
|
|
||||||
DropdownList,
|
|
||||||
DropdownItem,
|
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import {
|
import {
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
|
@ -51,10 +52,6 @@ import { useWhoAmI } from "../../context/whoami/WhoAmI";
|
||||||
import { DEFAULT_LOCALE } from "../../i18n/i18n";
|
import { DEFAULT_LOCALE } from "../../i18n/i18n";
|
||||||
import { localeToDisplayName } from "../../util";
|
import { localeToDisplayName } from "../../util";
|
||||||
import { AddTranslationModal } from "../AddTranslationModal";
|
import { AddTranslationModal } from "../AddTranslationModal";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
type RealmOverridesProps = {
|
type RealmOverridesProps = {
|
||||||
internationalizationEnabled: boolean;
|
internationalizationEnabled: boolean;
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
NumberControl,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
|
@ -8,14 +14,9 @@ import {
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { HelpItem, NumberControl } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { FormAccess } from "../../components/form/FormAccess";
|
import { FormAccess } from "../../components/form/FormAccess";
|
||||||
import { convertToFormValues } from "../../util";
|
import { convertToFormValues } from "../../util";
|
||||||
import { Time } from "./Time";
|
import { Time } from "./Time";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
type BruteForceDetectionProps = {
|
type BruteForceDetectionProps = {
|
||||||
realm: RealmRepresentation;
|
realm: RealmRepresentation;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { UserProfileAttribute } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import type { UserProfileAttribute } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
|
@ -13,20 +14,16 @@ import { uniqBy } from "lodash-es";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { DraggableTable } from "../../authentication/components/DraggableTable";
|
import { DraggableTable } from "../../authentication/components/DraggableTable";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
|
import useLocale from "../../utils/useLocale";
|
||||||
import useToggle from "../../utils/useToggle";
|
import useToggle from "../../utils/useToggle";
|
||||||
import { toAddAttribute } from "../routes/AddAttribute";
|
import { toAddAttribute } from "../routes/AddAttribute";
|
||||||
import { toAttribute } from "../routes/Attribute";
|
import { toAttribute } from "../routes/Attribute";
|
||||||
import { useUserProfile } from "./UserProfileContext";
|
import { useUserProfile } from "./UserProfileContext";
|
||||||
import useLocale from "../../utils/useLocale";
|
|
||||||
import { useAdminClient } from "../../admin-client";
|
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
const RESTRICTED_ATTRIBUTES = ["username", "email"];
|
const RESTRICTED_ATTRIBUTES = ["username", "email"];
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ import type { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs
|
||||||
import {
|
import {
|
||||||
FormErrorText,
|
FormErrorText,
|
||||||
HelpItem,
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
SelectControl,
|
SelectControl,
|
||||||
|
SelectVariant,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
|
@ -30,10 +32,6 @@ import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../../../admin-client";
|
import { useAdminClient } from "../../../admin-client";
|
||||||
import { FormAccess } from "../../../components/form/FormAccess";
|
import { FormAccess } from "../../../components/form/FormAccess";
|
||||||
import { KeycloakSpinner } from "../../../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../../../components/keycloak-spinner/KeycloakSpinner";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../../components/select/KeycloakSelect";
|
|
||||||
import { useRealm } from "../../../context/realm-context/RealmContext";
|
import { useRealm } from "../../../context/realm-context/RealmContext";
|
||||||
import { useFetch } from "../../../utils/useFetch";
|
import { useFetch } from "../../../utils/useFetch";
|
||||||
import { useParams } from "../../../utils/useParams";
|
import { useParams } from "../../../utils/useParams";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
import ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { KeycloakSelect } from "../../../components/select/KeycloakSelect";
|
|
||||||
import { useServerInfo } from "../../../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../../../context/server-info/ServerInfoProvider";
|
||||||
import useToggle from "../../../utils/useToggle";
|
import useToggle from "../../../utils/useToggle";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
|
import UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
DropdownItem,
|
DropdownItem,
|
||||||
PageSection,
|
PageSection,
|
||||||
|
@ -10,7 +11,6 @@ import { useTranslation } from "react-i18next";
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { KeycloakSelect } from "../components/select/KeycloakSelect";
|
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { fetchAdminUI } from "../context/auth/admin-ui-endpoint";
|
import { fetchAdminUI } from "../context/auth/admin-ui-endpoint";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
import type TestLdapConnectionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/testLdapConnection";
|
import type TestLdapConnectionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/testLdapConnection";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
PasswordControl,
|
||||||
|
SelectControl,
|
||||||
|
SelectVariant,
|
||||||
|
TextControl,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
Button,
|
Button,
|
||||||
|
@ -15,21 +23,11 @@ import {
|
||||||
useWatch,
|
useWatch,
|
||||||
} from "react-hook-form";
|
} from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
|
||||||
HelpItem,
|
|
||||||
PasswordControl,
|
|
||||||
SelectControl,
|
|
||||||
TextControl,
|
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { FormAccess } from "../../components/form/FormAccess";
|
import { FormAccess } from "../../components/form/FormAccess";
|
||||||
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type LdapSettingsConnectionProps = {
|
export type LdapSettingsConnectionProps = {
|
||||||
form: UseFormReturn;
|
form: UseFormReturn;
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
TextControl,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, SelectOption } from "@patternfly/react-core";
|
||||||
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Controller, FormProvider, UseFormReturn } from "react-hook-form";
|
import { Controller, FormProvider, UseFormReturn } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FormAccess } from "../../components/form/FormAccess";
|
import { FormAccess } from "../../components/form/FormAccess";
|
||||||
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type LdapSettingsGeneralProps = {
|
export type LdapSettingsGeneralProps = {
|
||||||
form: UseFormReturn<ComponentRepresentation>;
|
form: UseFormReturn<ComponentRepresentation>;
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||||
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
|
||||||
import { DirectionType } from "@keycloak/keycloak-admin-client/lib/resources/userStorageProvider";
|
import { DirectionType } from "@keycloak/keycloak-admin-client/lib/resources/userStorageProvider";
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectVariant,
|
||||||
|
TextControl,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
@ -15,7 +21,6 @@ import { useState } from "react";
|
||||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { useAdminClient } from "../../../admin-client";
|
import { useAdminClient } from "../../../admin-client";
|
||||||
import { useAlerts } from "../../../components/alert/Alerts";
|
import { useAlerts } from "../../../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
|
||||||
|
@ -32,10 +37,6 @@ import { useFetch } from "../../../utils/useFetch";
|
||||||
import { useParams } from "../../../utils/useParams";
|
import { useParams } from "../../../utils/useParams";
|
||||||
import { toUserFederationLdap } from "../../routes/UserFederationLdap";
|
import { toUserFederationLdap } from "../../routes/UserFederationLdap";
|
||||||
import { UserFederationLdapMapperParams } from "../../routes/UserFederationLdapMapper";
|
import { UserFederationLdapMapperParams } from "../../routes/UserFederationLdapMapper";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export default function LdapMapperDetails() {
|
export default function LdapMapperDetails() {
|
||||||
const { adminClient } = useAdminClient();
|
const { adminClient } = useAdminClient();
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
|
import {
|
||||||
|
HelpItem,
|
||||||
|
KeycloakSelect,
|
||||||
|
SelectControl,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { FormGroup, NumberInput, SelectOption } from "@patternfly/react-core";
|
import { FormGroup, NumberInput, SelectOption } from "@patternfly/react-core";
|
||||||
import { isEqual } from "lodash-es";
|
import { isEqual } from "lodash-es";
|
||||||
import { Controller, UseFormReturn, useWatch } from "react-hook-form";
|
import { Controller, UseFormReturn, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FormAccess } from "../../components/form/FormAccess";
|
import { FormAccess } from "../../components/form/FormAccess";
|
||||||
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
|
||||||
import useToggle from "../../utils/useToggle";
|
import useToggle from "../../utils/useToggle";
|
||||||
import {
|
|
||||||
KeycloakSelect,
|
|
||||||
SelectVariant,
|
|
||||||
} from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type SettingsCacheProps = {
|
export type SettingsCacheProps = {
|
||||||
form: UseFormReturn;
|
form: UseFormReturn;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { KeycloakSelect } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
DropdownItem,
|
DropdownItem,
|
||||||
|
@ -9,7 +10,6 @@ import {
|
||||||
import { FilterIcon } from "@patternfly/react-icons";
|
import { FilterIcon } from "@patternfly/react-icons";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { KeycloakSelect } from "../../components/select/KeycloakSelect";
|
|
||||||
|
|
||||||
export type SearchType = "default" | "attribute";
|
export type SearchType = "default" | "attribute";
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,6 @@ export const SingleSelectControl = <
|
||||||
} = useFormContext();
|
} = useFormContext();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const convert = () =>
|
|
||||||
options.map((option) => (
|
|
||||||
<SelectOption key={key(option)} value={key(option)}>
|
|
||||||
{isString(option) ? option : option.value}
|
|
||||||
</SelectOption>
|
|
||||||
));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormLabel
|
<FormLabel
|
||||||
name={name}
|
name={name}
|
||||||
|
@ -62,6 +55,7 @@ export const SingleSelectControl = <
|
||||||
<Select
|
<Select
|
||||||
{...rest}
|
{...rest}
|
||||||
onClick={() => setOpen(!open)}
|
onClick={() => setOpen(!open)}
|
||||||
|
onOpenChange={() => setOpen(false)}
|
||||||
selected={
|
selected={
|
||||||
isSelectBasedOptions(options)
|
isSelectBasedOptions(options)
|
||||||
? options
|
? options
|
||||||
|
@ -84,28 +78,27 @@ export const SingleSelectControl = <
|
||||||
aria-label="toggle"
|
aria-label="toggle"
|
||||||
>
|
>
|
||||||
{isSelectBasedOptions(options)
|
{isSelectBasedOptions(options)
|
||||||
? options.find((o) => o.key === value)?.value
|
? options.find(
|
||||||
|
(o) =>
|
||||||
|
o.key === (Array.isArray(value) ? value[0] : value),
|
||||||
|
)?.value
|
||||||
: value}
|
: value}
|
||||||
</MenuToggle>
|
</MenuToggle>
|
||||||
)}
|
)}
|
||||||
onSelect={(event, v) => {
|
onSelect={(_event, v) => {
|
||||||
event?.stopPropagation();
|
const option = v?.toString();
|
||||||
if (Array.isArray(value)) {
|
onChange(Array.isArray(value) ? [option] : option);
|
||||||
const option = v?.toString();
|
setOpen(false);
|
||||||
const selected = key(option!);
|
|
||||||
if (value.includes(key)) {
|
|
||||||
onChange(value.filter((item: string) => item !== selected));
|
|
||||||
} else {
|
|
||||||
onChange([...value, option]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onChange(v);
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
>
|
>
|
||||||
<SelectList>{convert()}</SelectList>
|
<SelectList>
|
||||||
|
{options.map((option) => (
|
||||||
|
<SelectOption key={key(option)} value={key(option)}>
|
||||||
|
{isString(option) ? option : option.value}
|
||||||
|
</SelectOption>
|
||||||
|
))}
|
||||||
|
</SelectList>
|
||||||
</Select>
|
</Select>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -89,11 +89,14 @@ export const TypeaheadSelectControl = <
|
||||||
|
|
||||||
if (variant !== SelectVariant.typeaheadMulti) {
|
if (variant !== SelectVariant.typeaheadMulti) {
|
||||||
setFilterValue(getValue(focusedItem));
|
setFilterValue(getValue(focusedItem));
|
||||||
|
} else {
|
||||||
|
setFilterValue("");
|
||||||
}
|
}
|
||||||
|
|
||||||
field.onChange(
|
field.onChange(
|
||||||
Array.isArray(field.value)
|
Array.isArray(field.value)
|
||||||
? [...field.value, getValue(focusedItem)]
|
? [...field.value, key(focusedItem)]
|
||||||
: getValue(focusedItem),
|
: key(focusedItem),
|
||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setFocusedItemIndex(0);
|
setFocusedItemIndex(0);
|
||||||
|
@ -106,6 +109,12 @@ export const TypeaheadSelectControl = <
|
||||||
field.onChange(undefined);
|
field.onChange(undefined);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "Backspace": {
|
||||||
|
if (variant === SelectVariant.typeahead) {
|
||||||
|
field.onChange("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
case "ArrowDown": {
|
case "ArrowDown": {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -150,6 +159,7 @@ export const TypeaheadSelectControl = <
|
||||||
<Select
|
<Select
|
||||||
{...rest}
|
{...rest}
|
||||||
onClick={() => setOpen(!open)}
|
onClick={() => setOpen(!open)}
|
||||||
|
onOpenChange={() => setOpen(false)}
|
||||||
selected={
|
selected={
|
||||||
isSelectBasedOptions(options)
|
isSelectBasedOptions(options)
|
||||||
? options
|
? options
|
||||||
|
@ -174,7 +184,19 @@ export const TypeaheadSelectControl = <
|
||||||
<TextInputGroup isPlain>
|
<TextInputGroup isPlain>
|
||||||
<TextInputGroupMain
|
<TextInputGroupMain
|
||||||
placeholder={placeholderText}
|
placeholder={placeholderText}
|
||||||
value={filterValue}
|
value={
|
||||||
|
variant === SelectVariant.typeahead && field.value
|
||||||
|
? isSelectBasedOptions(options)
|
||||||
|
? options.find(
|
||||||
|
(o) =>
|
||||||
|
o.key ===
|
||||||
|
(Array.isArray(field.value)
|
||||||
|
? field.value[0]
|
||||||
|
: field.value),
|
||||||
|
)?.value
|
||||||
|
: field.value
|
||||||
|
: filterValue
|
||||||
|
}
|
||||||
onClick={() => setOpen(!open)}
|
onClick={() => setOpen(!open)}
|
||||||
onChange={(_, value) => {
|
onChange={(_, value) => {
|
||||||
setFilterValue(value);
|
setFilterValue(value);
|
||||||
|
@ -234,21 +256,19 @@ export const TypeaheadSelectControl = <
|
||||||
onSelect={(event, v) => {
|
onSelect={(event, v) => {
|
||||||
event?.stopPropagation();
|
event?.stopPropagation();
|
||||||
const option = v?.toString();
|
const option = v?.toString();
|
||||||
if (Array.isArray(field.value)) {
|
if (
|
||||||
const select = key(option!);
|
variant === SelectVariant.typeaheadMulti &&
|
||||||
if (field.value.includes(key)) {
|
Array.isArray(field.value)
|
||||||
|
) {
|
||||||
|
if (field.value.includes(option)) {
|
||||||
field.onChange(
|
field.onChange(
|
||||||
field.value.filter((item: string) => item !== select),
|
field.value.filter((item: string) => item !== option),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
field.onChange([...field.value, option]);
|
field.onChange([...field.value, option]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const val = isSelectBasedOptions(options)
|
field.onChange(Array.isArray(field.value) ? [option] : option);
|
||||||
? options.find((o) => o.key === option)?.value
|
|
||||||
: option;
|
|
||||||
field.onChange(val);
|
|
||||||
setFilterValue(val || "");
|
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -58,3 +58,5 @@ export { isDefined } from "./utils/isDefined";
|
||||||
export { useRequiredContext } from "./utils/useRequiredContext";
|
export { useRequiredContext } from "./utils/useRequiredContext";
|
||||||
export { useStoredState } from "./utils/useStoredState";
|
export { useStoredState } from "./utils/useStoredState";
|
||||||
export { default as KeycloakMasthead } from "./masthead/Masthead";
|
export { default as KeycloakMasthead } from "./masthead/Masthead";
|
||||||
|
export { KeycloakSelect } from "./select/KeycloakSelect";
|
||||||
|
export type { Variant, KeycloakSelectProps } from "./select/KeycloakSelect";
|
||||||
|
|
|
@ -54,6 +54,7 @@ export const SingleSelect = ({
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
onClick={toggle}
|
onClick={toggle}
|
||||||
|
onOpenChange={() => setOpen(false)}
|
||||||
selected={selections}
|
selected={selections}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onSelect?.(value || "");
|
onSelect?.(value || "");
|
|
@ -75,6 +75,12 @@ export const TypeaheadSelect = ({
|
||||||
onToggle?.(false);
|
onToggle?.(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "Backspace": {
|
||||||
|
if (variant === SelectVariant.typeahead) {
|
||||||
|
onSelect?.("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
case "ArrowDown": {
|
case "ArrowDown": {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -107,6 +113,7 @@ export const TypeaheadSelect = ({
|
||||||
<Select
|
<Select
|
||||||
{...rest}
|
{...rest}
|
||||||
onClick={toggle}
|
onClick={toggle}
|
||||||
|
onOpenChange={() => onToggle?.(false)}
|
||||||
onSelect={(_, value) => onSelect?.(value || "")}
|
onSelect={(_, value) => onSelect?.(value || "")}
|
||||||
maxMenuHeight={propertyToString(maxHeight)}
|
maxMenuHeight={propertyToString(maxHeight)}
|
||||||
popperProps={{ direction, width: propertyToString(width) }}
|
popperProps={{ direction, width: propertyToString(width) }}
|
||||||
|
@ -124,7 +131,11 @@ export const TypeaheadSelect = ({
|
||||||
<TextInputGroup isPlain>
|
<TextInputGroup isPlain>
|
||||||
<TextInputGroupMain
|
<TextInputGroupMain
|
||||||
placeholder={placeholderText}
|
placeholder={placeholderText}
|
||||||
value={filterValue}
|
value={
|
||||||
|
variant === SelectVariant.typeahead && selections
|
||||||
|
? (selections as string)
|
||||||
|
: filterValue
|
||||||
|
}
|
||||||
onClick={toggle}
|
onClick={toggle}
|
||||||
onChange={(_, value) => {
|
onChange={(_, value) => {
|
||||||
setFilterValue(value);
|
setFilterValue(value);
|
||||||
|
@ -165,6 +176,7 @@ export const TypeaheadSelect = ({
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onSelect?.("");
|
onSelect?.("");
|
||||||
setFilterValue("");
|
setFilterValue("");
|
||||||
|
onFilter?.("");
|
||||||
textInputRef?.current?.focus();
|
textInputRef?.current?.focus();
|
||||||
}}
|
}}
|
||||||
aria-label="Clear input value"
|
aria-label="Clear input value"
|
|
@ -1,13 +1,7 @@
|
||||||
import {
|
import { SelectOption } from "@patternfly/react-core";
|
||||||
Chip,
|
|
||||||
ChipGroup,
|
|
||||||
MenuToggle,
|
|
||||||
Select,
|
|
||||||
SelectList,
|
|
||||||
SelectOption,
|
|
||||||
} from "@patternfly/react-core";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, ControllerRenderProps } from "react-hook-form";
|
import { Controller, ControllerRenderProps } from "react-hook-form";
|
||||||
|
import { KeycloakSelect, SelectVariant } from "../select/KeycloakSelect";
|
||||||
import {
|
import {
|
||||||
OptionLabel,
|
OptionLabel,
|
||||||
Options,
|
Options,
|
||||||
|
@ -19,6 +13,7 @@ import { UserFormFields, fieldName, label } from "./utils";
|
||||||
export const SelectComponent = (props: UserProfileFieldProps) => {
|
export const SelectComponent = (props: UserProfileFieldProps) => {
|
||||||
const { t, form, inputType, attribute } = props;
|
const { t, form, inputType, attribute } = props;
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
const [filter, setFilter] = useState("");
|
||||||
const isMultiValue = inputType === "multiselect";
|
const isMultiValue = inputType === "multiselect";
|
||||||
|
|
||||||
const setValue = (
|
const setValue = (
|
||||||
|
@ -36,7 +31,7 @@ export const SelectComponent = (props: UserProfileFieldProps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
field.onChange(value);
|
field.onChange(value === field.value ? "" : value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,9 +40,25 @@ export const SelectComponent = (props: UserProfileFieldProps) => {
|
||||||
|
|
||||||
const optionLabel =
|
const optionLabel =
|
||||||
(attribute.annotations?.["inputOptionLabels"] as OptionLabel) || {};
|
(attribute.annotations?.["inputOptionLabels"] as OptionLabel) || {};
|
||||||
|
|
||||||
const fetchLabel = (option: string) =>
|
const fetchLabel = (option: string) =>
|
||||||
label(props.t, optionLabel[option], option);
|
label(props.t, optionLabel[option], option);
|
||||||
|
|
||||||
|
const convertOptions = (selected: string) =>
|
||||||
|
options
|
||||||
|
.filter((o) =>
|
||||||
|
fetchLabel(o)!.toLowerCase().includes(filter.toLowerCase()),
|
||||||
|
)
|
||||||
|
.map((option) => (
|
||||||
|
<SelectOption
|
||||||
|
selected={selected === option}
|
||||||
|
key={option}
|
||||||
|
value={option}
|
||||||
|
>
|
||||||
|
{fetchLabel(option)}
|
||||||
|
</SelectOption>
|
||||||
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserProfileGroup {...props}>
|
<UserProfileGroup {...props}>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -55,58 +66,39 @@ export const SelectComponent = (props: UserProfileFieldProps) => {
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Select
|
<KeycloakSelect
|
||||||
toggle={(ref) => (
|
toggleId={attribute.name}
|
||||||
<MenuToggle
|
onToggle={(b) => setOpen(b)}
|
||||||
id={attribute.name}
|
onClear={() => setValue("", field)}
|
||||||
ref={ref}
|
onSelect={(value) => {
|
||||||
onClick={() => setOpen(!open)}
|
const option = value.toString();
|
||||||
isExpanded={open}
|
|
||||||
isFullWidth
|
|
||||||
isDisabled={attribute.readOnly}
|
|
||||||
>
|
|
||||||
{(isMultiValue && Array.isArray(field.value) ? (
|
|
||||||
<ChipGroup>
|
|
||||||
{field.value.map((selection, index: number) => (
|
|
||||||
<Chip
|
|
||||||
key={index}
|
|
||||||
onClick={(ev) => {
|
|
||||||
ev.stopPropagation();
|
|
||||||
setValue(selection, field);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{selection}
|
|
||||||
</Chip>
|
|
||||||
))}
|
|
||||||
</ChipGroup>
|
|
||||||
) : (
|
|
||||||
fetchLabel(field.value)
|
|
||||||
)) || t("choose")}
|
|
||||||
</MenuToggle>
|
|
||||||
)}
|
|
||||||
onSelect={(_, value) => {
|
|
||||||
const option = value?.toString() || "";
|
|
||||||
setValue(option, field);
|
setValue(option, field);
|
||||||
if (!isMultiValue) {
|
if (!Array.isArray(field.value)) {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
selected={field.value}
|
selections={
|
||||||
|
isMultiValue && Array.isArray(field.value)
|
||||||
|
? field.value
|
||||||
|
: fetchLabel(field.value)
|
||||||
|
}
|
||||||
|
variant={
|
||||||
|
isMultiValue
|
||||||
|
? SelectVariant.typeaheadMulti
|
||||||
|
: options.length >= 10
|
||||||
|
? SelectVariant.typeahead
|
||||||
|
: SelectVariant.single
|
||||||
|
}
|
||||||
aria-label={t("selectOne")}
|
aria-label={t("selectOne")}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
|
isDisabled={attribute.readOnly}
|
||||||
|
onFilter={(value) => {
|
||||||
|
setFilter(value);
|
||||||
|
return convertOptions(field.value);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<SelectList>
|
{convertOptions(field.value)}
|
||||||
{options.map((option) => (
|
</KeycloakSelect>
|
||||||
<SelectOption
|
|
||||||
selected={field.value === option}
|
|
||||||
key={option}
|
|
||||||
value={option}
|
|
||||||
>
|
|
||||||
{fetchLabel(option)}
|
|
||||||
</SelectOption>
|
|
||||||
))}
|
|
||||||
</SelectList>
|
|
||||||
</Select>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</UserProfileGroup>
|
</UserProfileGroup>
|
||||||
|
|
Loading…
Reference in a new issue