events: reverted to Flex (#1076)

Co-authored-by: Agnieszka Gancarczyk <agancarc@redhat.com>
This commit is contained in:
agagancarczyk 2021-08-26 11:37:56 +01:00 committed by GitHub
parent 2657eaf1d8
commit 764421033f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 392 additions and 378 deletions

View file

@ -3,6 +3,8 @@ import {
Button,
Dropdown,
DropdownToggle,
Flex,
FlexItem,
Form,
FormGroup,
Modal,
@ -11,7 +13,6 @@ import {
SelectVariant,
TextInput,
Tooltip,
ToolbarItem,
} from "@patternfly/react-core";
import {
cellWidth,
@ -159,136 +160,141 @@ export const AdminEvents = () => {
const adminEventSearchFormDisplay = () => {
return (
<>
<ToolbarItem>
<Dropdown
id="admin-events-search-select"
data-testid="AdminEventsSearchSelector"
className="pf-u-ml-md"
toggle={
<DropdownToggle
data-testid="adminEventsSearchSelectorToggle"
onToggle={(isOpen) => setSearchDropdownOpen(isOpen)}
className="keycloak__events_search_selector_dropdown__toggle"
>
{t("searchForAdminEvent")}
</DropdownToggle>
}
isOpen={searchDropdownOpen}
>
<Form
isHorizontal
className="keycloak__admin_events_search__form"
data-testid="searchForm"
>
<FormGroup
label={t("resourceType")}
fieldId="kc-resourceType"
className="keycloak__events_search__form_multiline_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("operationType")}
fieldId="kc-operationType"
className="keycloak__events_search__form_multiline_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("user")}
fieldId="kc-user"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-user"
name="user"
data-testid="user-searchField"
/>
</FormGroup>
<FormGroup
label={t("realm")}
fieldId="kc-realm"
className="keycloak__events_search__form_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("ipAddress")}
fieldId="kc-ipAddress"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-ipAddress"
name="ipAddress"
data-testid="ipAddress-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateFrom")}
fieldId="kc-dateFrom"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateFrom"
name="dateFrom"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateFrom-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateTo")}
fieldId="kc-dateTo"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateTo"
name="dateTo"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateTo-searchField"
/>
</FormGroup>
<ActionGroup>
<Button
className="keycloak__admin_events_search__form_btn"
variant={"primary"}
data-testid="search-events-btn"
isDisabled={!isDirty}
<Flex
direction={{ default: "column" }}
spaceItems={{ default: "spaceItemsNone" }}
>
<FlexItem>
<Dropdown
id="admin-events-search-select"
data-testid="AdminEventsSearchSelector"
className="pf-u-ml-md"
toggle={
<DropdownToggle
data-testid="adminEventsSearchSelectorToggle"
onToggle={(isOpen) => setSearchDropdownOpen(isOpen)}
className="keycloak__events_search_selector_dropdown__toggle"
>
{t("searchAdminEventsBtn")}
</Button>
</ActionGroup>
</Form>
</Dropdown>
<Button
className="pf-u-ml-md"
onClick={refresh}
data-testid="refresh-btn"
>
{t("refresh")}
</Button>
</ToolbarItem>
{t("searchForAdminEvent")}
</DropdownToggle>
}
isOpen={searchDropdownOpen}
>
<Form
isHorizontal
className="keycloak__admin_events_search__form"
data-testid="searchForm"
>
<FormGroup
label={t("resourceType")}
fieldId="kc-resourceType"
className="keycloak__events_search__form_multiline_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("operationType")}
fieldId="kc-operationType"
className="keycloak__events_search__form_multiline_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("user")}
fieldId="kc-user"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-user"
name="user"
data-testid="user-searchField"
/>
</FormGroup>
<FormGroup
label={t("realm")}
fieldId="kc-realm"
className="keycloak__events_search__form_label"
>
<Select
variant={SelectVariant.single}
onToggle={(isOpen) => setSelectOpen(isOpen)}
isOpen={selectOpen}
></Select>
</FormGroup>
<FormGroup
label={t("ipAddress")}
fieldId="kc-ipAddress"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-ipAddress"
name="ipAddress"
data-testid="ipAddress-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateFrom")}
fieldId="kc-dateFrom"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateFrom"
name="dateFrom"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateFrom-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateTo")}
fieldId="kc-dateTo"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateTo"
name="dateTo"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateTo-searchField"
/>
</FormGroup>
<ActionGroup>
<Button
className="keycloak__admin_events_search__form_btn"
variant={"primary"}
data-testid="search-events-btn"
isDisabled={!isDirty}
>
{t("searchAdminEventsBtn")}
</Button>
</ActionGroup>
</Form>
</Dropdown>
<Button
className="pf-u-ml-md"
onClick={refresh}
data-testid="refresh-btn"
>
{t("refresh")}
</Button>
</FlexItem>
</Flex>
</>
);
};

