add providers and search functionality
This commit is contained in:
parent
59f7812a24
commit
345c924e0f
4 changed files with 157 additions and 189 deletions
|
@ -11,15 +11,7 @@ import {
|
|||
TableHeader,
|
||||
TableVariant,
|
||||
} from "@patternfly/react-table";
|
||||
import {
|
||||
DataList,
|
||||
DataListAction,
|
||||
DataListCell,
|
||||
DataListItem,
|
||||
DataListItemCells,
|
||||
DataListItemRow,
|
||||
Spinner,
|
||||
} from "@patternfly/react-core";
|
||||
import { Spinner } from "@patternfly/react-core";
|
||||
import _ from "lodash";
|
||||
|
||||
import { PaginatingTableToolbar } from "./PaginatingTableToolbar";
|
||||
|
@ -55,6 +47,7 @@ type DataTableProps<T> = {
|
|||
onSelect?: (isSelected: boolean, rowIndex: number) => void;
|
||||
onCollapse?: (isOpen: boolean, rowIndex: number) => void;
|
||||
canSelectAll: boolean;
|
||||
isNotCompact?: boolean;
|
||||
};
|
||||
|
||||
function DataTable<T>({
|
||||
|
@ -66,13 +59,14 @@ function DataTable<T>({
|
|||
onSelect,
|
||||
onCollapse,
|
||||
canSelectAll,
|
||||
isNotCompact,
|
||||
...props
|
||||
}: DataTableProps<T>) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Table
|
||||
{...props}
|
||||
variant={TableVariant.compact}
|
||||
variant={isNotCompact ? undefined : TableVariant.compact}
|
||||
onSelect={
|
||||
onSelect
|
||||
? (_, isSelected, rowIndex) => onSelect(isSelected, rowIndex)
|
||||
|
@ -132,6 +126,7 @@ export type DataListProps<T> = {
|
|||
toolbarItem?: ReactNode;
|
||||
emptyState?: ReactNode;
|
||||
icon?: React.ComponentClass<SVGIconProps>;
|
||||
isNotCompact?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -163,6 +158,7 @@ export function KeycloakDataTable<T>({
|
|||
isPaginated = false,
|
||||
onSelect,
|
||||
canSelectAll = false,
|
||||
isNotCompact,
|
||||
detailColumns,
|
||||
isRowDisabled,
|
||||
loader,
|
||||
|
@ -391,47 +387,9 @@ export function KeycloakDataTable<T>({
|
|||
actionResolver={actionResolver}
|
||||
rows={filteredData || rows}
|
||||
columns={columns}
|
||||
isNotCompact={isNotCompact}
|
||||
ariaLabelKey={ariaLabelKey}
|
||||
/>
|
||||
// <DataList
|
||||
// // onSelectDataListItem={(value) => {
|
||||
// // setGroupId(value);
|
||||
// // }}
|
||||
// aria-label={t("groups")}
|
||||
// isCompact
|
||||
// itemOrder={itemOrder}
|
||||
// >
|
||||
// {(rows!).map((component) => (
|
||||
// <DataListItem draggable
|
||||
// aria-labelledby={"aria"}
|
||||
// key={"key"}
|
||||
// id={"id"}
|
||||
// // onClick={(e) => {
|
||||
// // if ((e.target as HTMLInputElement).type !== "checkbox") {
|
||||
// // setGroupId(group.id);
|
||||
// // }
|
||||
// // }}
|
||||
// >
|
||||
// <DataListItemRow data-testid={"group.name"}>
|
||||
|
||||
// <DataListItemCells
|
||||
// dataListCells={[
|
||||
// <DataListCell key={`name}`}>
|
||||
// <>{Math.random()}</>
|
||||
// </DataListCell>,
|
||||
// ]}
|
||||
// />
|
||||
// <DataListAction
|
||||
// aria-labelledby={`select`}
|
||||
// id={`select`}
|
||||
// aria-label={t("groupName")}
|
||||
// isPlainButtonAction
|
||||
// >
|
||||
// </DataListAction>
|
||||
// </DataListItemRow>
|
||||
// </DataListItem>
|
||||
// ))}
|
||||
// </DataList>
|
||||
)}
|
||||
{!loading &&
|
||||
rows.length === 0 &&
|
||||
|
|
|
@ -1,37 +1,30 @@
|
|||
import React, { Component, useState, useEffect } from "react";
|
||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
DataList,
|
||||
DataListAction,
|
||||
DataListCell,
|
||||
DataListControl,
|
||||
DataListDragButton,
|
||||
DataListItem,
|
||||
DataListItemCells,
|
||||
DataListItemRow,
|
||||
Dropdown,
|
||||
DropdownToggle,
|
||||
InputGroup,
|
||||
PageSection,
|
||||
TextInput,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { KeyMetadataRepresentation } from "keycloak-admin/lib/defs/keyMetadataRepresentation";
|
||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { emptyFormatter } from "../util";
|
||||
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
||||
|
||||
import "./RealmSettingsSection.css";
|
||||
import {
|
||||
cellWidth,
|
||||
Table,
|
||||
TableBody,
|
||||
TableHeader,
|
||||
TableVariant,
|
||||
} from "@patternfly/react-table";
|
||||
import ComponentTypeRepresentation from "keycloak-admin/lib/defs/componentTypeRepresentation";
|
||||
import { asyncStateFetch } from "../context/auth/AdminClient";
|
||||
import { useErrorHandler } from "react-error-boundary";
|
||||
import { SearchIcon } from "@patternfly/react-icons";
|
||||
|
||||
type ComponentData = KeyMetadataRepresentation & {
|
||||
providerDescription?: string;
|
||||
|
@ -44,163 +37,158 @@ type KeysTabInnerProps = {
|
|||
keyProviderComponentTypes: ComponentTypeRepresentation[];
|
||||
};
|
||||
|
||||
export const KeysTabInner = ({
|
||||
components,
|
||||
keyProviderComponentTypes,
|
||||
}: KeysTabInnerProps) => {
|
||||
export const KeysTabInner = ({ components }: KeysTabInnerProps) => {
|
||||
const { t } = useTranslation("roles");
|
||||
const history = useHistory();
|
||||
const { url } = useRouteMatch();
|
||||
const [key, setKey] = useState(0);
|
||||
const refresh = () => setKey(new Date().getTime());
|
||||
const errorHandler = useErrorHandler();
|
||||
|
||||
const [itemOrder, setItemOrder] = useState(["data1", "data2", "data3"]);
|
||||
const [id, setId] = useState("");
|
||||
const [searchVal, setSearchVal] = useState("");
|
||||
const [filteredComponents, setFilteredComponents] = useState<ComponentData[]>(
|
||||
[]
|
||||
);
|
||||
|
||||
const loader = async () => {
|
||||
return components;
|
||||
};
|
||||
const itemIds = components.map((item, idx) => "data" + idx);
|
||||
|
||||
// useEffect(
|
||||
// () =>
|
||||
// asyncStateFetch(
|
||||
// async () => {
|
||||
// return components;
|
||||
// },
|
||||
// async () => {
|
||||
const [itemOrder, setItemOrder] = useState<string[]>([]);
|
||||
|
||||
// setFetchedComponents(components)
|
||||
// },
|
||||
// errorHandler
|
||||
// ),
|
||||
// []
|
||||
// );
|
||||
console.log("itemord", itemOrder);
|
||||
|
||||
React.useEffect(() => {
|
||||
refresh();
|
||||
}, [components]);
|
||||
const [liveText, setLiveText] = useState("");
|
||||
|
||||
const goToCreate = () => history.push(`${url}/add-role`);
|
||||
|
||||
console.log("componentsss", components);
|
||||
useEffect(() => {
|
||||
setItemOrder(["data", ...itemIds]);
|
||||
}, [components, searchVal]);
|
||||
|
||||
const onDragStart = (id: string) => {
|
||||
console.log(itemOrder);
|
||||
setLiveText(t("onDragStart", { id }));
|
||||
setId(id);
|
||||
};
|
||||
|
||||
const onDragMove = (oldIndex, newIndex) => {
|
||||
console.log(`Dragging item ${id}.`);
|
||||
const onDragMove = () => {
|
||||
setLiveText(t("onDragMove", { id }));
|
||||
};
|
||||
|
||||
const columns = [
|
||||
t("realm-settings:name"),
|
||||
t("realm-settings:provider"),
|
||||
t("realm-settings:providerDescription"),
|
||||
];
|
||||
const onDragCancel = () => {
|
||||
setLiveText(t("onDragCancel"));
|
||||
};
|
||||
|
||||
// const onDragCancel = () => {
|
||||
// this.setState({
|
||||
// liveText: `Dragging cancelled. List is unchanged.`
|
||||
// });
|
||||
// };
|
||||
const onDragFinish = (itemOrder: string[]) => {
|
||||
setItemOrder(["data", ...itemOrder.filter((i) => i !== "data")]);
|
||||
setLiveText(t("onDragCancel"));
|
||||
};
|
||||
|
||||
const onDragFinish = (itemOrder) => {
|
||||
setItemOrder(itemOrder);
|
||||
const onSearch = () => {
|
||||
if (searchVal !== "") {
|
||||
setSearchVal(searchVal);
|
||||
const x = components.filter((v) => {
|
||||
return v.name?.includes(searchVal) || v.providerId?.includes(searchVal);
|
||||
});
|
||||
setFilteredComponents(x);
|
||||
} else {
|
||||
setSearchVal("");
|
||||
setFilteredComponents(components);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: any) => {
|
||||
if (e.key === "Enter") {
|
||||
onSearch();
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (value: string) => {
|
||||
setSearchVal(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageSection variant="light" padding={{ default: "noPadding" }}>
|
||||
{/* <PublicKeyDialog />
|
||||
<CertificateDialog /> */}
|
||||
{/* <KeycloakDataTable
|
||||
key={key}
|
||||
loader={loader}
|
||||
ariaLabelKey="realm-settings:keysList"
|
||||
searchPlaceholderKey="realm-settings:searchKey"
|
||||
canSelectAll
|
||||
columns={[
|
||||
{
|
||||
name: "providerId",
|
||||
displayKey: "realm-settings:name",
|
||||
cellFormatters: [emptyFormatter()],
|
||||
// cellRenderer: DataCellRendererTest,
|
||||
transforms: [cellWidth(15)],
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
displayKey: "realm-settings:provider",
|
||||
cellFormatters: [emptyFormatter()],
|
||||
transforms: [cellWidth(10)],
|
||||
},
|
||||
{
|
||||
name: "providerDescription",
|
||||
displayKey: "realm-settings:providerDescription",
|
||||
// cellRenderer: ProviderDescriptionRenderer,
|
||||
cellFormatters: [emptyFormatter()],
|
||||
},
|
||||
]}
|
||||
emptyState={
|
||||
<ListEmptyState
|
||||
hasIcon={true}
|
||||
message={t("noRoles")}
|
||||
instructions={t("noRolesInstructions")}
|
||||
primaryActionText={t("createRole")}
|
||||
onPrimaryAction={goToCreate}
|
||||
/>
|
||||
}
|
||||
/> */}
|
||||
<Table
|
||||
aria-label="Simple Table"
|
||||
// variant={TableVariant}
|
||||
// borders={choice !== 'compactBorderless'}
|
||||
cells={columns}
|
||||
// rows={rows}
|
||||
>
|
||||
<TableHeader />
|
||||
<TableBody />
|
||||
</Table>
|
||||
<Toolbar>
|
||||
<>
|
||||
<ToolbarGroup className="providers-toolbar">
|
||||
<ToolbarItem>
|
||||
<InputGroup>
|
||||
<TextInput
|
||||
name={"inputGroupName"}
|
||||
id={"inputGroupName"}
|
||||
type="search"
|
||||
aria-label={t("common:search")}
|
||||
placeholder={t("common:search")}
|
||||
onChange={handleInputChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
<Button
|
||||
variant={ButtonVariant.control}
|
||||
aria-label={t("common:search")}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
data-testid="addProviderDropdown"
|
||||
className="add-provider-dropdown"
|
||||
onSelect={() => {}}
|
||||
toggle={
|
||||
<DropdownToggle isPrimary>
|
||||
{t("realm-settings:addProvider")}
|
||||
</DropdownToggle>
|
||||
}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</ToolbarGroup>
|
||||
</>
|
||||
</Toolbar>
|
||||
|
||||
<DataList
|
||||
// onSelectDataListItem={(value) => {
|
||||
// setGroupId(value);
|
||||
// }}
|
||||
aria-label={t("groups")}
|
||||
onDragFinish={onDragFinish}
|
||||
onDragStart={onDragStart}
|
||||
onDragMove={onDragMove}
|
||||
// onDragCancel={this.onDragCancel}
|
||||
onDragCancel={onDragCancel}
|
||||
itemOrder={itemOrder}
|
||||
isCompact
|
||||
>
|
||||
{/* <DataListItem aria-labelledby={"aria"} id="data1" key="1">
|
||||
<DataListItemRow className="test" data-testid={"group.name"}>
|
||||
<DataListItemCells className="test2"
|
||||
<DataListItem aria-labelledby={"aria"} id="data" key="data">
|
||||
<DataListItemRow className="test" data-testid={"data-list-row"}>
|
||||
<DataListDragButton
|
||||
className="header-drag-button"
|
||||
aria-label="Reorder"
|
||||
aria-labelledby="simple-item"
|
||||
aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
|
||||
aria-pressed="false"
|
||||
isDisabled
|
||||
/>
|
||||
<DataListItemCells
|
||||
className="test2"
|
||||
dataListCells={[
|
||||
<DataListCell key={"1"}>
|
||||
<DataListCell className="name" key={"1"}>
|
||||
<>{t("realm-settings:name")}</>
|
||||
</DataListCell>,
|
||||
<DataListCell key={"2"}>
|
||||
<DataListCell className="provider" key={"2"}>
|
||||
<>{t("realm-settings:provider")}</>
|
||||
</DataListCell>,
|
||||
<DataListCell key={"3"}>
|
||||
<DataListCell className="provider-description" key={"3"}>
|
||||
<>{t("realm-settings:providerDescription")}</>
|
||||
</DataListCell>
|
||||
</DataListCell>,
|
||||
]}
|
||||
/>
|
||||
</DataListItemRow>
|
||||
</DataListItem> */}
|
||||
{components.map((component, idx) => (
|
||||
</DataListItem>
|
||||
{(filteredComponents.length === 0
|
||||
? components
|
||||
: filteredComponents
|
||||
).map((component, idx) => (
|
||||
<DataListItem
|
||||
draggable
|
||||
aria-labelledby={"aria"}
|
||||
key={`key-${idx + 1}`}
|
||||
id={`data${idx + 1}`}
|
||||
key={`data${idx}`}
|
||||
id={`data${idx}`}
|
||||
>
|
||||
<DataListItemRow data-testid={"data-list-row"}>
|
||||
<DataListControl>
|
||||
<DataListDragButton
|
||||
className="row-drag-button"
|
||||
aria-label="Reorder"
|
||||
aria-labelledby="simple-item2"
|
||||
aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
|
||||
|
@ -226,6 +214,9 @@ export const KeysTabInner = ({
|
|||
</DataListItem>
|
||||
))}
|
||||
</DataList>
|
||||
<div className="pf-screen-reader" aria-live="assertive">
|
||||
{liveText}
|
||||
</div>
|
||||
</PageSection>
|
||||
</>
|
||||
);
|
||||
|
@ -242,10 +233,6 @@ export const KeysProviderTab = ({
|
|||
keyProviderComponentTypes,
|
||||
...props
|
||||
}: KeysProps) => {
|
||||
// console.log("components", components)
|
||||
// console.log("keyz", keys)
|
||||
// console.log("keyz", keyProviderComponentTypes)
|
||||
|
||||
return (
|
||||
<KeysTabInner
|
||||
components={components?.map((component) => {
|
||||
|
@ -256,13 +243,6 @@ export const KeysProviderTab = ({
|
|||
return { ...component, providerDescription: provider?.helpText };
|
||||
})}
|
||||
keyProviderComponentTypes={keyProviderComponentTypes}
|
||||
// keyProviderComponentTypes={keyProviderComponentTypes?.map((key) => {
|
||||
// const provider = keyProviderComponentTypes.find(
|
||||
// (key: key) =>
|
||||
// component.id === key.providerId
|
||||
// );
|
||||
// return { ...key, provider: provider?.providerId };
|
||||
// })}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -24,3 +24,28 @@ button#kc-certificate.pf-c-button.pf-m-secondary {
|
|||
.pf-c-data-list__item-row.test {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pf-c-data-list__item-content.test2 {
|
||||
margin-left: var(--pf-global--spacer--xl);
|
||||
}
|
||||
|
||||
button.pf-c-data-list__item-draggable-button.pf-m-disabled.header-drag-button {
|
||||
/* --pf-c-data-list__item-draggable-button-icon--Color: white; */
|
||||
display: none;
|
||||
}
|
||||
|
||||
button.pf-c-data-list__item-draggable-button.row-drag-button {
|
||||
padding-top: var(--pf-global--spacer--md);
|
||||
}
|
||||
|
||||
.pf-c-data-list__item-control {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
button.pf-c-button.pf-m-link.add-provider {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.pf-c-toolbar__group.providers-toolbar {
|
||||
padding-left: var(--pf-c-toolbar__content--PaddingLeft);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
"kid": "Kid",
|
||||
"provider": "Provider",
|
||||
"providerDescription": "Provider description",
|
||||
"addProvider": "Add provider",
|
||||
"publicKeys": "Public keys",
|
||||
"certificate": "Certificate",
|
||||
"userRegistration": "User registration",
|
||||
|
@ -104,5 +105,9 @@
|
|||
"partial-import": {
|
||||
"partialImportHeaderText": "Partial import allows you to import users, clients, and resources from a previously exported json file.",
|
||||
"import": "Import"
|
||||
}
|
||||
},
|
||||
"onDragStart": "Dragging started for item {{id}}",
|
||||
"onDragMove": "Dragging item {{id}}",
|
||||
"onDragCancel": "Dragging cancelled. List is unchanged.",
|
||||
"onDragFinish": "Dragging finished {{list}}"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue