Merge pull request #1578 from automatisch/AUT-620
feat: improve UI display depending on user permissions
This commit is contained in:
@@ -8,6 +8,7 @@ import * as URLS from 'config/urls';
|
|||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import { ConnectionPropType } from 'propTypes/propTypes';
|
import { ConnectionPropType } from 'propTypes/propTypes';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import Can from 'components/Can';
|
||||||
|
|
||||||
function ContextMenu(props) {
|
function ContextMenu(props) {
|
||||||
const {
|
const {
|
||||||
@@ -44,34 +45,57 @@ function ContextMenu(props) {
|
|||||||
hideBackdrop={false}
|
hideBackdrop={false}
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<Can I="read" a="Flow" passThrough>
|
||||||
component={Link}
|
{(allowed) => (
|
||||||
to={URLS.APP_FLOWS_FOR_CONNECTION(appKey, connection.id)}
|
<MenuItem
|
||||||
onClick={createActionHandler({ type: 'viewFlows' })}
|
component={Link}
|
||||||
>
|
to={URLS.APP_FLOWS_FOR_CONNECTION(appKey, connection.id)}
|
||||||
{formatMessage('connection.viewFlows')}
|
onClick={createActionHandler({ type: 'viewFlows' })}
|
||||||
</MenuItem>
|
disabled={!allowed}
|
||||||
|
>
|
||||||
<MenuItem onClick={createActionHandler({ type: 'test' })}>
|
{formatMessage('connection.viewFlows')}
|
||||||
{formatMessage('connection.testConnection')}
|
</MenuItem>
|
||||||
</MenuItem>
|
|
||||||
|
|
||||||
<MenuItem
|
|
||||||
component={Link}
|
|
||||||
disabled={disableReconnection}
|
|
||||||
to={URLS.APP_RECONNECT_CONNECTION(
|
|
||||||
appKey,
|
|
||||||
connection.id,
|
|
||||||
connection.appAuthClientId,
|
|
||||||
)}
|
)}
|
||||||
onClick={createActionHandler({ type: 'reconnect' })}
|
</Can>
|
||||||
>
|
|
||||||
{formatMessage('connection.reconnect')}
|
|
||||||
</MenuItem>
|
|
||||||
|
|
||||||
<MenuItem onClick={createActionHandler({ type: 'delete' })}>
|
<Can I="update" a="Connection" passThrough>
|
||||||
{formatMessage('connection.delete')}
|
{(allowed) => (
|
||||||
</MenuItem>
|
<MenuItem
|
||||||
|
onClick={createActionHandler({ type: 'test' })}
|
||||||
|
disabled={!allowed}
|
||||||
|
>
|
||||||
|
{formatMessage('connection.testConnection')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
|
|
||||||
|
<Can I="create" a="Connection" passThrough>
|
||||||
|
{(allowed) => (
|
||||||
|
<MenuItem
|
||||||
|
component={Link}
|
||||||
|
disabled={!allowed || disableReconnection}
|
||||||
|
to={URLS.APP_RECONNECT_CONNECTION(
|
||||||
|
appKey,
|
||||||
|
connection.id,
|
||||||
|
connection.appAuthClientId,
|
||||||
|
)}
|
||||||
|
onClick={createActionHandler({ type: 'reconnect' })}
|
||||||
|
>
|
||||||
|
{formatMessage('connection.reconnect')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
|
|
||||||
|
<Can I="delete" a="Connection" passThrough>
|
||||||
|
{(allowed) => (
|
||||||
|
<MenuItem
|
||||||
|
onClick={createActionHandler({ type: 'delete' })}
|
||||||
|
disabled={!allowed}
|
||||||
|
>
|
||||||
|
{formatMessage('connection.delete')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import AppConnectionRow from 'components/AppConnectionRow';
|
import AppConnectionRow from 'components/AppConnectionRow';
|
||||||
import NoResultFound from 'components/NoResultFound';
|
import NoResultFound from 'components/NoResultFound';
|
||||||
|
import Can from 'components/Can';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import * as URLS from 'config/urls';
|
import * as URLS from 'config/urls';
|
||||||
import useAppConnections from 'hooks/useAppConnections';
|
import useAppConnections from 'hooks/useAppConnections';
|
||||||
@@ -16,11 +17,15 @@ function AppConnections(props) {
|
|||||||
|
|
||||||
if (!hasConnections) {
|
if (!hasConnections) {
|
||||||
return (
|
return (
|
||||||
<NoResultFound
|
<Can I="create" a="Connection" passThrough>
|
||||||
to={URLS.APP_ADD_CONNECTION(appKey)}
|
{(allowed) => (
|
||||||
text={formatMessage('app.noConnections')}
|
<NoResultFound
|
||||||
data-test="connections-no-results"
|
text={formatMessage('app.noConnections')}
|
||||||
/>
|
data-test="connections-no-results"
|
||||||
|
{...(allowed && { to: URLS.APP_ADD_CONNECTION(appKey) })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ import PaginationItem from '@mui/material/PaginationItem';
|
|||||||
|
|
||||||
import * as URLS from 'config/urls';
|
import * as URLS from 'config/urls';
|
||||||
import AppFlowRow from 'components/FlowRow';
|
import AppFlowRow from 'components/FlowRow';
|
||||||
|
import Can from 'components/Can';
|
||||||
import NoResultFound from 'components/NoResultFound';
|
import NoResultFound from 'components/NoResultFound';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import useConnectionFlows from 'hooks/useConnectionFlows';
|
import useConnectionFlows from 'hooks/useConnectionFlows';
|
||||||
@@ -36,11 +37,20 @@ function AppFlows(props) {
|
|||||||
|
|
||||||
if (!hasFlows) {
|
if (!hasFlows) {
|
||||||
return (
|
return (
|
||||||
<NoResultFound
|
<Can I="create" a="Flow" passThrough>
|
||||||
to={URLS.CREATE_FLOW_WITH_APP_AND_CONNECTION(appKey, connectionId)}
|
{(allowed) => (
|
||||||
text={formatMessage('app.noFlows')}
|
<NoResultFound
|
||||||
data-test="flows-no-results"
|
text={formatMessage('app.noFlows')}
|
||||||
/>
|
data-test="flows-no-results"
|
||||||
|
{...(allowed && {
|
||||||
|
to: URLS.CREATE_FLOW_WITH_APP_AND_CONNECTION(
|
||||||
|
appKey,
|
||||||
|
connectionId
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ import AppIcon from 'components/AppIcon';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
import useApp from 'hooks/useApp';
|
import useApp from 'hooks/useApp';
|
||||||
|
import Can from 'components/Can';
|
||||||
|
|
||||||
const ReconnectConnection = (props) => {
|
const ReconnectConnection = (props) => {
|
||||||
const { application, onClose } = props;
|
const { application, onClose } = props;
|
||||||
@@ -92,7 +93,7 @@ export default function Application() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}, [appKey, appConfig?.data, currentUserAbility]);
|
}, [appKey, appConfig?.data, currentUserAbility, formatMessage]);
|
||||||
|
|
||||||
if (loading) return null;
|
if (loading) return null;
|
||||||
|
|
||||||
@@ -118,37 +119,46 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.FLOWS}/*`}
|
path={`${URLS.FLOWS}/*`}
|
||||||
element={
|
element={
|
||||||
<ConditionalIconButton
|
<Can I="create" a="Flow" passThrough>
|
||||||
type="submit"
|
{(allowed) => (
|
||||||
variant="contained"
|
<ConditionalIconButton
|
||||||
color="primary"
|
type="submit"
|
||||||
size="large"
|
variant="contained"
|
||||||
component={Link}
|
color="primary"
|
||||||
to={URLS.CREATE_FLOW_WITH_APP_AND_CONNECTION(
|
size="large"
|
||||||
appKey,
|
component={Link}
|
||||||
connectionId,
|
to={URLS.CREATE_FLOW_WITH_APP_AND_CONNECTION(
|
||||||
|
appKey,
|
||||||
|
connectionId,
|
||||||
|
)}
|
||||||
|
fullWidth
|
||||||
|
icon={<AddIcon />}
|
||||||
|
disabled={!allowed}
|
||||||
|
>
|
||||||
|
{formatMessage('app.createFlow')}
|
||||||
|
</ConditionalIconButton>
|
||||||
)}
|
)}
|
||||||
fullWidth
|
</Can>
|
||||||
icon={<AddIcon />}
|
|
||||||
disabled={!currentUserAbility.can('create', 'Flow')}
|
|
||||||
>
|
|
||||||
{formatMessage('app.createFlow')}
|
|
||||||
</ConditionalIconButton>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={`${URLS.CONNECTIONS}/*`}
|
path={`${URLS.CONNECTIONS}/*`}
|
||||||
element={
|
element={
|
||||||
<SplitButton
|
<Can I="create" a="Connection" passThrough>
|
||||||
disabled={
|
{(allowed) => (
|
||||||
(appConfig?.data &&
|
<SplitButton
|
||||||
!appConfig?.data?.canConnect &&
|
disabled={
|
||||||
!appConfig?.data?.canCustomConnect) ||
|
!allowed ||
|
||||||
connectionOptions.every(({ disabled }) => disabled)
|
(appConfig?.data &&
|
||||||
}
|
!appConfig?.data?.canConnect &&
|
||||||
options={connectionOptions}
|
!appConfig?.data?.canCustomConnect) ||
|
||||||
/>
|
connectionOptions.every(({ disabled }) => disabled)
|
||||||
|
}
|
||||||
|
options={connectionOptions}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
@@ -169,17 +179,20 @@ export default function Application() {
|
|||||||
label={formatMessage('app.connections')}
|
label={formatMessage('app.connections')}
|
||||||
to={URLS.APP_CONNECTIONS(appKey)}
|
to={URLS.APP_CONNECTIONS(appKey)}
|
||||||
value={URLS.APP_CONNECTIONS_PATTERN}
|
value={URLS.APP_CONNECTIONS_PATTERN}
|
||||||
disabled={!app.supportsConnections}
|
disabled={
|
||||||
|
!currentUserAbility.can('read', 'Connection') ||
|
||||||
|
!app.supportsConnections
|
||||||
|
}
|
||||||
component={Link}
|
component={Link}
|
||||||
data-test="connections-tab"
|
data-test="connections-tab"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Tab
|
<Tab
|
||||||
label={formatMessage('app.flows')}
|
label={formatMessage('app.flows')}
|
||||||
to={URLS.APP_FLOWS(appKey)}
|
to={URLS.APP_FLOWS(appKey)}
|
||||||
value={URLS.APP_FLOWS_PATTERN}
|
value={URLS.APP_FLOWS_PATTERN}
|
||||||
component={Link}
|
component={Link}
|
||||||
data-test="flows-tab"
|
data-test="flows-tab"
|
||||||
|
disabled={!currentUserAbility.can('read', 'Flow')}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -187,14 +200,20 @@ export default function Application() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path={`${URLS.FLOWS}/*`}
|
path={`${URLS.FLOWS}/*`}
|
||||||
element={<AppFlows appKey={appKey} />}
|
element={
|
||||||
|
<Can I="read" a="Flow">
|
||||||
|
<AppFlows appKey={appKey} />
|
||||||
|
</Can>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={`${URLS.CONNECTIONS}/*`}
|
path={`${URLS.CONNECTIONS}/*`}
|
||||||
element={<AppConnections appKey={appKey} />}
|
element={
|
||||||
|
<Can I="read" a="Connection">
|
||||||
|
<AppConnections appKey={appKey} />
|
||||||
|
</Can>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/"
|
path="/"
|
||||||
element={
|
element={
|
||||||
@@ -218,17 +237,24 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path="/connections/add"
|
path="/connections/add"
|
||||||
element={
|
element={
|
||||||
<AddAppConnection onClose={goToApplicationPage} application={app} />
|
<Can I="create" a="Connection">
|
||||||
|
<AddAppConnection
|
||||||
|
onClose={goToApplicationPage}
|
||||||
|
application={app}
|
||||||
|
/>
|
||||||
|
</Can>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/connections/:connectionId/reconnect"
|
path="/connections/:connectionId/reconnect"
|
||||||
element={
|
element={
|
||||||
<ReconnectConnection
|
<Can I="create" a="Connection">
|
||||||
application={app}
|
<ReconnectConnection
|
||||||
onClose={goToApplicationPage}
|
application={app}
|
||||||
/>
|
onClose={goToApplicationPage}
|
||||||
|
/>
|
||||||
|
</Can>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
@@ -84,10 +84,14 @@ export default function Applications() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading && !hasApps && (
|
{!isLoading && !hasApps && (
|
||||||
<NoResultFound
|
<Can I="create" a="Connection" passThrough>
|
||||||
text={formatMessage('apps.noConnections')}
|
{(allowed) => (
|
||||||
to={URLS.NEW_APP_CONNECTION}
|
<NoResultFound
|
||||||
/>
|
text={formatMessage('apps.noConnections')}
|
||||||
|
{...(allowed && { to: URLS.NEW_APP_CONNECTION })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Can>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading &&
|
{!isLoading &&
|
||||||
|
Reference in New Issue
Block a user