View file

@ -9,6 +9,8 @@ import {
DescriptionListTerm,
Dropdown,
DropdownToggle,
Flex,
FlexItem,
Form,
FormGroup,
PageSection,
@ -19,13 +21,12 @@ import {
TabTitleText,
TextInput,
Tooltip,
ToolbarItem,
} from "@patternfly/react-core";
import { CheckCircleIcon, WarningTriangleIcon } from "@patternfly/react-icons";
import { cellWidth, expandable } from "@patternfly/react-table";
import type EventRepresentation from "@keycloak/keycloak-admin-client/lib/defs/eventRepresentation";
import type EventType from "@keycloak/keycloak-admin-client/lib/defs/eventTypes";
import type { RealmEventsConfigRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/realmEventsConfigRepresentation";
import type EventRepresentation from "keycloak-admin/lib/defs/eventRepresentation";
import type EventType from "keycloak-admin/lib/defs/eventTypes";
import type { RealmEventsConfigRepresentation } from "keycloak-admin/lib/defs/realmEventsConfigRepresentation";
import { pickBy } from "lodash";
import moment from "moment";
import React, { useState } from "react";
@ -184,204 +185,209 @@ export const EventsSection = () => {
const userEventSearchFormDisplay = () => {
return (
<>
<ToolbarItem>
<Dropdown
id="user-events-search-select"
data-testid="UserEventsSearchSelector"
className="pf-u-ml-md"
toggle={
<DropdownToggle
data-testid="userEventsSearchSelectorToggle"
onToggle={(isOpen) => setSearchDropdownOpen(isOpen)}
className="keycloak__events_search_selector_dropdown__toggle"
>
{t("searchForUserEvent")}
</DropdownToggle>
}
isOpen={searchDropdownOpen}
>
<Form
isHorizontal
className="keycloak__user_events_search__form"
data-testid="searchForm"
>
<FormGroup
label={t("userId")}
fieldId="kc-userId"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-userId"
name="user"
data-testid="userId-searchField"
/>
</FormGroup>
<FormGroup
label={t("eventType")}
fieldId="kc-eventType"
className="keycloak__events_search__form_label"
>
<Controller
name="type"
control={control}
render={({
onChange,
value,
}: {
onChange: (newValue: EventType[]) => void;
value: EventType[];
}) => (
<Select
className="keycloak__events_search__event_type_select"
name="eventType"
data-testid="event-type-searchField"
chipGroupProps={{
numChips: 1,
expandedText: "Hide",
collapsedText: "Show ${remaining}",
}}
variant={SelectVariant.typeaheadMulti}
typeAheadAriaLabel="Select"
onToggle={(isOpen) => setSelectOpen(isOpen)}
selections={value}
onSelect={(_, selectedValue) => {
const option = selectedValue.toString() as EventType;
const changedValue = value.includes(option)
? value.filter((item) => item !== option)
: [...value, option];
onChange(changedValue);
}}
onClear={(event) => {
event.stopPropagation();
onChange([]);
}}
isOpen={selectOpen}
aria-labelledby={"eventType"}
chipGroupComponent={
<ChipGroup>
{value.map((chip) => (
<Chip
key={chip}
onClick={(event) => {
event.stopPropagation();
onChange(value.filter((val) => val !== chip));
}}
>
{chip}
</Chip>
))}
</ChipGroup>
}
>
{events?.enabledEventTypes?.map((option) => (
<SelectOption key={option} value={option} />
))}
</Select>
)}
/>
</FormGroup>
<FormGroup
label={t("client")}
fieldId="kc-client"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-client"
name="client"
data-testid="client-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateFrom")}
fieldId="kc-dateFrom"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateFrom"
name="dateFrom"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateFrom-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateTo")}
fieldId="kc-dateTo"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateTo"
name="dateTo"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateTo-searchField"
/>
</FormGroup>
<ActionGroup>
<Button
className="keycloak__user_events_search__form_btn"
variant={"primary"}
onClick={submitSearch}
data-testid="search-events-btn"
isDisabled={!isDirty}
<Flex
direction={{ default: "column" }}
spaceItems={{ default: "spaceItemsNone" }}
>
<FlexItem>
<Dropdown
id="user-events-search-select"
data-testid="UserEventsSearchSelector"
className="pf-u-ml-md"
toggle={
<DropdownToggle
data-testid="userEventsSearchSelectorToggle"
onToggle={(isOpen) => setSearchDropdownOpen(isOpen)}
className="keycloak__events_search_selector_dropdown__toggle"
>
{t("searchUserEventsBtn")}
</Button>
</ActionGroup>
</Form>
</Dropdown>
<Button
className="pf-u-ml-md"
onClick={refresh}
data-testid="refresh-btn"
>
{t("refresh")}
</Button>
</ToolbarItem>
<ToolbarItem>
{Object.entries(activeFilters).length > 0 && (
<div className="keycloak__searchChips pf-u-ml-md">
{Object.entries(activeFilters).map((filter) => {
const [key, value] = filter as [
keyof UserEventSearchForm,
string | EventType[]
];
{t("searchForUserEvent")}
</DropdownToggle>
}
isOpen={searchDropdownOpen}
>
<Form
isHorizontal
className="keycloak__user_events_search__form"
data-testid="searchForm"
>
<FormGroup
label={t("userId")}
fieldId="kc-userId"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-userId"
name="user"
data-testid="userId-searchField"
/>
</FormGroup>
<FormGroup
label={t("eventType")}
fieldId="kc-eventType"
className="keycloak__events_search__form_label"
>
<Controller
name="type"
control={control}
render={({
onChange,
value,
}: {
onChange: (newValue: EventType[]) => void;
value: EventType[];
}) => (
<Select
className="keycloak__events_search__event_type_select"
name="eventType"
data-testid="event-type-searchField"
chipGroupProps={{
numChips: 1,
expandedText: "Hide",
collapsedText: "Show ${remaining}",
}}
variant={SelectVariant.typeaheadMulti}
typeAheadAriaLabel="Select"
onToggle={(isOpen) => setSelectOpen(isOpen)}
selections={value}
onSelect={(_, selectedValue) => {
const option = selectedValue.toString() as EventType;
const changedValue = value.includes(option)
? value.filter((item) => item !== option)
: [...value, option];
return (
<ChipGroup
className="pf-u-mr-md pf-u-mb-md"
key={key}
categoryName={filterLabels[key]}
isClosable
onClick={() => removeFilter(key)}
>
{typeof value === "string" ? (
<Chip isReadOnly>{value}</Chip>
) : (
value.map((entry) => (
<Chip
key={entry}
onClick={() => removeFilterValue(key, entry)}
>
{entry}
</Chip>
))
onChange(changedValue);
}}
onClear={(event) => {
event.stopPropagation();
onChange([]);
}}
isOpen={selectOpen}
aria-labelledby={"eventType"}
chipGroupComponent={
<ChipGroup>
{value.map((chip) => (
<Chip
key={chip}
onClick={(event) => {
event.stopPropagation();
onChange(value.filter((val) => val !== chip));
}}
>
{chip}
</Chip>
))}
</ChipGroup>
}
>
{events?.enabledEventTypes?.map((option) => (
<SelectOption key={option} value={option} />
))}
</Select>
)}
</ChipGroup>
);
})}
</div>
)}
</ToolbarItem>
/>
</FormGroup>
<FormGroup
label={t("client")}
fieldId="kc-client"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-client"
name="client"
data-testid="client-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateFrom")}
fieldId="kc-dateFrom"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateFrom"
name="dateFrom"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateFrom-searchField"
/>
</FormGroup>
<FormGroup
label={t("dateTo")}
fieldId="kc-dateTo"
className="keycloak__events_search__form_label"
>
<TextInput
ref={register()}
type="text"
id="kc-dateTo"
name="dateTo"
className="pf-c-form-control pf-m-icon pf-m-calendar"
placeholder="yyyy-MM-dd"
data-testid="dateTo-searchField"
/>
</FormGroup>
<ActionGroup>
<Button
className="keycloak__user_events_search__form_btn"
variant={"primary"}
onClick={submitSearch}
data-testid="search-events-btn"
isDisabled={!isDirty}
>
{t("searchUserEventsBtn")}
</Button>
</ActionGroup>
</Form>
</Dropdown>
<Button
className="pf-u-ml-md"
onClick={refresh}
data-testid="refresh-btn"
>
{t("refresh")}
</Button>
</FlexItem>
<FlexItem>
{Object.entries(activeFilters).length > 0 && (
<div className="keycloak__searchChips pf-u-ml-md">
{Object.entries(activeFilters).map((filter) => {
const [key, value] = filter as [
keyof UserEventSearchForm,
string | EventType[]
];
return (
<ChipGroup
className="pf-u-mt-md pf-u-mr-md"
key={key}
categoryName={filterLabels[key]}
isClosable
onClick={() => removeFilter(key)}
>
{typeof value === "string" ? (
<Chip isReadOnly>{value}</Chip>
) : (
value.map((entry) => (
<Chip
key={entry}
onClick={() => removeFilterValue(key, entry)}
>
{entry}
</Chip>
))
)}
</ChipGroup>
);
})}
</div>
)}
</FlexItem>
</Flex>
</>
);
};
@ -408,55 +414,57 @@ export const EventsSection = () => {
eventKey="userEvents"
title={<TabTitleText>{t("userEvents")}</TabTitleText>}
>
<KeycloakDataTable
key={key}
loader={loader}
detailColumns={[
{
name: "details",
enabled: (event) => event.details !== undefined,
cellRenderer: DetailCell,
},
]}
isPaginated
ariaLabelKey="events:title"
toolbarItem={userEventSearchFormDisplay()}
columns={[
{
name: "time",
displayKey: "events:time",
cellRenderer: (row) => moment(row.time).format("LLL"),
cellFormatters: [expandable],
},
{
name: "userId",
displayKey: "events:user",
cellRenderer: UserDetailLink,
},
{
name: "type",
displayKey: "events:eventType",
cellRenderer: StatusRow,
},
{
name: "ipAddress",
displayKey: "events:ipAddress",
transforms: [cellWidth(10)],
},
{
name: "clientId",
displayKey: "events:client",
},
]}
emptyState={
<div className="pf-u-mt-md">
<ListEmptyState
message={t("emptyEvents")}
instructions={t("emptyEventsInstructions")}
/>
</div>
}
/>
<div className="keycloak__events_table">
<KeycloakDataTable
key={key}
loader={loader}
detailColumns={[
{
name: "details",
enabled: (event) => event.details !== undefined,
cellRenderer: DetailCell,
},
]}
isPaginated
ariaLabelKey="events:title"
toolbarItem={userEventSearchFormDisplay()}
columns={[
{
name: "time",
displayKey: "events:time",
cellRenderer: (row) => moment(row.time).format("LLL"),
cellFormatters: [expandable],
},
{
name: "userId",
displayKey: "events:user",
cellRenderer: UserDetailLink,
},
{
name: "type",
displayKey: "events:eventType",
cellRenderer: StatusRow,
},
{
name: "ipAddress",
displayKey: "events:ipAddress",
transforms: [cellWidth(10)],
},
{
name: "clientId",
displayKey: "events:client",
},
]}
emptyState={
<div className="pf-u-mt-md">
<ListEmptyState
message={t("emptyEvents")}
instructions={t("emptyEventsInstructions")}
/>
</div>
}
/>
</div>
</Tab>
<Tab
eventKey="adminEvents"