import { KeyboardEvent, useMemo, useState } from "react"; import { Select, SelectVariant, SelectOption, PageSection, ActionGroup, Button, TextInput, ButtonVariant, InputGroup, Toolbar, ToolbarGroup, ToolbarItem, Divider, } from "@patternfly/react-core"; import { useTranslation } from "react-i18next"; import { SearchIcon } from "@patternfly/react-icons"; import { TableComposable, Th, Thead, Tr } from "@patternfly/react-table"; import type EvaluationResultRepresentation from "@keycloak/keycloak-admin-client/lib/defs/evaluationResultRepresentation"; import type PolicyEvaluationResponse from "@keycloak/keycloak-admin-client/lib/defs/policyEvaluationResponse"; import { AuthorizationEvaluateResource } from "../AuthorizationEvaluateResource"; import { ListEmptyState } from "../../../components/list-empty-state/ListEmptyState"; import { AuthorizationDataModal } from "../AuthorizationDataModal"; import useToggle from "../../../utils/useToggle"; type ResultProps = { evaluateResult: PolicyEvaluationResponse; refresh: () => void; back: () => void; }; enum ResultsFilter { All = "ALL", StatusDenied = "STATUS_DENIED", StatusPermitted = "STATUS_PERMITTED", } function filterResults( results: EvaluationResultRepresentation[], filter: ResultsFilter ) { switch (filter) { case ResultsFilter.StatusPermitted: return results.filter(({ status }) => status === "PERMIT"); case ResultsFilter.StatusDenied: return results.filter(({ status }) => status === "DENY"); default: return results; } } export const Results = ({ evaluateResult, refresh, back }: ResultProps) => { const { t } = useTranslation("clients"); const [filterDropdownOpen, toggleFilterDropdown] = useToggle(); const [filter, setFilter] = useState(ResultsFilter.All); const [searchQuery, setSearchQuery] = useState(""); const [searchInput, setSearchInput] = useState(""); const confirmSearchQuery = () => { setSearchQuery(searchInput); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Enter") { confirmSearchQuery(); } }; const filteredResources = useMemo( () => filterResults(evaluateResult.results!, filter).filter( ({ resource }) => resource?.name?.includes(searchQuery) ?? false ), [evaluateResult.results, filter, searchQuery] ); const noEvaluatedData = evaluateResult.results!.length === 0; const noFilteredData = filteredResources.length === 0; return ( {!noFilteredData && ( {t("resource")} {t("overallResults")} {t("scopes")} {filteredResources.map((resource, rowIndex) => ( ))} )} {(noFilteredData || noEvaluatedData) && ( <> )} ); };