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:
parent
cf911075af
commit
07129329c3
5 changed files with 182 additions and 148 deletions
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ export interface Resource {
|
|||
client: Client;
|
||||
scopes: Scope[];
|
||||
uris: string[];
|
||||
shareRequests: Permission[];
|
||||
shareRequests?: Permission[];
|
||||
}
|
||||
|
||||
export interface Permission {
|
||||
|
|
|
@ -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}{" "}
|
||||
|
|
|
@ -27,7 +27,7 @@ const Resources = () => {
|
|||
eventKey={1}
|
||||
title={<TabTitleText>{t("sharedWithMe")}</TabTitleText>}
|
||||
>
|
||||
<h1>Share</h1>
|
||||
<ResourcesTab isShared />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Page>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue