added shared resources to account ui (#21339)

* added shared resources to account ui

* Update js/apps/account-ui/src/resources/PermissionRequest.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>

* Update js/apps/account-ui/src/resources/PermissionRequest.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>

* Update js/apps/account-ui/src/resources/ResourcesTab.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>

---------

Co-authored-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
Erik Jan de Wit 2023-07-31 11:54:16 +02:00 committed by GitHub
parent cf911075af
commit 07129329c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 182 additions and 148 deletions

View file

@ -10,9 +10,9 @@ export const fetchResources = async (
shared: boolean | undefined = false,
): Promise<{ data: Resource[]; links: Links }> => {
const response = await get(
`/resources${shared ? "/shared-with-me?" : "?"}${new URLSearchParams(
requestParams,
)}`,
`/resources${shared ? "/shared-with-me?" : "?"}${
shared ? "" : new URLSearchParams(requestParams)
}`,
params,
);

View file

@ -187,7 +187,7 @@ export interface Resource {
client: Client;
scopes: Scope[];
uris: string[];
shareRequests: Permission[];
shareRequests?: Permission[];
}
export interface Permission {

View file

@ -67,7 +67,7 @@ export const PermissionRequest = ({
<>
<Button variant="link" onClick={toggle}>
<UserCheckIcon size="lg" />
<Badge>{resource.shareRequests.length}</Badge>
<Badge>{resource.shareRequests?.length}</Badge>
</Button>
<Modal
title={t("permissionRequest", [resource.name])}
@ -89,7 +89,7 @@ export const PermissionRequest = ({
</Tr>
</Thead>
<Tbody>
{resource.shareRequests.map((shareRequest) => (
{resource.shareRequests?.map((shareRequest) => (
<Tr key={shareRequest.username}>
<Td>
{shareRequest.firstName} {shareRequest.lastName}{" "}

View file

@ -27,7 +27,7 @@ const Resources = () => {
eventKey={1}
title={<TabTitleText>{t("sharedWithMe")}</TabTitleText>}
>
<h1>Share</h1>
<ResourcesTab isShared />
</Tab>
</Tabs>
</Page>

View file

@ -1,5 +1,7 @@
import {
Button,
Chip,
ChipGroup,
Dropdown,
DropdownItem,
KebabToggle,
@ -49,7 +51,11 @@ type PermissionDetail = {
permissions?: Permission[];
};
export const ResourcesTab = () => {
type ResourcesTabProps = {
isShared?: boolean;
};
export const ResourcesTab = ({ isShared = false }: ResourcesTabProps) => {
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
@ -67,13 +73,16 @@ export const ResourcesTab = () => {
usePromise(
async (signal) => {
const result = await fetchResources({ signal }, params);
await Promise.all(
result.data.map(
async (r) =>
(r.shareRequests = await getPermissionRequests(r._id, { signal })),
),
);
const result = await fetchResources({ signal }, params, isShared);
if (!isShared)
await Promise.all(
result.data.map(
async (r) =>
(r.shareRequests = await getPermissionRequests(r._id, {
signal,
})),
),
);
return result;
},
({ data, links }) => {
@ -145,7 +154,7 @@ export const ResourcesTab = () => {
<Th aria-hidden="true" />
<Th>{t("resourceName")}</Th>
<Th>{t("application")}</Th>
<Th>{t("permissionRequests")}</Th>
<Th>{!isShared ? t("permissionRequests") : ""}</Th>
</Tr>
</Thead>
{resources.map((resource, index) => (
@ -155,16 +164,20 @@ export const ResourcesTab = () => {
>
<Tr>
<Td
expand={{
isExpanded: details[resource._id]?.rowOpen || false,
rowIndex: index,
onToggle: () =>
toggleOpen(
resource._id,
"rowOpen",
!details[resource._id]?.rowOpen,
),
}}
expand={
!isShared
? {
isExpanded: details[resource._id]?.rowOpen || false,
rowIndex: index,
onToggle: () =>
toggleOpen(
resource._id,
"rowOpen",
!details[resource._id]?.rowOpen,
),
}
: undefined
}
/>
<Td dataLabel={t("resourceName")}>{resource.name}</Td>
<Td dataLabel={t("application")}>
@ -174,12 +187,13 @@ export const ResourcesTab = () => {
</a>
</Td>
<Td dataLabel={t("permissionRequests")}>
{resource.shareRequests.length > 0 && (
<PermissionRequest
resource={resource}
refresh={() => refresh()}
/>
)}
{resource.shareRequests &&
resource.shareRequests.length > 0 && (
<PermissionRequest
resource={resource}
refresh={() => refresh()}
/>
)}
<ShareTheResource
resource={resource}
permissions={details[resource._id]?.permissions}
@ -194,122 +208,142 @@ export const ResourcesTab = () => {
/>
)}
</Td>
<Td isActionCell>
<OverflowMenu breakpoint="lg">
<OverflowMenuContent>
<OverflowMenuGroup groupType="button">
<OverflowMenuItem>
<Button
data-testid={`share-${resource.name}`}
variant="link"
onClick={() =>
toggleOpen(resource._id, "shareDialogOpen", true)
}
>
<ShareAltIcon /> {t("share")}
</Button>
</OverflowMenuItem>
<OverflowMenuItem>
<Dropdown
position="right"
toggle={
<KebabToggle
onToggle={(open) =>
toggleOpen(resource._id, "contextOpen", open)
}
/>
}
isOpen={details[resource._id]?.contextOpen}
isPlain
dropdownItems={[
<DropdownItem
key="edit"
isDisabled={
details[resource._id]?.permissions?.length === 0
}
onClick={() =>
toggleOpen(resource._id, "editDialogOpen", true)
}
>
<EditAltIcon /> {t("edit")}
</DropdownItem>,
<ContinueCancelModal
key="unShare"
buttonTitle={
<>
<Remove2Icon /> {t("unShare")}
</>
}
modalTitle={t("unShare")}
continueLabel={t("confirm")}
cancelLabel={t("cancel")}
component={DropdownItem}
onContinue={() => removeShare(resource)}
isDisabled={
details[resource._id]?.permissions?.length === 0
}
>
{t("unShareAllConfirm")}
</ContinueCancelModal>,
]}
/>
</OverflowMenuItem>
</OverflowMenuGroup>
</OverflowMenuContent>
<OverflowMenuControl>
<Dropdown
position="right"
toggle={
<KebabToggle
onToggle={(open) =>
toggleOpen(resource._id, "contextOpen", open)
}
/>
}
isOpen={details[resource._id]?.contextOpen}
isPlain
dropdownItems={[
<OverflowMenuDropdownItem
key="share"
isShared
onClick={() =>
toggleOpen(resource._id, "shareDialogOpen", true)
}
>
<ShareAltIcon /> {t("share")}
</OverflowMenuDropdownItem>,
<OverflowMenuDropdownItem
key="edit"
isShared
onClick={() =>
toggleOpen(resource._id, "editDialogOpen", true)
}
>
<EditAltIcon /> {t("edit")}
</OverflowMenuDropdownItem>,
<ContinueCancelModal
key="unShare"
buttonTitle={
<>
<Remove2Icon /> {t("unShare")}
</>
}
modalTitle={t("unShare")}
continueLabel={t("confirm")}
cancelLabel={t("cancel")}
component={OverflowMenuDropdownItem}
onContinue={() => removeShare(resource)}
isDisabled={
details[resource._id]?.permissions?.length === 0
}
>
{t("unShareAllConfirm")}
</ContinueCancelModal>,
]}
/>
</OverflowMenuControl>
</OverflowMenu>
</Td>
{isShared ? (
<Td>
{resource.scopes.length > 0 && (
<ChipGroup categoryName={t("permissions")}>
{resource.scopes.map((scope) => (
<Chip key={scope.name} isReadOnly>
{scope.displayName || scope.name}
</Chip>
))}
</ChipGroup>
)}
</Td>
) : (
<Td isActionCell>
<OverflowMenu breakpoint="lg">
<OverflowMenuContent>
<OverflowMenuGroup groupType="button">
<OverflowMenuItem>
<Button
data-testid={`share-${resource.name}`}
variant="link"
onClick={() =>
toggleOpen(resource._id, "shareDialogOpen", true)
}
>
<ShareAltIcon /> {t("share")}
</Button>
</OverflowMenuItem>
<OverflowMenuItem>
<Dropdown
position="right"
toggle={
<KebabToggle
onToggle={(open) =>
toggleOpen(resource._id, "contextOpen", open)
}
/>
}
isOpen={details[resource._id]?.contextOpen}
isPlain
dropdownItems={[
<DropdownItem
key="edit"
isDisabled={
details[resource._id]?.permissions?.length ===
0
}
onClick={() =>
toggleOpen(
resource._id,
"editDialogOpen",
true,
)
}
>
<EditAltIcon /> {t("edit")}
</DropdownItem>,
<ContinueCancelModal
key="unShare"
buttonTitle={
<>
<Remove2Icon /> {t("unShare")}
</>
}
modalTitle={t("unShare")}
continueLabel={t("confirm")}
cancelLabel={t("cancel")}
component={DropdownItem}
onContinue={() => removeShare(resource)}
isDisabled={
details[resource._id]?.permissions?.length ===
0
}
>
{t("unShareAllConfirm")}
</ContinueCancelModal>,
]}
/>
</OverflowMenuItem>
</OverflowMenuGroup>
</OverflowMenuContent>
<OverflowMenuControl>
<Dropdown
position="right"
toggle={
<KebabToggle
onToggle={(open) =>
toggleOpen(resource._id, "contextOpen", open)
}
/>
}
isOpen={details[resource._id]?.contextOpen}
isPlain
dropdownItems={[
<OverflowMenuDropdownItem
key="share"
isShared
onClick={() =>
toggleOpen(resource._id, "shareDialogOpen", true)
}
>
<ShareAltIcon /> {t("share")}
</OverflowMenuDropdownItem>,
<OverflowMenuDropdownItem
key="edit"
isShared
onClick={() =>
toggleOpen(resource._id, "editDialogOpen", true)
}
>
<EditAltIcon /> {t("edit")}
</OverflowMenuDropdownItem>,
<ContinueCancelModal
key="unShare"
buttonTitle={
<>
<Remove2Icon /> {t("unShare")}
</>
}
modalTitle={t("unShare")}
continueLabel={t("confirm")}
cancelLabel={t("cancel")}
component={OverflowMenuDropdownItem}
onContinue={() => removeShare(resource)}
isDisabled={
details[resource._id]?.permissions?.length === 0
}
>
{t("unShareAllConfirm")}
</ContinueCancelModal>,
]}
/>
</OverflowMenuControl>
</OverflowMenu>
</Td>
)}
</Tr>
<Tr isExpanded={details[resource._id]?.rowOpen || false}>
<Td colSpan={4} textCenter>