2023-01-16 10:23:07 +00:00
|
|
|
import {
|
|
|
|
Badge,
|
|
|
|
Button,
|
|
|
|
Chip,
|
|
|
|
Modal,
|
|
|
|
ModalVariant,
|
|
|
|
Text,
|
|
|
|
} from "@patternfly/react-core";
|
|
|
|
import { UserCheckIcon } from "@patternfly/react-icons";
|
|
|
|
|
|
|
|
import {
|
|
|
|
TableComposable,
|
|
|
|
Tbody,
|
|
|
|
Td,
|
|
|
|
Th,
|
|
|
|
Thead,
|
|
|
|
Tr,
|
|
|
|
} from "@patternfly/react-table";
|
|
|
|
import { useState } from "react";
|
|
|
|
import { useTranslation } from "react-i18next";
|
2023-02-07 11:29:30 +00:00
|
|
|
import { useAlerts } from "ui-shared";
|
2023-01-16 10:23:07 +00:00
|
|
|
import { fetchPermission, updateRequest } from "../api";
|
|
|
|
import { Permission, Resource } from "../api/representations";
|
|
|
|
|
|
|
|
type PermissionRequestProps = {
|
|
|
|
resource: Resource;
|
|
|
|
refresh: () => void;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const PermissionRequest = ({
|
|
|
|
resource,
|
|
|
|
refresh,
|
|
|
|
}: PermissionRequestProps) => {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { addAlert, addError } = useAlerts();
|
|
|
|
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
|
|
|
|
const toggle = () => setOpen(!open);
|
|
|
|
|
|
|
|
const approveDeny = async (
|
|
|
|
shareRequest: Permission,
|
|
|
|
approve: boolean = false
|
|
|
|
) => {
|
|
|
|
try {
|
|
|
|
const permissions = await fetchPermission({}, resource._id);
|
|
|
|
const { scopes, username } = permissions.find(
|
|
|
|
(p) => p.username === shareRequest.username
|
|
|
|
)!;
|
|
|
|
|
|
|
|
await updateRequest(
|
|
|
|
resource._id,
|
|
|
|
username,
|
|
|
|
approve
|
|
|
|
? [...(scopes as string[]), ...(shareRequest.scopes as string[])]
|
|
|
|
: scopes
|
|
|
|
);
|
2023-03-02 12:54:34 +00:00
|
|
|
addAlert(t("shareSuccess"));
|
2023-01-16 10:23:07 +00:00
|
|
|
toggle();
|
|
|
|
refresh();
|
|
|
|
} catch (error) {
|
2023-03-02 12:54:34 +00:00
|
|
|
addError(t("shareError", { error }).toString());
|
2023-01-16 10:23:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Button variant="link" onClick={toggle}>
|
|
|
|
<UserCheckIcon size="lg" />
|
|
|
|
<Badge>{resource.shareRequests.length}</Badge>
|
|
|
|
</Button>
|
|
|
|
<Modal
|
|
|
|
title={t("permissionRequest", [resource.name])}
|
|
|
|
variant={ModalVariant.large}
|
|
|
|
isOpen={open}
|
|
|
|
onClose={toggle}
|
|
|
|
actions={[
|
|
|
|
<Button key="close" variant="link" onClick={toggle}>
|
|
|
|
{t("close")}
|
|
|
|
</Button>,
|
|
|
|
]}
|
|
|
|
>
|
|
|
|
<TableComposable aria-label={t("resources")}>
|
|
|
|
<Thead>
|
|
|
|
<Tr>
|
|
|
|
<Th>{t("requestor")}</Th>
|
|
|
|
<Th>{t("permissionRequests")}</Th>
|
|
|
|
<Th></Th>
|
|
|
|
</Tr>
|
|
|
|
</Thead>
|
|
|
|
<Tbody>
|
|
|
|
{resource.shareRequests.map((shareRequest) => (
|
|
|
|
<Tr key={shareRequest.username}>
|
|
|
|
<Td>
|
|
|
|
{shareRequest.firstName} {shareRequest.lastName}{" "}
|
|
|
|
{shareRequest.lastName ? "" : shareRequest.username}
|
|
|
|
<br />
|
|
|
|
<Text component="small">{shareRequest.email}</Text>
|
|
|
|
</Td>
|
|
|
|
<Td>
|
|
|
|
{shareRequest.scopes.map((scope) => (
|
|
|
|
<Chip key={scope.toString()} isReadOnly>
|
2023-02-13 07:18:16 +00:00
|
|
|
{scope as string}
|
2023-01-16 10:23:07 +00:00
|
|
|
</Chip>
|
|
|
|
))}
|
|
|
|
</Td>
|
|
|
|
<Td>
|
|
|
|
<Button
|
|
|
|
onClick={() => {
|
|
|
|
approveDeny(shareRequest, true);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{t("accept")}
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
onClick={() => {
|
|
|
|
approveDeny(shareRequest);
|
|
|
|
}}
|
|
|
|
className="pf-u-ml-sm"
|
|
|
|
variant="danger"
|
|
|
|
>
|
|
|
|
{t("doDeny")}
|
|
|
|
</Button>
|
|
|
|
</Td>
|
|
|
|
</Tr>
|
|
|
|
))}
|
|
|
|
</Tbody>
|
|
|
|
</TableComposable>
|
|
|
|
</Modal>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|