Skip to content

Commit 36ffb8b

Browse files
Add permission handling for connections page (#2075)
<!-- Ensure the title clearly reflects what was changed. Provide a clear and concise description of the changes made. The PR should only contain the changes related to the issue, and no other unrelated changes. --> Fixes OPS-3681
1 parent 98e84f8 commit 36ffb8b

3 files changed

Lines changed: 63 additions & 71 deletions

File tree

packages/react-ui/src/app/features/connections/components/connection-table.tsx

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import { useAuthorization } from '@/app/common/hooks/authorization-hooks';
1+
import { PermissionGuard } from '@/app/common/components/permission-guard';
22
import { appConnectionsApi } from '@/app/features/connections/lib/app-connections-api';
33
import { handleMutationError } from '@/app/interceptors/interceptor-utils';
44
import { formatUtils } from '@/app/lib/utils';
55
import {
66
BlockIcon,
7-
Button,
87
DataTable,
98
DataTableColumnHeader,
109
DropdownMenu,
1110
DropdownMenuContent,
1211
DropdownMenuItem,
1312
DropdownMenuTrigger,
14-
PageHeader,
1513
PaginationParams,
1614
RowDataWithActions,
1715
StatusIconWithText,
@@ -35,7 +33,6 @@ import { appConnectionsHooks } from '../lib/app-connections-hooks';
3533
import { useConnectionsContext } from './connections-context';
3634
import { DeleteConnectionDialog } from './delete-connection-dialog';
3735
import { EditConnectionDialog } from './edit-connection-dialog';
38-
import { NewConnectionTypeDialog } from './new-connection-type-dialog';
3936

4037
type BlockIconWithBlockNameProps = {
4138
authProviderKey: string;
@@ -107,38 +104,48 @@ const MenuConnectionColumn = ({
107104
<EllipsisVertical className="h-10 w-10" />
108105
</DropdownMenuTrigger>
109106
<DropdownMenuContent className="w-[155px]">
110-
<DropdownMenuItem
111-
key="edit"
112-
onSelect={(e) => {
113-
e.preventDefault();
114-
setIsEditConnectionDialog(true);
115-
}}
107+
<PermissionGuard
108+
permission={Permission.WRITE_APP_CONNECTION}
109+
tooltipClassName="flex"
116110
>
117-
<span className="text-black text-sm font-medium cursor-pointer w-full">
118-
{t('Edit')}
119-
</span>
120-
</DropdownMenuItem>
121-
<DropdownMenuItem
122-
key="delete"
123-
onSelect={(e) => {
124-
e.preventDefault();
125-
}}
111+
<DropdownMenuItem
112+
key="edit"
113+
onSelect={(e) => {
114+
e.preventDefault();
115+
setIsEditConnectionDialog(true);
116+
}}
117+
>
118+
<span className="text-black text-sm font-medium cursor-pointer w-full">
119+
{t('Edit')}
120+
</span>
121+
</DropdownMenuItem>
122+
</PermissionGuard>
123+
<PermissionGuard
124+
permission={Permission.DELETE_APP_CONNECTION}
125+
tooltipClassName="flex"
126126
>
127-
<DeleteConnectionDialog
128-
connectionName={row.name}
129-
mutationFn={deleteConnectionMutation}
130-
isPending={isPending}
131-
linkedFlows={linkedFlows}
127+
<DropdownMenuItem
128+
key="delete"
129+
onSelect={(e) => {
130+
e.preventDefault();
131+
}}
132132
>
133-
<button
134-
onClick={() => mutate({ connectionName: row.name })}
135-
className="text-black text-sm font-medium bg-transparent border-none p-0 m-0 cursor-pointer appearance-none w-full text-left"
136-
type="button"
133+
<DeleteConnectionDialog
134+
connectionName={row.name}
135+
mutationFn={deleteConnectionMutation}
136+
isPending={isPending}
137+
linkedFlows={linkedFlows}
137138
>
138-
{t('Delete')}
139-
</button>
140-
</DeleteConnectionDialog>
141-
</DropdownMenuItem>
139+
<button
140+
onClick={() => mutate({ connectionName: row.name })}
141+
className="text-black text-sm font-medium bg-transparent border-none p-0 m-0 cursor-pointer appearance-none w-full text-left"
142+
type="button"
143+
>
144+
{t('Delete')}
145+
</button>
146+
</DeleteConnectionDialog>
147+
</DropdownMenuItem>
148+
</PermissionGuard>
142149
</DropdownMenuContent>
143150
</DropdownMenu>
144151
{isEditConnectionDialog && (
@@ -260,32 +267,6 @@ const fetchData = async (
260267
});
261268
};
262269

263-
const ConnectionsHeader = () => {
264-
const { checkAccess } = useAuthorization();
265-
const userHasPermissionToWriteAppConnection = checkAccess(
266-
Permission.WRITE_APP_CONNECTION,
267-
);
268-
269-
const { setRefresh } = useConnectionsContext();
270-
271-
return (
272-
<PageHeader title={t('Connections')}>
273-
<div className="ml-auto mr-7">
274-
<NewConnectionTypeDialog
275-
onConnectionCreated={() => setRefresh((prev) => !prev)}
276-
>
277-
<Button
278-
variant="default"
279-
disabled={!userHasPermissionToWriteAppConnection}
280-
>
281-
{t('New Connection')}
282-
</Button>
283-
</NewConnectionTypeDialog>
284-
</div>
285-
</PageHeader>
286-
);
287-
};
288-
289270
function AppConnectionsTable() {
290271
const { refresh, setRefresh } = useConnectionsContext();
291272

@@ -303,4 +284,4 @@ function AppConnectionsTable() {
303284
);
304285
}
305286

306-
export { AppConnectionsTable, ConnectionsHeader };
287+
export { AppConnectionsTable };

packages/react-ui/src/app/router.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ import {
2727
OpsErrorBoundary,
2828
RouteErrorBoundary,
2929
} from './common/error-boundaries/ops-error-boundary';
30-
import { ConnectionsHeader } from './features/connections/components/connection-table';
3130
import { ConnectionsProvider } from './features/connections/components/connections-context';
3231
import { GlobalLayout } from './features/navigation/layout/global-layout';
3332
import { RouteWrapper } from './features/navigation/layout/route-wrapper';
3433
import NotFoundPage from './routes/404-page';
3534
import { ChangePasswordPage } from './routes/change-password';
36-
import AppConnectionsPage from './routes/connections';
35+
import AppConnectionsPage, { ConnectionsHeader } from './routes/connections';
3736
import { FlowBuilderPage } from './routes/flows/id';
3837
import { ResetPasswordPage } from './routes/forget-password';
3938
import { HomePage } from './routes/home';
Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1+
import { PermissionGuard } from '@/app/common/components/permission-guard';
12
import { AppConnectionsTable } from '@/app/features/connections/components/connection-table';
3+
import { useConnectionsContext } from '@/app/features/connections/components/connections-context';
24
import { NewConnectionTypeDialog } from '@/app/features/connections/components/new-connection-type-dialog';
3-
import { useState } from 'react';
5+
import { Button, PageHeader } from '@openops/components/ui';
6+
import { Permission } from '@openops/shared';
7+
import { t } from 'i18next';
48

5-
export default function AppConnectionsPage() {
6-
const [openNewConnectionDialog, setOpenNewConnectionDialog] = useState(false);
9+
export const ConnectionsHeader = () => {
10+
const { setRefresh } = useConnectionsContext();
711

812
return (
9-
<>
10-
<NewConnectionTypeDialog
11-
open={openNewConnectionDialog}
12-
setOpen={setOpenNewConnectionDialog}
13-
></NewConnectionTypeDialog>
14-
<AppConnectionsTable></AppConnectionsTable>
15-
</>
13+
<PageHeader title={t('Connections')}>
14+
<div className="ml-auto mr-7">
15+
<NewConnectionTypeDialog
16+
onConnectionCreated={() => setRefresh((prev) => !prev)}
17+
>
18+
<PermissionGuard permission={Permission.WRITE_APP_CONNECTION}>
19+
<Button variant="default">{t('New Connection')}</Button>
20+
</PermissionGuard>
21+
</NewConnectionTypeDialog>
22+
</div>
23+
</PageHeader>
1624
);
25+
};
26+
27+
export default function AppConnectionsPage() {
28+
return <AppConnectionsTable />;
1729
}

0 commit comments

Comments
 (0)