parent
748c53df7f
commit
c62f04e7c9
1 changed files with 71 additions and 26 deletions
|
@ -5,6 +5,7 @@ import type {
|
||||||
PolicyQuery,
|
PolicyQuery,
|
||||||
} from "@keycloak/keycloak-admin-client/lib/resources/clients";
|
} from "@keycloak/keycloak-admin-client/lib/resources/clients";
|
||||||
import {
|
import {
|
||||||
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
Chip,
|
Chip,
|
||||||
ChipGroup,
|
ChipGroup,
|
||||||
|
@ -26,6 +27,10 @@ import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { useFetch } from "../../utils/useFetch";
|
import { useFetch } from "../../utils/useFetch";
|
||||||
import { toPolicyDetails } from "../routes/PolicyDetails";
|
import { toPolicyDetails } from "../routes/PolicyDetails";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
|
import { toCreatePolicy } from "../routes/NewPolicy";
|
||||||
|
import { NewPolicyDialog } from "./NewPolicyDialog";
|
||||||
|
import useToggle from "../../utils/useToggle";
|
||||||
|
import PolicyProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyProviderRepresentation";
|
||||||
|
|
||||||
type Type = "resources" | "policies";
|
type Type = "resources" | "policies";
|
||||||
|
|
||||||
|
@ -84,7 +89,11 @@ export const ResourcesPolicySelect = ({
|
||||||
const [items, setItems] = useState<Policies[]>([]);
|
const [items, setItems] = useState<Policies[]>([]);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [clickedPolicy, setClickedPolicy] = useState<Policies>();
|
const [createPolicyDialog, toggleCreatePolicyDialog] = useToggle();
|
||||||
|
const [policyProviders, setPolicyProviders] =
|
||||||
|
useState<PolicyProviderRepresentation[]>();
|
||||||
|
const [onUnsavedChangesConfirm, setOnUnsavedChangesConfirm] =
|
||||||
|
useState<() => void>();
|
||||||
|
|
||||||
const functions = typeMapping[name];
|
const functions = typeMapping[name];
|
||||||
|
|
||||||
|
@ -102,29 +111,35 @@ export const ResourcesPolicySelect = ({
|
||||||
{ id: clientId, first: 0, max: 10, permission: "false" },
|
{ id: clientId, first: 0, max: 10, permission: "false" },
|
||||||
search === "" ? null : { name: search },
|
search === "" ? null : { name: search },
|
||||||
);
|
);
|
||||||
return (
|
return await Promise.all([
|
||||||
await Promise.all([
|
adminClient.clients.listPolicyProviders({ id: clientId }),
|
||||||
adminClient.clients[functions.searchFunction](params),
|
adminClient.clients[functions.searchFunction](params),
|
||||||
permissionId
|
permissionId
|
||||||
? adminClient.clients[functions.fetchFunction]({
|
? adminClient.clients[functions.fetchFunction]({
|
||||||
id: clientId,
|
id: clientId,
|
||||||
permissionId,
|
permissionId,
|
||||||
})
|
})
|
||||||
: Promise.resolve([]),
|
: Promise.resolve([]),
|
||||||
])
|
]);
|
||||||
)
|
},
|
||||||
.flat()
|
([providers, ...policies]) => {
|
||||||
.filter(
|
setPolicyProviders(
|
||||||
(r): r is PolicyRepresentation | ResourceRepresentation =>
|
providers.filter((p) => p.type !== "resource" && p.type !== "scope"),
|
||||||
typeof r !== "string",
|
);
|
||||||
)
|
setItems(
|
||||||
.map(convert)
|
policies
|
||||||
.filter(
|
.flat()
|
||||||
({ id }, index, self) =>
|
.filter(
|
||||||
index === self.findIndex(({ id: otherId }) => id === otherId),
|
(r): r is PolicyRepresentation | ResourceRepresentation =>
|
||||||
);
|
typeof r !== "string",
|
||||||
|
)
|
||||||
|
.map(convert)
|
||||||
|
.filter(
|
||||||
|
({ id }, index, self) =>
|
||||||
|
index === self.findIndex(({ id: otherId }) => id === otherId),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
setItems,
|
|
||||||
[search],
|
[search],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -133,7 +148,7 @@ export const ResourcesPolicySelect = ({
|
||||||
messageKey: t("unsavedChangesConfirm"),
|
messageKey: t("unsavedChangesConfirm"),
|
||||||
continueButtonLabel: t("common:continue"),
|
continueButtonLabel: t("common:continue"),
|
||||||
continueButtonVariant: ButtonVariant.danger,
|
continueButtonVariant: ButtonVariant.danger,
|
||||||
onConfirm: () => navigate(to(clickedPolicy!)),
|
onConfirm: onUnsavedChangesConfirm!,
|
||||||
});
|
});
|
||||||
|
|
||||||
const to = (policy: Policies) =>
|
const to = (policy: Policies) =>
|
||||||
|
@ -165,6 +180,8 @@ export const ResourcesPolicySelect = ({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const location = to(policy);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chip
|
<Chip
|
||||||
key={policy.id}
|
key={policy.id}
|
||||||
|
@ -175,13 +192,13 @@ export const ResourcesPolicySelect = ({
|
||||||
>
|
>
|
||||||
{policy.type ? (
|
{policy.type ? (
|
||||||
<Link
|
<Link
|
||||||
to={to(policy)}
|
to={location}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setClickedPolicy(policy);
|
setOnUnsavedChangesConfirm(() => navigate(location));
|
||||||
toggleUnsavedChangesDialog();
|
toggleUnsavedChangesDialog();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -201,6 +218,17 @@ export const ResourcesPolicySelect = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<UnsavedChangesConfirm />
|
<UnsavedChangesConfirm />
|
||||||
|
{createPolicyDialog && (
|
||||||
|
<NewPolicyDialog
|
||||||
|
policyProviders={policyProviders}
|
||||||
|
onSelect={(p) => {
|
||||||
|
navigate(
|
||||||
|
toCreatePolicy({ id: clientId, realm, policyType: p.type! }),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
toggleDialog={toggleCreatePolicyDialog}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Controller
|
<Controller
|
||||||
name={name}
|
name={name}
|
||||||
defaultValue={preSelected ? [preSelected] : []}
|
defaultValue={preSelected ? [preSelected] : []}
|
||||||
|
@ -241,6 +269,23 @@ export const ResourcesPolicySelect = ({
|
||||||
validated={errors[name] ? "error" : "default"}
|
validated={errors[name] ? "error" : "default"}
|
||||||
typeAheadAriaLabel={t(name)}
|
typeAheadAriaLabel={t(name)}
|
||||||
chipGroupComponent={toChipGroupItems(field)}
|
chipGroupComponent={toChipGroupItems(field)}
|
||||||
|
footer={
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
isInline
|
||||||
|
onClick={() => {
|
||||||
|
if (isDirty) {
|
||||||
|
setOpen(false);
|
||||||
|
setOnUnsavedChangesConfirm(() => toggleCreatePolicyDialog);
|
||||||
|
toggleUnsavedChangesDialog();
|
||||||
|
} else {
|
||||||
|
toggleCreatePolicyDialog();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("createPolicy")}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{toSelectOptions()}
|
{toSelectOptions()}
|
||||||
</Select>
|
</Select>
|
||||||
|
|
Loading…
Reference in a new issue