remove use of deprecated table component (#29812)
* remove use of deprecated table component Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * added transformer Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fix row click Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed useless name label Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fix row click again Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed more useless name label Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed useless options Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed useless options Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed data-label Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fix for action click Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * made indeterminate work again Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fixed test Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
e5123ea9de
commit
d1756564a7
13 changed files with 163 additions and 83 deletions
|
@ -777,7 +777,7 @@ describe("Clients test", () => {
|
||||||
commonPage.sidebar().waitForPageLoad();
|
commonPage.sidebar().waitForPageLoad();
|
||||||
rolesTab.goToAssociatedRolesTab();
|
rolesTab.goToAssociatedRolesTab();
|
||||||
|
|
||||||
cy.get('td[data-label="Name"]')
|
cy.get("td")
|
||||||
.contains("manage-account")
|
.contains("manage-account")
|
||||||
.parent()
|
.parent()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default class RoleMappingTab {
|
||||||
#assignBtn = "assign";
|
#assignBtn = "assign";
|
||||||
#hideInheritedRolesBtn = "#hideInheritedRoles";
|
#hideInheritedRolesBtn = "#hideInheritedRoles";
|
||||||
#assignedRolesTable = "assigned-roles";
|
#assignedRolesTable = "assigned-roles";
|
||||||
#namesColumn = 'td[data-label="Name"]:visible';
|
#namesColumn = "td:visible";
|
||||||
#roleMappingTab = "role-mapping-tab";
|
#roleMappingTab = "role-mapping-tab";
|
||||||
#filterTypeDropdown = "filter-type-dropdown";
|
#filterTypeDropdown = "filter-type-dropdown";
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default class InitialAccessTokenTab extends CommonPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFirstId(callback: (id: string) => void) {
|
getFirstId(callback: (id: string) => void) {
|
||||||
cy.get('tbody > tr:first-child > [data-label="ID"]')
|
cy.get("tbody > tr:first-child > td:first-child")
|
||||||
.invoke("text")
|
.invoke("text")
|
||||||
.then((text) => {
|
.then((text) => {
|
||||||
callback(text);
|
callback(text);
|
||||||
|
|
|
@ -13,8 +13,7 @@ export default class GroupDetailPage extends GroupPage {
|
||||||
#attributesTab = "attributes";
|
#attributesTab = "attributes";
|
||||||
#roleMappingTab = "role-mapping-tab";
|
#roleMappingTab = "role-mapping-tab";
|
||||||
#permissionsTab = "permissionsTab";
|
#permissionsTab = "permissionsTab";
|
||||||
#memberNameColumn =
|
#memberNameColumn = '[data-testid="members-table"] > tbody > tr';
|
||||||
'[data-testid="members-table"] > tbody > tr > [data-label="Name"]';
|
|
||||||
#addMembers = "addMember";
|
#addMembers = "addMember";
|
||||||
#memberUsernameColumn = 'tbody > tr > [data-label="Username"]';
|
#memberUsernameColumn = 'tbody > tr > [data-label="Username"]';
|
||||||
#actionDrpDwnItemRenameGroup = "renameGroupAction";
|
#actionDrpDwnItemRenameGroup = "renameGroupAction";
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class AssociatedRolesPage {
|
||||||
#filterTypeDropdownItem = "clients";
|
#filterTypeDropdownItem = "clients";
|
||||||
#usersPage = "users-page";
|
#usersPage = "users-page";
|
||||||
#removeRolesButton = "unAssignRole";
|
#removeRolesButton = "unAssignRole";
|
||||||
#addRoleTable = '[aria-label="Roles"] td[data-label="Name"]';
|
#addRoleTable = '[aria-label="Roles"] td';
|
||||||
|
|
||||||
addAssociatedRealmRole(roleName: string) {
|
addAssociatedRealmRole(roleName: string) {
|
||||||
cy.findByTestId(this.#actionDropdown).last().click();
|
cy.findByTestId(this.#actionDropdown).last().click();
|
||||||
|
|
|
@ -85,7 +85,7 @@ export default class RealmSettingsPage extends CommonPage {
|
||||||
eventsUserSave = "save-user";
|
eventsUserSave = "save-user";
|
||||||
enableAdminEvents = "adminEventsEnabled";
|
enableAdminEvents = "adminEventsEnabled";
|
||||||
eventsAdminSave = "save-admin";
|
eventsAdminSave = "save-admin";
|
||||||
eventTypeColumn = 'tbody > tr > [data-label="Event saved type"]';
|
eventTypeColumn = "tbody > tr td";
|
||||||
filterSelectMenu = ".kc-filter-type-select";
|
filterSelectMenu = ".kc-filter-type-select";
|
||||||
passiveKeysOption = "PASSIVE-option";
|
passiveKeysOption = "PASSIVE-option";
|
||||||
disabledKeysOption = "DISABLED-option";
|
disabledKeysOption = "DISABLED-option";
|
||||||
|
@ -1270,12 +1270,12 @@ export default class RealmSettingsPage extends CommonPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
checkElementNotInList(name: string) {
|
checkElementNotInList(name: string) {
|
||||||
cy.get('tbody [data-label="Name"]').should("not.contain.text", name);
|
cy.get("tbody").should("not.contain.text", name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkElementInList(name: string) {
|
checkElementInList(name: string) {
|
||||||
cy.get('tbody [data-label="Name"]').should("contain.text", name);
|
cy.get("tbody").should("contain.text", name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default class UserProfile {
|
||||||
#newAttributeAnnotationBtn = "annotations-add-row";
|
#newAttributeAnnotationBtn = "annotations-add-row";
|
||||||
#newAttributeAnnotationKey = "annotations.0.key";
|
#newAttributeAnnotationKey = "annotations.0.key";
|
||||||
#newAttributeAnnotationValue = "annotations.0.value";
|
#newAttributeAnnotationValue = "annotations.0.value";
|
||||||
#validatorsList = 'tbody [data-label="name"]';
|
#validatorsList = "tbody";
|
||||||
#saveNewAttributeBtn = "attribute-create";
|
#saveNewAttributeBtn = "attribute-create";
|
||||||
#addValidatorBtn = "addValidator";
|
#addValidatorBtn = "addValidator";
|
||||||
#removeValidatorBtn = "deleteValidator";
|
#removeValidatorBtn = "deleteValidator";
|
||||||
|
|
|
@ -3,7 +3,7 @@ export default class UserRegistration {
|
||||||
#defaultGroupTab = "#pf-tab-20-groups";
|
#defaultGroupTab = "#pf-tab-20-groups";
|
||||||
#addRoleBtn = "assignRole";
|
#addRoleBtn = "assignRole";
|
||||||
#addDefaultGroupBtn = "no-default-groups-empty-action";
|
#addDefaultGroupBtn = "no-default-groups-empty-action";
|
||||||
#namesColumn = 'tbody td[data-label="Name"]:visible';
|
#namesColumn = "tbody td:visible";
|
||||||
#addBtn = "assign";
|
#addBtn = "assign";
|
||||||
#filterTypeDropdown = "filter-type-dropdown";
|
#filterTypeDropdown = "filter-type-dropdown";
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
import { Button, ButtonVariant, ToolbarItem } from "@patternfly/react-core";
|
import { Button, ButtonVariant, ToolbarItem } from "@patternfly/react-core";
|
||||||
import type { SVGIconProps } from "@patternfly/react-icons/dist/js/createIcon";
|
import type { SVGIconProps } from "@patternfly/react-icons/dist/js/createIcon";
|
||||||
import {
|
import {
|
||||||
|
ActionsColumn,
|
||||||
|
ExpandableRowContent,
|
||||||
IAction,
|
IAction,
|
||||||
IActions,
|
IActions,
|
||||||
IActionsResolver,
|
IActionsResolver,
|
||||||
IFormatter,
|
IFormatter,
|
||||||
IRow,
|
IRow,
|
||||||
|
IRowCell,
|
||||||
ITransform,
|
ITransform,
|
||||||
TableVariant,
|
|
||||||
} from "@patternfly/react-table";
|
|
||||||
import {
|
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
|
||||||
TableHeader,
|
|
||||||
TableProps,
|
TableProps,
|
||||||
} from "@patternfly/react-table/deprecated";
|
TableVariant,
|
||||||
|
Tbody,
|
||||||
|
Td,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tr,
|
||||||
|
} from "@patternfly/react-table";
|
||||||
import { cloneDeep, differenceBy, get } from "lodash-es";
|
import { cloneDeep, differenceBy, get } from "lodash-es";
|
||||||
import {
|
import {
|
||||||
ComponentClass,
|
ComponentClass,
|
||||||
|
@ -67,6 +71,18 @@ type DataTableProps<T> = {
|
||||||
isRadio?: boolean;
|
isRadio?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CellRendererProps = {
|
||||||
|
row: IRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CellRenderer = ({ row }: CellRendererProps) => {
|
||||||
|
const isRow = (c: ReactNode | IRowCell): c is IRowCell =>
|
||||||
|
!!c && (c as IRowCell).title !== undefined;
|
||||||
|
return row.cells!.map((c, i) => (
|
||||||
|
<Td key={`cell-${i}`}>{(isRow(c) ? c.title : c) as ReactNode}</Td>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
function DataTable<T>({
|
function DataTable<T>({
|
||||||
columns,
|
columns,
|
||||||
rows,
|
rows,
|
||||||
|
@ -81,32 +97,129 @@ function DataTable<T>({
|
||||||
...props
|
...props
|
||||||
}: DataTableProps<T>) {
|
}: DataTableProps<T>) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [selectedRows, setSelectedRows] = useState<boolean[]>([]);
|
||||||
|
const [expandedRows, setExpandedRows] = useState<boolean[]>([]);
|
||||||
|
|
||||||
|
const updateState = (rowIndex: number, isSelected: boolean) => {
|
||||||
|
const items = [
|
||||||
|
...(rowIndex === -1 ? Array(rows.length).fill(isSelected) : selectedRows),
|
||||||
|
];
|
||||||
|
items[rowIndex] = isSelected;
|
||||||
|
setSelectedRows(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (canSelectAll) {
|
||||||
|
const selectAllCheckbox = document.getElementsByName("check-all").item(0);
|
||||||
|
if (selectAllCheckbox) {
|
||||||
|
const checkbox = selectAllCheckbox as HTMLInputElement;
|
||||||
|
const selected = selectedRows.filter((r) => r === true);
|
||||||
|
checkbox.indeterminate =
|
||||||
|
selected.length < rows.length && selected.length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [selectedRows]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
{...props}
|
{...props}
|
||||||
variant={isNotCompact ? undefined : TableVariant.compact}
|
variant={isNotCompact ? undefined : TableVariant.compact}
|
||||||
onSelect={
|
|
||||||
onSelect
|
|
||||||
? (_, isSelected, rowIndex) => onSelect(isSelected, rowIndex)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onCollapse={
|
|
||||||
onCollapse
|
|
||||||
? (_, rowIndex, isOpen) => onCollapse(isOpen, rowIndex)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
selectVariant={isRadio ? "radio" : "checkbox"}
|
|
||||||
canSelectAll={canSelectAll}
|
|
||||||
cells={columns.map((column) => {
|
|
||||||
return { ...column, title: t(column.displayKey || column.name) };
|
|
||||||
})}
|
|
||||||
rows={rows as IRow[]}
|
|
||||||
actions={actions}
|
|
||||||
actionResolver={actionResolver}
|
|
||||||
aria-label={t(ariaLabelKey)}
|
aria-label={t(ariaLabelKey)}
|
||||||
>
|
>
|
||||||
<TableHeader />
|
<Thead>
|
||||||
<TableBody />
|
<Tr>
|
||||||
|
{onCollapse && <Th />}
|
||||||
|
{canSelectAll && (
|
||||||
|
<Th
|
||||||
|
select={
|
||||||
|
!isRadio
|
||||||
|
? {
|
||||||
|
onSelect: (_, isSelected, rowIndex) => {
|
||||||
|
onSelect!(isSelected, rowIndex);
|
||||||
|
updateState(-1, isSelected);
|
||||||
|
},
|
||||||
|
isSelected:
|
||||||
|
selectedRows.filter((r) => r === true).length ===
|
||||||
|
rows.length,
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{columns.map((column) => (
|
||||||
|
<Th
|
||||||
|
key={column.displayKey}
|
||||||
|
aria-label={t(ariaLabelKey)}
|
||||||
|
className={column.transforms?.[0]().className}
|
||||||
|
>
|
||||||
|
{t(column.displayKey || column.name)}
|
||||||
|
</Th>
|
||||||
|
))}
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
{!onCollapse ? (
|
||||||
|
<Tbody>
|
||||||
|
{(rows as IRow[]).map((row, index) => (
|
||||||
|
<Tr key={index} isExpanded={expandedRows[index]}>
|
||||||
|
{onSelect && (
|
||||||
|
<Td
|
||||||
|
select={{
|
||||||
|
rowIndex: index,
|
||||||
|
onSelect: (_, isSelected, rowIndex) => {
|
||||||
|
onSelect!(isSelected, rowIndex);
|
||||||
|
updateState(rowIndex, isSelected);
|
||||||
|
},
|
||||||
|
isSelected: selectedRows[index],
|
||||||
|
variant: isRadio ? "radio" : "checkbox",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<CellRenderer row={row} />
|
||||||
|
{(actions || actionResolver) && (
|
||||||
|
<Td isActionCell>
|
||||||
|
<ActionsColumn
|
||||||
|
items={actions || actionResolver?.(row, {})!}
|
||||||
|
extraData={{ rowIndex: index }}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
)}
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
) : (
|
||||||
|
(rows as IRow[]).map((row, index) => (
|
||||||
|
<Tbody key={index}>
|
||||||
|
{index % 2 === 0 ? (
|
||||||
|
<Tr>
|
||||||
|
<Td
|
||||||
|
expand={{
|
||||||
|
isExpanded: !!expandedRows[index],
|
||||||
|
rowIndex: index,
|
||||||
|
expandId: `${index}`,
|
||||||
|
onToggle: (_, rowIndex, isOpen) => {
|
||||||
|
onCollapse(isOpen, rowIndex);
|
||||||
|
const expand = [...expandedRows];
|
||||||
|
expand[index] = isOpen;
|
||||||
|
setExpandedRows(expand);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CellRenderer row={row} />
|
||||||
|
</Tr>
|
||||||
|
) : (
|
||||||
|
<Tr isExpanded={!!expandedRows[index - 1]}>
|
||||||
|
<Td />
|
||||||
|
<Td colSpan={columns.length}>
|
||||||
|
<ExpandableRowContent>
|
||||||
|
<CellRenderer row={row} />
|
||||||
|
</ExpandableRowContent>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
)}
|
||||||
|
</Tbody>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -229,6 +342,10 @@ export function KeycloakDataTable<T>({
|
||||||
|
|
||||||
const renderCell = (columns: (Field<T> | DetailField<T>)[], value: T) => {
|
const renderCell = (columns: (Field<T> | DetailField<T>)[], value: T) => {
|
||||||
return columns.map((col) => {
|
return columns.map((col) => {
|
||||||
|
if ("cellFormatters" in col) {
|
||||||
|
const v = get(value, col.name);
|
||||||
|
return col.cellFormatters?.reduce((s, f) => f(s), v);
|
||||||
|
}
|
||||||
if (col.cellRenderer) {
|
if (col.cellRenderer) {
|
||||||
const Component = col.cellRenderer;
|
const Component = col.cellRenderer;
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
@ -302,22 +419,6 @@ export function KeycloakDataTable<T>({
|
||||||
[search, first, max],
|
[search, first, max],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (canSelectAll) {
|
|
||||||
const checkboxes = document
|
|
||||||
.getElementsByClassName("pf-v5-c-table__check")
|
|
||||||
.item(0);
|
|
||||||
if (checkboxes) {
|
|
||||||
const checkAllCheckbox = checkboxes.children!.item(
|
|
||||||
0,
|
|
||||||
)! as HTMLInputElement;
|
|
||||||
checkAllCheckbox.indeterminate =
|
|
||||||
selected.length > 0 &&
|
|
||||||
selected.length < (filteredData || rows)!.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [selected]);
|
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
async () => {
|
async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
|
@ -153,7 +153,6 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
canSelectAll
|
|
||||||
columns={[
|
columns={[
|
||||||
{
|
{
|
||||||
name: "algorithm",
|
name: "algorithm",
|
||||||
|
@ -182,16 +181,14 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
{
|
{
|
||||||
name: "provider",
|
name: "provider",
|
||||||
displayKey: "provider",
|
displayKey: "provider",
|
||||||
cellRenderer: ({ provider }: KeyData) => provider || "",
|
cellRenderer: ({ provider }: KeyData) => provider || "-",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
transforms: [cellWidth(10)],
|
transforms: [cellWidth(10)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "validTo",
|
name: "validTo",
|
||||||
displayKey: "validTo",
|
displayKey: "validTo",
|
||||||
cellRenderer: ({ validTo }: KeyData) =>
|
cellRenderer: ({ validTo }: KeyData) =>
|
||||||
validTo ? formatDate(new Date(validTo)) : "",
|
validTo ? formatDate(new Date(validTo)) : "-",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
transforms: [cellWidth(10)],
|
transforms: [cellWidth(10)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -252,7 +249,6 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
);
|
);
|
||||||
} else return "";
|
} else return "";
|
||||||
},
|
},
|
||||||
cellFormatters: [],
|
|
||||||
transforms: [cellWidth(20)],
|
transforms: [cellWidth(20)],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { CubesIcon, InfoCircleIcon } from "@patternfly/react-icons";
|
import { CubesIcon, InfoCircleIcon } from "@patternfly/react-icons";
|
||||||
import { IRowData } from "@patternfly/react-table";
|
import { IRowData } from "@patternfly/react-table";
|
||||||
import { MouseEvent, ReactNode, useMemo, useState } from "react";
|
import { ReactNode, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useMatch, useNavigate } from "react-router-dom";
|
import { Link, useMatch, useNavigate } from "react-router-dom";
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
|
@ -165,11 +165,7 @@ export default function SessionsTable({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
async function onClickRevoke(
|
async function onClickRevoke(rowData: IRowData) {
|
||||||
event: MouseEvent,
|
|
||||||
rowIndex: number,
|
|
||||||
rowData: IRowData,
|
|
||||||
) {
|
|
||||||
const session = rowData.data as UserSessionRepresentation;
|
const session = rowData.data as UserSessionRepresentation;
|
||||||
await adminClient.realms.deleteSession({
|
await adminClient.realms.deleteSession({
|
||||||
realm,
|
realm,
|
||||||
|
@ -180,11 +176,7 @@ export default function SessionsTable({
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onClickSignOut(
|
async function onClickSignOut(rowData: IRowData) {
|
||||||
event: MouseEvent,
|
|
||||||
rowIndex: number,
|
|
||||||
rowData: IRowData,
|
|
||||||
) {
|
|
||||||
const session = rowData.data as UserSessionRepresentation;
|
const session = rowData.data as UserSessionRepresentation;
|
||||||
await adminClient.realms.deleteSession({
|
await adminClient.realms.deleteSession({
|
||||||
realm,
|
realm,
|
||||||
|
@ -230,14 +222,14 @@ export default function SessionsTable({
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: t("revoke"),
|
title: t("revoke"),
|
||||||
onClick: onClickRevoke,
|
onClick: () => onClickRevoke(rowData),
|
||||||
} as Action<UserSessionRepresentation>,
|
} as Action<UserSessionRepresentation>,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: t("signOut"),
|
title: t("signOut"),
|
||||||
onClick: onClickSignOut,
|
onClick: () => onClickSignOut(rowData),
|
||||||
} as Action<UserSessionRepresentation>,
|
} as Action<UserSessionRepresentation>,
|
||||||
];
|
];
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
|
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
|
||||||
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
||||||
|
import { useHelp } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
Button,
|
Button,
|
||||||
|
@ -12,7 +13,6 @@ import { cellWidth } from "@patternfly/react-table";
|
||||||
import { intersectionBy, sortBy, uniqBy } from "lodash-es";
|
import { intersectionBy, sortBy, uniqBy } from "lodash-es";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useHelp } from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
|
@ -21,7 +21,6 @@ import { GroupPickerDialog } from "../components/group/GroupPickerDialog";
|
||||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
import { useAccess } from "../context/access/Access";
|
import { useAccess } from "../context/access/Access";
|
||||||
import { emptyFormatter } from "../util";
|
|
||||||
|
|
||||||
type UserGroupsProps = {
|
type UserGroupsProps = {
|
||||||
user: UserRepresentation;
|
user: UserRepresentation;
|
||||||
|
@ -239,8 +238,7 @@ export const UserGroups = ({ user }: UserGroupsProps) => {
|
||||||
{
|
{
|
||||||
name: "groupMembership",
|
name: "groupMembership",
|
||||||
displayKey: "groupMembership",
|
displayKey: "groupMembership",
|
||||||
cellRenderer: (group: GroupRepresentation) => group.name || "",
|
cellRenderer: (group: GroupRepresentation) => group.name || "-",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
transforms: [cellWidth(40)],
|
transforms: [cellWidth(40)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -269,10 +267,9 @@ export const UserGroups = ({ user }: UserGroupsProps) => {
|
||||||
{t("leave")}
|
{t("leave")}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
""
|
"-"
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
transforms: [cellWidth(20)],
|
transforms: [cellWidth(20)],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|
|
@ -194,7 +194,6 @@ export const UserIdentityProviderLinks = ({
|
||||||
{
|
{
|
||||||
name: "identityProvider",
|
name: "identityProvider",
|
||||||
displayKey: "name",
|
displayKey: "name",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
cellRenderer: idpLinkRenderer,
|
cellRenderer: idpLinkRenderer,
|
||||||
transforms: [cellWidth(20)],
|
transforms: [cellWidth(20)],
|
||||||
},
|
},
|
||||||
|
@ -213,7 +212,6 @@ export const UserIdentityProviderLinks = ({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
cellRenderer: unlinkRenderer,
|
cellRenderer: unlinkRenderer,
|
||||||
transforms: [cellWidth(20)],
|
transforms: [cellWidth(20)],
|
||||||
},
|
},
|
||||||
|
@ -223,7 +221,6 @@ export const UserIdentityProviderLinks = ({
|
||||||
columns.splice(1, 0, {
|
columns.splice(1, 0, {
|
||||||
name: "type",
|
name: "type",
|
||||||
displayKey: "type",
|
displayKey: "type",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
cellRenderer: badgeRenderer1,
|
cellRenderer: badgeRenderer1,
|
||||||
transforms: [cellWidth(10)],
|
transforms: [cellWidth(10)],
|
||||||
});
|
});
|
||||||
|
@ -286,13 +283,11 @@ export const UserIdentityProviderLinks = ({
|
||||||
{
|
{
|
||||||
name: "type",
|
name: "type",
|
||||||
displayKey: "type",
|
displayKey: "type",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
cellRenderer: badgeRenderer2,
|
cellRenderer: badgeRenderer2,
|
||||||
transforms: [cellWidth(60)],
|
transforms: [cellWidth(60)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
cellFormatters: [emptyFormatter()],
|
|
||||||
cellRenderer: linkRenderer,
|
cellRenderer: linkRenderer,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|
Loading…
Reference in a new issue