Add useToggle hook to manage toggleable state (#1600)
This commit is contained in:
parent
31e1415758
commit
61b2689864
33 changed files with 197 additions and 112 deletions
61
package-lock.json
generated
61
package-lock.json
generated
|
@ -38,6 +38,7 @@
|
||||||
"@testing-library/cypress": "^8.0.2",
|
"@testing-library/cypress": "^8.0.2",
|
||||||
"@testing-library/jest-dom": "^5.15.1",
|
"@testing-library/jest-dom": "^5.15.1",
|
||||||
"@testing-library/react": "^12.1.1",
|
"@testing-library/react": "^12.1.1",
|
||||||
|
"@testing-library/react-hooks": "^7.0.2",
|
||||||
"@types/dagre": "^0.7.45",
|
"@types/dagre": "^0.7.45",
|
||||||
"@types/file-saver": "^2.0.4",
|
"@types/file-saver": "^2.0.4",
|
||||||
"@types/lodash": "^4.14.177",
|
"@types/lodash": "^4.14.177",
|
||||||
|
@ -4483,6 +4484,35 @@
|
||||||
"react-dom": "*"
|
"react-dom": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@testing-library/react-hooks": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@types/react": ">=16.9.0",
|
||||||
|
"@types/react-dom": ">=16.9.0",
|
||||||
|
"@types/react-test-renderer": ">=16.9.0",
|
||||||
|
"react-error-boundary": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.9.0",
|
||||||
|
"react-dom": ">=16.9.0",
|
||||||
|
"react-test-renderer": ">=16.9.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-test-renderer": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tootallnate/once": {
|
"node_modules/@tootallnate/once": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
||||||
|
@ -5002,6 +5032,15 @@
|
||||||
"@types/react-router": "*"
|
"@types/react-router": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-test-renderer": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
|
@ -24660,6 +24699,19 @@
|
||||||
"@testing-library/dom": "^8.0.0"
|
"@testing-library/dom": "^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@testing-library/react-hooks": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@types/react": ">=16.9.0",
|
||||||
|
"@types/react-dom": ">=16.9.0",
|
||||||
|
"@types/react-test-renderer": ">=16.9.0",
|
||||||
|
"react-error-boundary": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@tootallnate/once": {
|
"@tootallnate/once": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
||||||
|
@ -25176,6 +25228,15 @@
|
||||||
"@types/react-router": "*"
|
"@types/react-router": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-test-renderer": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/resolve": {
|
"@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
"@testing-library/cypress": "^8.0.2",
|
"@testing-library/cypress": "^8.0.2",
|
||||||
"@testing-library/jest-dom": "^5.15.1",
|
"@testing-library/jest-dom": "^5.15.1",
|
||||||
"@testing-library/react": "^12.1.1",
|
"@testing-library/react": "^12.1.1",
|
||||||
|
"@testing-library/react-hooks": "^7.0.2",
|
||||||
"@types/dagre": "^0.7.45",
|
"@types/dagre": "^0.7.45",
|
||||||
"@types/file-saver": "^2.0.4",
|
"@types/file-saver": "^2.0.4",
|
||||||
"@types/lodash": "^4.14.177",
|
"@types/lodash": "^4.14.177",
|
||||||
|
|
|
@ -132,16 +132,12 @@ export const Header = () => {
|
||||||
const KebabDropdown = () => {
|
const KebabDropdown = () => {
|
||||||
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
||||||
|
|
||||||
const onDropdownToggle = () => {
|
|
||||||
setDropdownOpen(!isDropdownOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
id="user-dropdown-kebab"
|
id="user-dropdown-kebab"
|
||||||
isPlain
|
isPlain
|
||||||
position="right"
|
position="right"
|
||||||
toggle={<KebabToggle onToggle={onDropdownToggle} />}
|
toggle={<KebabToggle onToggle={setDropdownOpen} />}
|
||||||
isOpen={isDropdownOpen}
|
isOpen={isDropdownOpen}
|
||||||
dropdownItems={kebabDropdownItems}
|
dropdownItems={kebabDropdownItems}
|
||||||
/>
|
/>
|
||||||
|
@ -152,10 +148,6 @@ export const Header = () => {
|
||||||
const { whoAmI } = useWhoAmI();
|
const { whoAmI } = useWhoAmI();
|
||||||
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
const [isDropdownOpen, setDropdownOpen] = useState(false);
|
||||||
|
|
||||||
const onDropdownToggle = () => {
|
|
||||||
setDropdownOpen(!isDropdownOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
isPlain
|
isPlain
|
||||||
|
@ -163,7 +155,7 @@ export const Header = () => {
|
||||||
id="user-dropdown"
|
id="user-dropdown"
|
||||||
isOpen={isDropdownOpen}
|
isOpen={isDropdownOpen}
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle onToggle={onDropdownToggle}>
|
<DropdownToggle onToggle={setDropdownOpen}>
|
||||||
{whoAmI.getDisplayName()}
|
{whoAmI.getDisplayName()}
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { toUpperCase } from "../util";
|
import { toUpperCase } from "../util";
|
||||||
|
import useToggle from "../utils/useToggle";
|
||||||
import { DuplicateFlowModal } from "./DuplicateFlowModal";
|
import { DuplicateFlowModal } from "./DuplicateFlowModal";
|
||||||
import { toCreateFlow } from "./routes/CreateFlow";
|
import { toCreateFlow } from "./routes/CreateFlow";
|
||||||
import { toFlow } from "./routes/Flow";
|
import { toFlow } from "./routes/Flow";
|
||||||
|
@ -55,7 +56,7 @@ export default function AuthenticationSection() {
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
|
|
||||||
const [selectedFlow, setSelectedFlow] = useState<AuthenticationType>();
|
const [selectedFlow, setSelectedFlow] = useState<AuthenticationType>();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, toggleOpen, setOpen] = useToggle();
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
const clients = await adminClient.clients.find();
|
const clients = await adminClient.clients.find();
|
||||||
|
@ -202,7 +203,7 @@ export default function AuthenticationSection() {
|
||||||
<DuplicateFlowModal
|
<DuplicateFlowModal
|
||||||
name={selectedFlow ? selectedFlow.alias! : ""}
|
name={selectedFlow ? selectedFlow.alias! : ""}
|
||||||
description={selectedFlow?.description!}
|
description={selectedFlow?.description!}
|
||||||
toggleDialog={() => setOpen(!open)}
|
toggleDialog={toggleOpen}
|
||||||
onComplete={() => {
|
onComplete={() => {
|
||||||
refresh();
|
refresh();
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
|
@ -40,6 +40,7 @@ import { AddSubFlowModal, Flow } from "./components/modals/AddSubFlowModal";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { DuplicateFlowModal } from "./DuplicateFlowModal";
|
import { DuplicateFlowModal } from "./DuplicateFlowModal";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
import useToggle from "../utils/useToggle";
|
||||||
import { toAuthentication } from "./routes/Authentication";
|
import { toAuthentication } from "./routes/Authentication";
|
||||||
import { EditFlowModal } from "./EditFlowModal";
|
import { EditFlowModal } from "./EditFlowModal";
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ export default function FlowDetails() {
|
||||||
const [showAddSubFlowDialog, setShowSubFlowDialog] = useState<boolean>();
|
const [showAddSubFlowDialog, setShowSubFlowDialog] = useState<boolean>();
|
||||||
const [selectedExecution, setSelectedExecution] =
|
const [selectedExecution, setSelectedExecution] =
|
||||||
useState<ExpandableExecution>();
|
useState<ExpandableExecution>();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, toggleOpen, setOpen] = useToggle();
|
||||||
const [edit, setEdit] = useState(false);
|
const [edit, setEdit] = useState(false);
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
@ -280,7 +281,7 @@ export default function FlowDetails() {
|
||||||
<DuplicateFlowModal
|
<DuplicateFlowModal
|
||||||
name={flow?.alias!}
|
name={flow?.alias!}
|
||||||
description={flow?.description!}
|
description={flow?.description!}
|
||||||
toggleDialog={() => setOpen(!open)}
|
toggleDialog={toggleOpen}
|
||||||
onComplete={() => {
|
onComplete={() => {
|
||||||
refresh();
|
refresh();
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const EditFlowDropdown = ({
|
||||||
data-testid={`${execution.displayName}-edit-dropdown`}
|
data-testid={`${execution.displayName}-edit-dropdown`}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle onToggle={(open) => setOpen(open)}>
|
<DropdownToggle onToggle={setOpen}>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const FlowRequirementDropdown = ({
|
||||||
<Select
|
<Select
|
||||||
className="keycloak__authentication__requirement-dropdown"
|
className="keycloak__authentication__requirement-dropdown"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setOpen(!open)}
|
onToggle={setOpen}
|
||||||
onSelect={(_event, value) => {
|
onSelect={(_event, value) => {
|
||||||
flow.requirement = value.toString();
|
flow.requirement = value.toString();
|
||||||
onChange(flow);
|
onChange(flow);
|
||||||
|
|
|
@ -151,7 +151,7 @@ export const AddSubFlowModal = ({
|
||||||
<Select
|
<Select
|
||||||
menuAppendTo="parent"
|
menuAppendTo="parent"
|
||||||
toggleId="flowType"
|
toggleId="flowType"
|
||||||
onToggle={() => setOpen(!open)}
|
onToggle={setOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
@ -194,9 +194,9 @@ export const AddSubFlowModal = ({
|
||||||
<Select
|
<Select
|
||||||
menuAppendTo="parent"
|
menuAppendTo="parent"
|
||||||
toggleId="provider"
|
toggleId="provider"
|
||||||
onToggle={(toggle) => setOpenProvider(toggle)}
|
onToggle={setOpenProvider}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value.toString());
|
||||||
setOpenProvider(false);
|
setOpenProvider(false);
|
||||||
}}
|
}}
|
||||||
selections={value.displayName}
|
selections={value.displayName}
|
||||||
|
|
|
@ -37,9 +37,9 @@ export const FlowType = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="flowType"
|
toggleId="flowType"
|
||||||
onToggle={() => setOpen(!open)}
|
onToggle={setOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value.toString());
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={t(`top-level-flow-type.${value}`)}
|
selections={t(`top-level-flow-type.${value}`)}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export const ChangeTypeDropdown = ({
|
||||||
selections={[]}
|
selections={[]}
|
||||||
isDisabled={selectedRows.length === 0}
|
isDisabled={selectedRows.length === 0}
|
||||||
placeholderText={t("changeTypeTo")}
|
placeholderText={t("changeTypeTo")}
|
||||||
onToggle={(isExpanded) => setOpen(isExpanded)}
|
onToggle={setOpen}
|
||||||
onSelect={async (_, value) => {
|
onSelect={async (_, value) => {
|
||||||
try {
|
try {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
|
|
|
@ -221,9 +221,7 @@ export default function ClientScopesSection() {
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
toggle={
|
toggle={<KebabToggle onToggle={setKebabOpen} />}
|
||||||
<KebabToggle onToggle={() => setKebabOpen(!kebabOpen)} />
|
|
||||||
}
|
|
||||||
isOpen={kebabOpen}
|
isOpen={kebabOpen}
|
||||||
isPlain
|
isPlain
|
||||||
dropdownItems={[
|
dropdownItems={[
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* @jest-environment jsdom
|
* @jest-environment jsdom
|
||||||
*/
|
*/
|
||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
import { fireEvent, render, screen } from "@testing-library/react";
|
import { fireEvent, render, screen } from "@testing-library/react";
|
||||||
import { Button } from "@patternfly/react-core";
|
import { Button } from "@patternfly/react-core";
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/l
|
||||||
import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
||||||
import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider";
|
import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider";
|
||||||
import serverInfo from "../../context/server-info/__tests__/mock.json";
|
import serverInfo from "../../context/server-info/__tests__/mock.json";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
import { AddMapperDialog, AddMapperDialogModalProps } from "./MapperDialog";
|
import { AddMapperDialog, AddMapperDialogModalProps } from "./MapperDialog";
|
||||||
import { WhoAmI, WhoAmIContext } from "../../context/whoami/WhoAmI";
|
import { WhoAmI, WhoAmIContext } from "../../context/whoami/WhoAmI";
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ import whoami from "../../context/whoami/__tests__/mock-whoami.json";
|
||||||
|
|
||||||
describe("MapperDialog", () => {
|
describe("MapperDialog", () => {
|
||||||
const Test = (args: AddMapperDialogModalProps) => {
|
const Test = (args: AddMapperDialogModalProps) => {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, toggleOpen, setOpen] = useToggle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ServerInfoContext.Provider
|
<ServerInfoContext.Provider
|
||||||
|
@ -28,11 +29,7 @@ describe("MapperDialog", () => {
|
||||||
whoAmI: new WhoAmI(whoami as WhoAmIRepresentation),
|
whoAmI: new WhoAmI(whoami as WhoAmIRepresentation),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AddMapperDialog
|
<AddMapperDialog {...args} open={open} toggleDialog={toggleOpen} />
|
||||||
{...args}
|
|
||||||
open={open}
|
|
||||||
toggleDialog={() => setOpen(!open)}
|
|
||||||
/>
|
|
||||||
<Button onClick={() => setOpen(true)}>
|
<Button onClick={() => setOpen(true)}>
|
||||||
{!open ? "Show" : "Hide"}
|
{!open ? "Show" : "Hide"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -142,7 +142,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
isOpen={openType}
|
isOpen={openType}
|
||||||
selections={value}
|
selections={value}
|
||||||
onToggle={() => setOpenType(!openType)}
|
onToggle={setOpenType}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setOpenType(false);
|
setOpenType(false);
|
||||||
|
@ -173,7 +173,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
<Select
|
<Select
|
||||||
toggleId="kc-protocol"
|
toggleId="kc-protocol"
|
||||||
required
|
required
|
||||||
onToggle={() => isOpen(!open)}
|
onToggle={isOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
isOpen(false);
|
isOpen(false);
|
||||||
|
|
|
@ -72,10 +72,7 @@ export const SearchDropdown = ({
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="keycloak__client-scopes__searchtype"
|
className="keycloak__client-scopes__searchtype"
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle
|
<DropdownToggle id="toggle-id" onToggle={setSearchToggle}>
|
||||||
id="toggle-id"
|
|
||||||
onToggle={(open) => setSearchToggle(open)}
|
|
||||||
>
|
|
||||||
<FilterIcon /> {t(`clientScopeSearch.${searchType}`)}
|
<FilterIcon /> {t(`clientScopeSearch.${searchType}`)}
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
}
|
}
|
||||||
|
@ -110,7 +107,7 @@ export const SearchToolbar = ({
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Select
|
<Select
|
||||||
className="keycloak__client-scopes__searchtype"
|
className="keycloak__client-scopes__searchtype"
|
||||||
onToggle={(open) => setOpen(open)}
|
onToggle={setOpen}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
selections={[
|
selections={[
|
||||||
type === AllClientScopes.none
|
type === AllClientScopes.none
|
||||||
|
@ -142,7 +139,7 @@ export const SearchToolbar = ({
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Select
|
<Select
|
||||||
className="keycloak__client-scopes__searchtype"
|
className="keycloak__client-scopes__searchtype"
|
||||||
onToggle={(open) => setOpen(open)}
|
onToggle={setOpen}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
selections={[t(`protocolTypes.${protocol}`)]}
|
selections={[t(`protocolTypes.${protocol}`)]}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import {
|
||||||
ClientScopeDefaultOptionalType,
|
ClientScopeDefaultOptionalType,
|
||||||
} from "../../components/client-scope/ClientScopeTypes";
|
} from "../../components/client-scope/ClientScopeTypes";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
import { toMapper } from "../routes/Mapper";
|
import { toMapper } from "../routes/Mapper";
|
||||||
import { toClientScope } from "../routes/ClientScope";
|
import { toClientScope } from "../routes/ClientScope";
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ export default function ClientScopeForm() {
|
||||||
useState<ClientScopeDefaultOptionalType>();
|
useState<ClientScopeDefaultOptionalType>();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
const [hide, setHide] = useState(false);
|
const [hide, toggleHide] = useToggle();
|
||||||
|
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const { id, type } = useParams<{ id: string; type: AllClientScopes }>();
|
const { id, type } = useParams<{ id: string; type: AllClientScopes }>();
|
||||||
|
@ -249,7 +250,7 @@ export default function ClientScopeForm() {
|
||||||
dropdownItems={
|
dropdownItems={
|
||||||
clientScope
|
clientScope
|
||||||
? [
|
? [
|
||||||
<DropdownItem key="delete" onClick={() => toggleDeleteDialog()}>
|
<DropdownItem key="delete" onClick={toggleDeleteDialog}>
|
||||||
{t("common:delete")}
|
{t("common:delete")}
|
||||||
</DropdownItem>,
|
</DropdownItem>,
|
||||||
]
|
]
|
||||||
|
@ -299,7 +300,7 @@ export default function ClientScopeForm() {
|
||||||
type={"client-scope"}
|
type={"client-scope"}
|
||||||
loader={loader}
|
loader={loader}
|
||||||
save={assignRoles}
|
save={assignRoles}
|
||||||
onHideRolesToggle={() => setHide(!hide)}
|
onHideRolesToggle={toggleHide}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
</KeycloakTabs>
|
</KeycloakTabs>
|
||||||
|
|
|
@ -300,7 +300,7 @@ export const AdvancedTab = ({
|
||||||
/>
|
/>
|
||||||
<ExpandableSection
|
<ExpandableSection
|
||||||
toggleText={t("registeredClusterNodes")}
|
toggleText={t("registeredClusterNodes")}
|
||||||
onToggle={() => setExpanded(!expanded)}
|
onToggle={setExpanded}
|
||||||
isExpanded={expanded}
|
isExpanded={expanded}
|
||||||
>
|
>
|
||||||
<KeycloakDataTable
|
<KeycloakDataTable
|
||||||
|
|
|
@ -43,6 +43,7 @@ import {
|
||||||
convertToFormValues,
|
convertToFormValues,
|
||||||
exportClient,
|
exportClient,
|
||||||
} from "../util";
|
} from "../util";
|
||||||
|
import useToggle from "../utils/useToggle";
|
||||||
import { AdvancedTab } from "./AdvancedTab";
|
import { AdvancedTab } from "./AdvancedTab";
|
||||||
import { ClientSettings } from "./ClientSettings";
|
import { ClientSettings } from "./ClientSettings";
|
||||||
import { Credentials } from "./credentials/Credentials";
|
import { Credentials } from "./credentials/Credentials";
|
||||||
|
@ -115,7 +116,7 @@ const ClientDetailHeader = ({
|
||||||
}, [client, t]);
|
}, [client, t]);
|
||||||
|
|
||||||
const dropdownItems = [
|
const dropdownItems = [
|
||||||
<DropdownItem key="download" onClick={() => toggleDownloadDialog()}>
|
<DropdownItem key="download" onClick={toggleDownloadDialog}>
|
||||||
{t("downloadAdapterConfig")}
|
{t("downloadAdapterConfig")}
|
||||||
</DropdownItem>,
|
</DropdownItem>,
|
||||||
<DropdownItem key="export" onClick={() => exportClient(client)}>
|
<DropdownItem key="export" onClick={() => exportClient(client)}>
|
||||||
|
@ -127,7 +128,7 @@ const ClientDetailHeader = ({
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
data-testid="delete-client"
|
data-testid="delete-client"
|
||||||
key="delete"
|
key="delete"
|
||||||
onClick={() => toggleDeleteDialog()}
|
onClick={toggleDeleteDialog}
|
||||||
>
|
>
|
||||||
{t("common:delete")}
|
{t("common:delete")}
|
||||||
</DropdownItem>,
|
</DropdownItem>,
|
||||||
|
@ -180,11 +181,8 @@ export default function ClientDetails() {
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false);
|
const [downloadDialogOpen, toggleDownloadDialogOpen] = useToggle();
|
||||||
const toggleDownloadDialog = () => setDownloadDialogOpen(!downloadDialogOpen);
|
const [changeAuthenticatorOpen, toggleChangeAuthenticatorOpen] = useToggle();
|
||||||
const [changeAuthenticatorOpen, setChangeAuthenticatorOpen] = useState(false);
|
|
||||||
const toggleChangeAuthenticator = () =>
|
|
||||||
setChangeAuthenticatorOpen(!changeAuthenticatorOpen);
|
|
||||||
const [clientScopeSubTab, setClientScopeSubTab] = useState(30);
|
const [clientScopeSubTab, setClientScopeSubTab] = useState(30);
|
||||||
const [authorizationSubTab, setAuthorizationSubTab] = useState(40);
|
const [authorizationSubTab, setAuthorizationSubTab] = useState(40);
|
||||||
|
|
||||||
|
@ -259,7 +257,7 @@ export default function ClientDetails() {
|
||||||
client?.clientAuthenticatorType !== clientAuthenticatorType &&
|
client?.clientAuthenticatorType !== clientAuthenticatorType &&
|
||||||
!confirmed
|
!confirmed
|
||||||
) {
|
) {
|
||||||
toggleChangeAuthenticator();
|
toggleChangeAuthenticatorOpen();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
||||||
|
@ -343,7 +341,7 @@ export default function ClientDetails() {
|
||||||
clientAuthenticatorType: clientAuthenticatorType,
|
clientAuthenticatorType: clientAuthenticatorType,
|
||||||
})}
|
})}
|
||||||
open={changeAuthenticatorOpen}
|
open={changeAuthenticatorOpen}
|
||||||
toggleDialog={toggleChangeAuthenticator}
|
toggleDialog={toggleChangeAuthenticatorOpen}
|
||||||
onConfirm={() => save({ confirmed: true })}
|
onConfirm={() => save({ confirmed: true })}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
|
@ -360,7 +358,7 @@ export default function ClientDetails() {
|
||||||
id={client.id!}
|
id={client.id!}
|
||||||
protocol={client.protocol}
|
protocol={client.protocol}
|
||||||
open={downloadDialogOpen}
|
open={downloadDialogOpen}
|
||||||
toggleDialog={toggleDownloadDialog}
|
toggleDialog={toggleDownloadDialogOpen}
|
||||||
/>
|
/>
|
||||||
<Controller
|
<Controller
|
||||||
name="enabled"
|
name="enabled"
|
||||||
|
@ -373,7 +371,7 @@ export default function ClientDetails() {
|
||||||
client={client}
|
client={client}
|
||||||
save={save}
|
save={save}
|
||||||
toggleDeleteDialog={toggleDeleteDialog}
|
toggleDeleteDialog={toggleDeleteDialog}
|
||||||
toggleDownloadDialog={toggleDownloadDialog}
|
toggleDownloadDialog={toggleDownloadDialogOpen}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -182,9 +182,9 @@ export const ClientSettings = ({
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="loginTheme"
|
toggleId="loginTheme"
|
||||||
onToggle={() => setLoginThemeOpen(!loginThemeOpen)}
|
onToggle={setLoginThemeOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value.toString());
|
||||||
setLoginThemeOpen(false);
|
setLoginThemeOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={value || t("common:choose")}
|
selections={value || t("common:choose")}
|
||||||
|
|
|
@ -42,9 +42,9 @@ export const GeneralSettings = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
id="kc-type"
|
id="kc-type"
|
||||||
onToggle={() => isOpen(!open)}
|
onToggle={isOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value.toString());
|
||||||
isOpen(false);
|
isOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={value}
|
selections={value}
|
||||||
|
|
|
@ -78,7 +78,7 @@ export const SamlConfig = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="samlNameIdFormat"
|
toggleId="samlNameIdFormat"
|
||||||
onToggle={(open) => setNameFormatOpen(open)}
|
onToggle={setNameFormatOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
setNameFormatOpen(false);
|
setNameFormatOpen(false);
|
||||||
|
|
|
@ -85,7 +85,7 @@ export const SamlSignature = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="signatureAlgorithm"
|
toggleId="signatureAlgorithm"
|
||||||
onToggle={(open) => setAlgOpen(open)}
|
onToggle={setAlgOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
setAlgOpen(false);
|
setAlgOpen(false);
|
||||||
|
@ -126,7 +126,7 @@ export const SamlSignature = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="signatureKeyName"
|
toggleId="signatureKeyName"
|
||||||
onToggle={(open) => setKeyOpen(open)}
|
onToggle={setKeyOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
setKeyOpen(false);
|
setKeyOpen(false);
|
||||||
|
@ -167,7 +167,7 @@ export const SamlSignature = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="canonicalization"
|
toggleId="canonicalization"
|
||||||
onToggle={(open) => setCanOpen(open)}
|
onToggle={setCanOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
setCanOpen(false);
|
setCanOpen(false);
|
||||||
|
|
|
@ -118,7 +118,7 @@ export const AdvancedSettings = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="keyForCodeExchange"
|
toggleId="keyForCodeExchange"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setOpen(!open)}
|
onToggle={setOpen}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
|
|
@ -76,7 +76,7 @@ export const AuthenticationOverrides = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="browserFlow"
|
toggleId="browserFlow"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setBrowserFlowOpen(!browserFlowOpen)}
|
onToggle={setBrowserFlowOpen}
|
||||||
isOpen={browserFlowOpen}
|
isOpen={browserFlowOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -109,7 +109,7 @@ export const AuthenticationOverrides = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="directGrant"
|
toggleId="directGrant"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setDirectGrantOpen(!directGrantOpen)}
|
onToggle={setDirectGrantOpen}
|
||||||
isOpen={directGrantOpen}
|
isOpen={directGrantOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
|
|
@ -125,7 +125,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="accessTokenSignatureAlgorithm"
|
toggleId="accessTokenSignatureAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setAccessTokenOpen(!accessTokenOpen)}
|
onToggle={setAccessTokenOpen}
|
||||||
isOpen={accessTokenOpen}
|
isOpen={accessTokenOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -157,7 +157,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="idTokenSignatureAlgorithm"
|
toggleId="idTokenSignatureAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setIdTokenOpen(!idTokenOpen)}
|
onToggle={setIdTokenOpen}
|
||||||
isOpen={idTokenOpen}
|
isOpen={idTokenOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -189,9 +189,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="idTokenEncryptionKeyManagementAlgorithm"
|
toggleId="idTokenEncryptionKeyManagementAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() =>
|
onToggle={setIdTokenKeyManagementOpen}
|
||||||
setIdTokenKeyManagementOpen(!idTokenKeyManagementOpen)
|
|
||||||
}
|
|
||||||
isOpen={idTokenKeyManagementOpen}
|
isOpen={idTokenKeyManagementOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -223,7 +221,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="idTokenEncryptionContentEncryptionAlgorithm"
|
toggleId="idTokenEncryptionContentEncryptionAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() => setIdTokenContentOpen(!idTokenContentOpen)}
|
onToggle={setIdTokenContentOpen}
|
||||||
isOpen={idTokenContentOpen}
|
isOpen={idTokenContentOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -255,9 +253,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="userInfoSignedResponseAlgorithm"
|
toggleId="userInfoSignedResponseAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() =>
|
onToggle={setUserInfoSignedResponseOpen}
|
||||||
setUserInfoSignedResponseOpen(!userInfoSignedResponseOpen)
|
|
||||||
}
|
|
||||||
isOpen={userInfoSignedResponseOpen}
|
isOpen={userInfoSignedResponseOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -289,9 +285,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="requestObjectSignatureAlgorithm"
|
toggleId="requestObjectSignatureAlgorithm"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() =>
|
onToggle={setRequestObjectSignatureOpen}
|
||||||
setRequestObjectSignatureOpen(!requestObjectSignatureOpen)
|
|
||||||
}
|
|
||||||
isOpen={requestObjectSignatureOpen}
|
isOpen={requestObjectSignatureOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
@ -323,9 +317,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
<Select
|
<Select
|
||||||
toggleId="requestObjectRequired"
|
toggleId="requestObjectRequired"
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={() =>
|
onToggle={setRequestObjectRequiredOpen}
|
||||||
setRequestObjectRequiredOpen(!requestObjectRequiredOpen)
|
|
||||||
}
|
|
||||||
isOpen={requestObjectRequiredOpen}
|
isOpen={requestObjectRequiredOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
|
|
@ -67,7 +67,7 @@ export const TokenLifespan = ({
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<Select
|
<Select
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
onToggle={(isExpanded) => setOpen(isExpanded)}
|
onToggle={setOpen}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
|
|
|
@ -155,7 +155,7 @@ export const Credentials = ({ clientId, save }: CredentialsProps) => {
|
||||||
<Select
|
<Select
|
||||||
toggleId="kc-client-authenticator-type"
|
toggleId="kc-client-authenticator-type"
|
||||||
required
|
required
|
||||||
onToggle={() => isOpen(!open)}
|
onToggle={isOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
isOpen(false);
|
isOpen(false);
|
||||||
|
|
|
@ -40,9 +40,9 @@ export const SignedJWT = () => {
|
||||||
<Select
|
<Select
|
||||||
maxHeight={200}
|
maxHeight={200}
|
||||||
toggleId="kc-signature-algorithm"
|
toggleId="kc-signature-algorithm"
|
||||||
onToggle={() => isOpen(!open)}
|
onToggle={isOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value.toString());
|
||||||
isOpen(false);
|
isOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={value || t("anyAlgorithm")}
|
selections={value || t("anyAlgorithm")}
|
||||||
|
|
|
@ -61,7 +61,7 @@ export const KeyForm = ({
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="archiveFormat"
|
toggleId="archiveFormat"
|
||||||
onToggle={(isExpanded) => setOpenArchiveFormat(isExpanded)}
|
onToggle={setOpenArchiveFormat}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
setOpenArchiveFormat(false);
|
setOpenArchiveFormat(false);
|
||||||
|
|
|
@ -105,7 +105,7 @@ export const ImportKeyDialog = ({
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="archiveFormat"
|
toggleId="archiveFormat"
|
||||||
onToggle={() => setOpenArchiveFormat(!openArchiveFormat)}
|
onToggle={setOpenArchiveFormat}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
setOpenArchiveFormat(false);
|
setOpenArchiveFormat(false);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import type { ClientForm } from "../ClientDetails";
|
||||||
import { GenerateKeyDialog } from "./GenerateKeyDialog";
|
import { GenerateKeyDialog } from "./GenerateKeyDialog";
|
||||||
import { useFetch, useAdminClient } from "../../context/auth/AdminClient";
|
import { useFetch, useAdminClient } from "../../context/auth/AdminClient";
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
import { ImportKeyDialog, ImportFile } from "./ImportKeyDialog";
|
import { ImportKeyDialog, ImportFile } from "./ImportKeyDialog";
|
||||||
import { Certificate } from "./Certificate";
|
import { Certificate } from "./Certificate";
|
||||||
|
|
||||||
|
@ -47,8 +48,9 @@ export const Keys = ({ clientId, save }: KeysProps) => {
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
|
|
||||||
const [keyInfo, setKeyInfo] = useState<CertificateRepresentation>();
|
const [keyInfo, setKeyInfo] = useState<CertificateRepresentation>();
|
||||||
const [openGenerateKeys, setOpenGenerateKeys] = useState(false);
|
const [openGenerateKeys, toggleOpenGenerateKeys, setOpenGenerateKeys] =
|
||||||
const [openImportKeys, setOpenImportKeys] = useState(false);
|
useToggle();
|
||||||
|
const [openImportKeys, toggleOpenImportKeys, setOpenImportKeys] = useToggle();
|
||||||
|
|
||||||
const useJwksUrl = useWatch({
|
const useJwksUrl = useWatch({
|
||||||
control,
|
control,
|
||||||
|
@ -104,15 +106,12 @@ export const Keys = ({ clientId, save }: KeysProps) => {
|
||||||
<PageSection variant="light" className="keycloak__form">
|
<PageSection variant="light" className="keycloak__form">
|
||||||
{openGenerateKeys && (
|
{openGenerateKeys && (
|
||||||
<GenerateKeyDialog
|
<GenerateKeyDialog
|
||||||
toggleDialog={() => setOpenGenerateKeys(!openGenerateKeys)}
|
toggleDialog={toggleOpenGenerateKeys}
|
||||||
save={generate}
|
save={generate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{openImportKeys && (
|
{openImportKeys && (
|
||||||
<ImportKeyDialog
|
<ImportKeyDialog toggleDialog={toggleOpenImportKeys} save={importKey} />
|
||||||
toggleDialog={() => setOpenImportKeys(!openImportKeys)}
|
|
||||||
save={importKey}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<Card isFlat>
|
<Card isFlat>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|
|
@ -26,9 +26,10 @@ import {
|
||||||
clientScopeTypesDropdown,
|
clientScopeTypesDropdown,
|
||||||
} from "../../components/client-scope/ClientScopeTypes";
|
} from "../../components/client-scope/ClientScopeTypes";
|
||||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||||
|
import { getProtocolName } from "../utils";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
|
|
||||||
import "./client-scopes.css";
|
import "./client-scopes.css";
|
||||||
import { getProtocolName } from "../utils";
|
|
||||||
|
|
||||||
export type AddScopeDialogProps = {
|
export type AddScopeDialogProps = {
|
||||||
clientScopes: ClientScopeRepresentation[];
|
clientScopes: ClientScopeRepresentation[];
|
||||||
|
@ -68,11 +69,11 @@ export const AddScopeDialog = ({
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
const refresh = () => setKey(key + 1);
|
const refresh = () => setKey(key + 1);
|
||||||
|
|
||||||
const [isFilterTypeDropdownOpen, setIsFilterTypeDropdownOpen] =
|
const [isFilterTypeDropdownOpen, toggleIsFilterTypeDropdownOpen] =
|
||||||
useState(false);
|
useToggle();
|
||||||
|
|
||||||
const [isProtocolTypeDropdownOpen, setIsProtocolTypeDropdownOpen] =
|
const [isProtocolTypeDropdownOpen, toggleIsProtocolTypeDropdownOpen] =
|
||||||
useState(false);
|
useToggle(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -97,14 +98,6 @@ export const AddScopeDialog = ({
|
||||||
toggleDialog();
|
toggleDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFilterTypeDropdownToggle = () => {
|
|
||||||
setIsFilterTypeDropdownOpen(!isFilterTypeDropdownOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onProtocolTypeDropdownToggle = () => {
|
|
||||||
setIsProtocolTypeDropdownOpen(!isProtocolTypeDropdownOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFilterTypeDropdownSelect = (filterType: string) => {
|
const onFilterTypeDropdownSelect = (filterType: string) => {
|
||||||
if (filterType === FilterType.Name) {
|
if (filterType === FilterType.Name) {
|
||||||
setFilterType(FilterType.Protocol);
|
setFilterType(FilterType.Protocol);
|
||||||
|
@ -112,7 +105,7 @@ export const AddScopeDialog = ({
|
||||||
setFilterType(FilterType.Name);
|
setFilterType(FilterType.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsFilterTypeDropdownOpen(!isFilterTypeDropdownOpen);
|
toggleIsFilterTypeDropdownOpen();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onProtocolTypeDropdownSelect = (protocolType: string) => {
|
const onProtocolTypeDropdownSelect = (protocolType: string) => {
|
||||||
|
@ -124,7 +117,7 @@ export const AddScopeDialog = ({
|
||||||
setProtocolType(ProtocolType.All);
|
setProtocolType(ProtocolType.All);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsProtocolTypeDropdownOpen(!isProtocolTypeDropdownOpen);
|
toggleIsProtocolTypeDropdownOpen();
|
||||||
};
|
};
|
||||||
|
|
||||||
const protocolTypeOptions = [
|
const protocolTypeOptions = [
|
||||||
|
@ -226,7 +219,7 @@ export const AddScopeDialog = ({
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
id="toggle-id-9"
|
id="toggle-id-9"
|
||||||
onToggle={onFilterTypeDropdownToggle}
|
onToggle={toggleIsFilterTypeDropdownOpen}
|
||||||
toggleIndicator={CaretDownIcon}
|
toggleIndicator={CaretDownIcon}
|
||||||
icon={<FilterIcon />}
|
icon={<FilterIcon />}
|
||||||
>
|
>
|
||||||
|
@ -258,7 +251,7 @@ export const AddScopeDialog = ({
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
id="toggle-id-9"
|
id="toggle-id-9"
|
||||||
onToggle={onFilterTypeDropdownToggle}
|
onToggle={toggleIsFilterTypeDropdownOpen}
|
||||||
toggleIndicator={CaretDownIcon}
|
toggleIndicator={CaretDownIcon}
|
||||||
icon={<FilterIcon />}
|
icon={<FilterIcon />}
|
||||||
>
|
>
|
||||||
|
@ -279,7 +272,7 @@ export const AddScopeDialog = ({
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
className="kc-protocolType-select"
|
className="kc-protocolType-select"
|
||||||
aria-label="Select Input"
|
aria-label="Select Input"
|
||||||
onToggle={onProtocolTypeDropdownToggle}
|
onToggle={toggleIsProtocolTypeDropdownOpen}
|
||||||
onSelect={(_, value) =>
|
onSelect={(_, value) =>
|
||||||
onProtocolTypeDropdownSelect(value.toString())
|
onProtocolTypeDropdownSelect(value.toString())
|
||||||
}
|
}
|
||||||
|
|
41
src/utils/useToggle.test.ts
Normal file
41
src/utils/useToggle.test.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* @jest-environment jsdom
|
||||||
|
*/
|
||||||
|
import { act, renderHook } from "@testing-library/react-hooks";
|
||||||
|
import useToggle from "./useToggle";
|
||||||
|
|
||||||
|
describe("useToggle", () => {
|
||||||
|
it("has a default value of false", () => {
|
||||||
|
const { result } = renderHook(() => useToggle());
|
||||||
|
const [value] = result.current;
|
||||||
|
|
||||||
|
expect(value).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses the initial value", () => {
|
||||||
|
const { result } = renderHook(() => useToggle(true));
|
||||||
|
const [value] = result.current;
|
||||||
|
|
||||||
|
expect(value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("toggles the value", () => {
|
||||||
|
const { result } = renderHook(() => useToggle());
|
||||||
|
const [, toggleValue] = result.current;
|
||||||
|
|
||||||
|
act(() => toggleValue());
|
||||||
|
|
||||||
|
const [value] = result.current;
|
||||||
|
expect(value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets the value", () => {
|
||||||
|
const { result } = renderHook(() => useToggle());
|
||||||
|
const [, , setValue] = result.current;
|
||||||
|
|
||||||
|
act(() => setValue(true));
|
||||||
|
|
||||||
|
const [value] = result.current;
|
||||||
|
expect(value).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
13
src/utils/useToggle.ts
Normal file
13
src/utils/useToggle.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook that allows you toggle a boolean value, useful for toggle buttons, showing and hiding modals, etc.
|
||||||
|
*
|
||||||
|
* @param initialValue The initial value to use, false by default.
|
||||||
|
*/
|
||||||
|
export default function useToggle(initialValue = false) {
|
||||||
|
const [value, setValue] = useState(initialValue);
|
||||||
|
const toggleValue = useCallback(() => setValue((val) => !val), []);
|
||||||
|
|
||||||
|
return [value, toggleValue, setValue] as const;
|
||||||
|
}
|
Loading…
Reference in a new issue