@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
134 lines • 6.04 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import styles from "@patternfly/react-styles/css/components/DataList/data-list";
import { ActionsColumn, Table, Tbody, Td, Th, Thead, Tr, } from "@patternfly/react-table";
import { get } from "lodash-es";
import { useMemo, useRef, useState, } from "react";
import { useTranslation } from "react-i18next";
export function DraggableTable({ keyField, columns, data, actions, onDragFinish, ...props }) {
const { t } = useTranslation();
const bodyRef = useRef(null);
const [state, setState] = useState({
draggedItemId: "",
draggingToItemIndex: -1,
dragging: false,
tempItemOrder: [""],
});
const itemOrder = useMemo(() => data.map((d) => get(d, keyField)), [data]);
const onDragStart = (evt) => {
evt.dataTransfer.effectAllowed = "move";
evt.dataTransfer.setData("text/plain", evt.currentTarget.id);
const draggedItemId = evt.currentTarget.id;
evt.currentTarget.classList.add(styles.modifiers.ghostRow);
evt.currentTarget.setAttribute("aria-grabbed", "true");
setState({ ...state, draggedItemId, dragging: true });
};
const moveItem = (arr, i1, toIndex) => {
const fromIndex = arr.indexOf(i1);
if (fromIndex === toIndex) {
return arr;
}
const temp = arr.splice(fromIndex, 1);
arr.splice(toIndex, 0, temp[0]);
return arr;
};
const move = (itemOrder) => {
if (!bodyRef.current)
return;
const ulNode = bodyRef.current;
const nodes = Array.from(ulNode.children);
if (nodes.map((node) => node.id).every((id, i) => id === itemOrder[i])) {
return;
}
while (ulNode.firstChild) {
ulNode.removeChild(ulNode.lastChild);
}
itemOrder.forEach((id) => {
ulNode.appendChild(nodes.find((n) => n.id === id));
});
};
const onDragCancel = () => {
var _a;
Array.from(((_a = bodyRef.current) === null || _a === void 0 ? void 0 : _a.children) || []).forEach((el) => {
el.classList.remove(styles.modifiers.ghostRow);
el.setAttribute("aria-grabbed", "false");
});
setState({
...state,
draggedItemId: "",
draggingToItemIndex: -1,
dragging: false,
});
};
const onDragLeave = (evt) => {
if (!isValidDrop(evt)) {
move(itemOrder);
setState({ ...state, draggingToItemIndex: -1 });
}
};
const isValidDrop = (evt) => {
const ulRect = bodyRef.current.getBoundingClientRect();
return (evt.clientX > ulRect.x &&
evt.clientX < ulRect.x + ulRect.width &&
evt.clientY > ulRect.y &&
evt.clientY < ulRect.y + ulRect.height);
};
const onDrop = (evt) => {
if (isValidDrop(evt)) {
onDragFinish(state.draggedItemId, state.tempItemOrder);
}
else {
onDragCancel();
}
};
const onDragOver = (evt) => {
var _a;
evt.preventDefault();
const td = evt.target;
const curListItem = td.closest("tr");
if (!curListItem ||
(bodyRef.current && !bodyRef.current.contains(curListItem)) ||
curListItem.id === state.draggedItemId) {
return null;
}
else {
const dragId = curListItem.id;
const draggingToItemIndex = Array.from(((_a = bodyRef.current) === null || _a === void 0 ? void 0 : _a.children) || []).findIndex((item) => item.id === dragId);
if (draggingToItemIndex !== state.draggingToItemIndex) {
const tempItemOrder = moveItem(itemOrder, state.draggedItemId, draggingToItemIndex);
move(tempItemOrder);
setState({
...state,
draggingToItemIndex,
tempItemOrder,
});
}
}
};
const onDragEnd = (evt) => {
const tr = evt.target;
tr.classList.remove(styles.modifiers.ghostRow);
tr.setAttribute("aria-grabbed", "false");
setState({
...state,
draggedItemId: "",
draggingToItemIndex: -1,
dragging: false,
});
};
const thInfo = (column) => {
if (!column.thTooltipText)
return undefined;
return {
popover: _jsx("div", { children: t(column.thTooltipText) }),
ariaLabel: t(column.thTooltipText),
};
};
return (_jsxs(Table, { "aria-label": "Draggable table", className: state.dragging ? styles.modifiers.dragOver : "", ...props, children: [_jsx(Thead, { children: _jsxs(Tr, { children: [_jsx(Th, { "aria-hidden": "true" }), columns.map((column) => (_jsx(Th, { info: thInfo(column), width: column.width, modifier: "fitContent", children: t(column.displayKey || column.name) }, column.name)))] }) }), _jsx(Tbody, { ref: bodyRef, onDragOver: onDragOver, onDrop: onDragOver, onDragLeave: onDragLeave, children: data.map((row) => (_jsxs(Tr, { id: get(row, keyField), draggable: true, onDrop: onDrop, onDragEnd: onDragEnd, onDragStart: onDragStart, children: [_jsx(Td, { draggableRow: {
id: `draggable-row-${get(row, keyField)}`,
} }), columns.map((column) => (_jsx(Td, { dataLabel: column.name, children: column.cellRenderer
? column.cellRenderer(row)
: get(row, column.name) }, `${get(row, keyField)}_${column.name}`))), actions && (_jsx(Td, { isActionCell: true, children: _jsx(ActionsColumn, { items: actions.map(({ isActionable, ...action }) => isActionable
? { ...action, isDisabled: !isActionable(row) }
: action), rowData: row }) }))] }, get(row, keyField)))) })] }));
}
//# sourceMappingURL=DraggableTable.js.map