@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
286 lines • 17.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useAlerts, useFetch } from "../ui-shared";
import { AlertVariant, Button, ButtonVariant, DataList, DragDrop, DropdownItem, Droppable, Label, PageSection, ToggleGroup, ToggleGroupItem, Toolbar, ToolbarContent, ToolbarItem, } from "@patternfly/react-core";
import { DomainIcon, TableIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { useAdminClient } from "../admin-client";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useRealm } from "../context/realm-context/RealmContext";
import useToggle from "../utils/useToggle";
import { BindFlowDialog } from "../authentication/BindFlowDialog";
import { BuildInLabel } from "../authentication/BuildInLabel";
import { DuplicateFlowModal } from "../authentication/DuplicateFlowModal";
import { EditFlowModal } from "../authentication/EditFlowModal";
import { EmptyExecutionState } from "../authentication/EmptyExecutionState";
import { FlowDiagram } from "../authentication/components/FlowDiagram";
import { FlowHeader } from "../authentication/components/FlowHeader";
import { FlowRow } from "../authentication/components/FlowRow";
import { AddStepModal } from "../authentication/components/modals/AddStepModal";
import { AddSubFlowModal } from "../authentication/components/modals/AddSubFlowModal";
import { ExecutionList, } from "../authentication/execution-model";
import { toAuthentication } from "../authentication/routes/Authentication";
import { toFlow } from "../authentication/routes/Flow";
export const providerConditionFilter = (value) => { var _a; return (_a = value.displayName) === null || _a === void 0 ? void 0 : _a.startsWith("Condition "); };
export default function FlowDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { realm } = useRealm();
const { addAlert, addError } = useAlerts();
const { id, usedBy, builtIn } = useParams();
const navigate = useNavigate();
const [key, setKey] = useState(0);
const refresh = () => setKey(new Date().getTime());
const [tableView, setTableView] = useState(true);
const [flow, setFlow] = useState();
const [executionList, setExecutionList] = useState();
const [liveText, setLiveText] = useState("");
const [showAddExecutionDialog, setShowAddExecutionDialog] = useState();
const [showAddSubFlowDialog, setShowSubFlowDialog] = useState();
const [selectedExecution, setSelectedExecution] = useState();
const [open, toggleOpen, setOpen] = useToggle();
const [edit, setEdit] = useState(false);
const [bindFlowOpen, toggleBindFlow] = useToggle();
useFetch(async () => {
const flows = await adminClient.authenticationManagement.getFlows();
const flow = flows.find((f) => f.id === id);
if (!flow) {
throw new Error(t("notFound"));
}
const executions = await adminClient.authenticationManagement.getExecutions({
flow: flow.alias,
});
return { flow, executions };
}, ({ flow, executions }) => {
setFlow(flow);
setExecutionList(new ExecutionList(executions));
}, [key]);
const executeChange = async (ex, change) => {
var _a, _b, _c;
try {
let id = ex.id;
if ("parent" in change) {
let config = {};
if ("authenticationConfig" in ex) {
config = await adminClient.authenticationManagement.getConfig({
id: ex.authenticationConfig,
});
}
try {
await adminClient.authenticationManagement.delExecution({ id });
}
catch (_d) {
// skipping already deleted execution
}
if ("authenticationFlow" in ex) {
const executionFlow = ex;
const result = await adminClient.authenticationManagement.addFlowToFlow({
flow: ((_a = change.parent) === null || _a === void 0 ? void 0 : _a.displayName) || (flow === null || flow === void 0 ? void 0 : flow.alias),
alias: executionFlow.displayName,
description: executionFlow.description,
provider: ex.providerId,
type: "basic-flow",
});
id = result.id;
(_b = ex.executionList) === null || _b === void 0 ? void 0 : _b.forEach((e, i) => executeChange(e, {
parent: { ...ex, id: result.id },
newIndex: i,
oldIndex: i,
}));
}
else {
const result = await adminClient.authenticationManagement.addExecutionToFlow({
flow: ((_c = change.parent) === null || _c === void 0 ? void 0 : _c.displayName) || (flow === null || flow === void 0 ? void 0 : flow.alias),
provider: ex.providerId,
});
if (config.id) {
const newConfig = {
id: result.id,
alias: config.alias,
config: config.config,
};
await adminClient.authenticationManagement.createConfig(newConfig);
}
id = result.id;
}
}
const times = change.newIndex - change.oldIndex;
for (let index = 0; index < Math.abs(times); index++) {
if (times > 0) {
await adminClient.authenticationManagement.lowerPriorityExecution({
id,
});
}
else {
await adminClient.authenticationManagement.raisePriorityExecution({
id,
});
}
}
refresh();
addAlert(t("updateFlowSuccess"), AlertVariant.success);
}
catch (error) {
addError("updateFlowError", error);
}
};
const update = async (execution) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { executionList, isCollapsed, ...ex } = execution;
try {
await adminClient.authenticationManagement.updateExecution({ flow: flow === null || flow === void 0 ? void 0 : flow.alias }, ex);
refresh();
addAlert(t("updateFlowSuccess"), AlertVariant.success);
}
catch (error) {
addError("updateFlowError", error);
}
};
const addExecution = async (name, type) => {
try {
await adminClient.authenticationManagement.addExecutionToFlow({
flow: name,
provider: type.id,
});
refresh();
addAlert(t("updateFlowSuccess"), AlertVariant.success);
}
catch (error) {
addError("updateFlowError", error);
}
};
const addFlow = async (flow, { name, description = "", type, provider }) => {
try {
await adminClient.authenticationManagement.addFlowToFlow({
flow,
alias: name,
description,
provider,
type,
});
refresh();
addAlert(t("updateFlowSuccess"), AlertVariant.success);
}
catch (error) {
addError("updateFlowError", error);
}
};
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: "deleteConfirmExecution",
children: (_jsxs(Trans, { i18nKey: "deleteConfirmExecutionMessage", children: [" ", _jsx("strong", { children: { name: selectedExecution === null || selectedExecution === void 0 ? void 0 : selectedExecution.displayName } }), "."] })),
continueButtonLabel: "delete",
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
try {
await adminClient.authenticationManagement.delExecution({
id: selectedExecution === null || selectedExecution === void 0 ? void 0 : selectedExecution.id,
});
addAlert(t("deleteExecutionSuccess"), AlertVariant.success);
refresh();
}
catch (error) {
addError("deleteExecutionError", error);
}
},
});
const [toggleDeleteFlow, DeleteFlowConfirm] = useConfirmDialog({
titleKey: "deleteConfirmFlow",
children: (_jsxs(Trans, { i18nKey: "deleteConfirmFlowMessage", children: [" ", _jsx("strong", { children: { flow: (flow === null || flow === void 0 ? void 0 : flow.alias) || "" } }), "."] })),
continueButtonLabel: "delete",
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
try {
await adminClient.authenticationManagement.deleteFlow({
flowId: flow.id,
});
navigate(toAuthentication({ realm }));
addAlert(t("deleteFlowSuccess"), AlertVariant.success);
}
catch (error) {
addError("deleteFlowError", error);
}
},
});
const hasExecutions = (executionList === null || executionList === void 0 ? void 0 : executionList.expandableList.length) !== 0;
const dropdownItems = [
...(usedBy !== "DEFAULT"
? [
_jsx(DropdownItem, { "data-testid": "set-as-default", onClick: toggleBindFlow, children: t("bindFlow") }, "default"),
]
: []),
_jsx(DropdownItem, { onClick: () => setOpen(true), children: t("duplicate") }, "duplicate"),
...(!builtIn
? [
_jsx(DropdownItem, { "data-testid": "edit-flow", onClick: () => setEdit(true), children: t("editInfo") }, "edit"),
_jsx(DropdownItem, { "data-testid": "delete-flow", onClick: () => toggleDeleteFlow(), children: t("delete") }, "delete"),
]
: []),
];
return (_jsxs(_Fragment, { children: [bindFlowOpen && (_jsx(BindFlowDialog, { flowAlias: flow === null || flow === void 0 ? void 0 : flow.alias, onClose: (usedBy) => {
toggleBindFlow();
navigate(toFlow({
realm,
id: id,
usedBy: usedBy ? "DEFAULT" : "notInUse",
builtIn: builtIn ? "builtIn" : undefined,
}));
} })), open && (_jsx(DuplicateFlowModal, { name: flow === null || flow === void 0 ? void 0 : flow.alias, description: flow === null || flow === void 0 ? void 0 : flow.description, toggleDialog: toggleOpen, onComplete: () => {
refresh();
setOpen(false);
} })), edit && (_jsx(EditFlowModal, { flow: flow, toggleDialog: () => {
setEdit(!edit);
refresh();
} })), _jsx(DeleteFlowConfirm, {}), _jsx(ViewHeader, { titleKey: (flow === null || flow === void 0 ? void 0 : flow.alias) || "", badges: [
{ text: _jsx(Label, { children: t(`used.${usedBy}`) }) },
builtIn
? {
text: _jsx(BuildInLabel, {}),
id: "builtIn",
}
: {},
], dropdownItems: dropdownItems }), _jsxs(PageSection, { variant: "light", children: [executionList && hasExecutions && (_jsxs(_Fragment, { children: [_jsx(Toolbar, { id: "toolbar", children: _jsxs(ToolbarContent, { children: [_jsx(ToolbarItem, { children: _jsxs(ToggleGroup, { children: [_jsx(ToggleGroupItem, { icon: _jsx(TableIcon, {}), "aria-label": t("tableView"), buttonId: "tableView", isSelected: tableView, onChange: () => setTableView(true) }), _jsx(ToggleGroupItem, { icon: _jsx(DomainIcon, {}), "aria-label": t("diagramView"), buttonId: "diagramView", isSelected: !tableView, onChange: () => setTableView(false) })] }) }), _jsx(ToolbarItem, { children: _jsx(Button, { "data-testid": "addStep", variant: "secondary", onClick: () => setShowAddExecutionDialog(true), children: t("addStep") }) }), _jsx(ToolbarItem, { children: _jsx(Button, { "data-testid": "addSubFlow", variant: "secondary", onClick: () => setShowSubFlowDialog(true), children: t("addSubFlow") }) })] }) }), _jsx(DeleteConfirm, {}), tableView && (_jsx(DragDrop, { onDrag: ({ index }) => {
const item = executionList.findExecution(index);
setLiveText(t("onDragStart", { item: item.displayName }));
if (!item.isCollapsed) {
item.isCollapsed = true;
setExecutionList(executionList.clone());
}
return true;
}, onDragMove: ({ index }) => {
const dragged = executionList.findExecution(index);
setLiveText(t("onDragMove", { item: dragged === null || dragged === void 0 ? void 0 : dragged.displayName }));
}, onDrop: (source, dest) => {
if (dest) {
const dragged = executionList.findExecution(source.index);
const order = executionList.order().map((ex) => ex.id);
setLiveText(t("onDragFinish", { list: dragged.displayName }));
const [removed] = order.splice(source.index, 1);
order.splice(dest.index, 0, removed);
const change = executionList.getChange(dragged, order);
executeChange(dragged, change);
return true;
}
else {
setLiveText(t("onDragCancel"));
return false;
}
}, children: _jsx(Droppable, { hasNoWrapper: true, children: _jsxs(DataList, { "aria-label": t("flows"), children: [_jsx(FlowHeader, {}), _jsx(_Fragment, { children: executionList.expandableList.map((execution) => (_jsx(FlowRow, { builtIn: !!builtIn, execution: execution, onRowClick: (execution) => {
execution.isCollapsed = !execution.isCollapsed;
setExecutionList(executionList.clone());
}, onRowChange: update, onAddExecution: (execution, type) => addExecution(execution.displayName, type), onAddFlow: (execution, flow) => addFlow(execution.displayName, flow), onDelete: (execution) => {
setSelectedExecution(execution);
toggleDeleteDialog();
} }, execution.id))) })] }) }) })), flow && (_jsxs(_Fragment, { children: [showAddExecutionDialog && (_jsx(AddStepModal, { name: flow.alias, type: flow.providerId === "client-flow" ? "client" : "basic", onSelect: (type) => {
if (type) {
addExecution(flow.alias, type);
}
setShowAddExecutionDialog(false);
} })), showAddSubFlowDialog && (_jsx(AddSubFlowModal, { name: flow.alias, onCancel: () => setShowSubFlowDialog(false), onConfirm: (newFlow) => {
addFlow(flow.alias, newFlow);
setShowSubFlowDialog(false);
} }))] })), _jsx("div", { className: "pf-v5-screen-reader", "aria-live": "assertive", children: liveText })] })), !tableView && (executionList === null || executionList === void 0 ? void 0 : executionList.expandableList) && (_jsx(FlowDiagram, { executionList: executionList })), !(executionList === null || executionList === void 0 ? void 0 : executionList.expandableList) ||
(flow && !hasExecutions && (_jsx(EmptyExecutionState, { flow: flow, onAddExecution: (type) => addExecution(flow.alias, type), onAddFlow: (newFlow) => addFlow(flow.alias, newFlow) })))] })] }));
}
//# sourceMappingURL=FlowDetails.js.map