Merge branch 'main' into AUT-1372
This commit is contained in:
@@ -9,7 +9,7 @@ import * as React from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { AppPropType } from 'propTypes/propTypes';
|
||||
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
|
||||
import AppOAuthClientsDialog from 'components/OAuthClientsDialog/index.ee';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import * as URLS from 'config/urls';
|
||||
import useAuthenticateApp from 'hooks/useAuthenticateApp.ee';
|
||||
@@ -31,12 +31,12 @@ function AddAppConnection(props) {
|
||||
const [inProgress, setInProgress] = React.useState(false);
|
||||
const hasConnection = Boolean(connectionId);
|
||||
const useShared = searchParams.get('shared') === 'true';
|
||||
const appAuthClientId = searchParams.get('appAuthClientId') || undefined;
|
||||
const oauthClientId = searchParams.get('oauthClientId') || undefined;
|
||||
const { authenticate } = useAuthenticateApp({
|
||||
appKey: key,
|
||||
connectionId,
|
||||
appAuthClientId,
|
||||
useShared: !!appAuthClientId,
|
||||
oauthClientId,
|
||||
useShared: !!oauthClientId,
|
||||
});
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -52,8 +52,8 @@ function AddAppConnection(props) {
|
||||
}, []);
|
||||
|
||||
React.useEffect(
|
||||
function initiateSharedAuthenticationForGivenAuthClient() {
|
||||
if (!appAuthClientId) return;
|
||||
function initiateSharedAuthenticationForGivenOAuthClient() {
|
||||
if (!oauthClientId) return;
|
||||
|
||||
if (!authenticate) return;
|
||||
|
||||
@@ -64,13 +64,13 @@ function AddAppConnection(props) {
|
||||
|
||||
asyncAuthenticate();
|
||||
},
|
||||
[appAuthClientId, authenticate],
|
||||
[oauthClientId, authenticate, key, navigate],
|
||||
);
|
||||
|
||||
const handleClientClick = (appAuthClientId) =>
|
||||
navigate(URLS.APP_ADD_CONNECTION_WITH_AUTH_CLIENT_ID(key, appAuthClientId));
|
||||
const handleClientClick = (oauthClientId) =>
|
||||
navigate(URLS.APP_ADD_CONNECTION_WITH_OAUTH_CLIENT_ID(key, oauthClientId));
|
||||
|
||||
const handleAuthClientsDialogClose = () =>
|
||||
const handleOAuthClientsDialogClose = () =>
|
||||
navigate(URLS.APP_CONNECTIONS(key));
|
||||
|
||||
const submitHandler = React.useCallback(
|
||||
@@ -104,14 +104,14 @@ function AddAppConnection(props) {
|
||||
|
||||
if (useShared)
|
||||
return (
|
||||
<AppAuthClientsDialog
|
||||
<AppOAuthClientsDialog
|
||||
appKey={key}
|
||||
onClose={handleAuthClientsDialogClose}
|
||||
onClose={handleOAuthClientsDialogClose}
|
||||
onClientClick={handleClientClick}
|
||||
/>
|
||||
);
|
||||
|
||||
if (appAuthClientId) return <React.Fragment />;
|
||||
if (oauthClientId) return <React.Fragment />;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
|
||||
@@ -5,11 +5,11 @@ import { AppPropType } from 'propTypes/propTypes';
|
||||
import useAdminCreateAppConfig from 'hooks/useAdminCreateAppConfig';
|
||||
import useAppConfig from 'hooks/useAppConfig.ee';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import useAdminCreateAppAuthClient from 'hooks/useAdminCreateAppAuthClient.ee';
|
||||
import AdminApplicationAuthClientDialog from 'components/AdminApplicationAuthClientDialog';
|
||||
import useAdminCreateOAuthClient from 'hooks/useAdminCreateOAuthClient.ee';
|
||||
import AdminApplicationOAuthClientDialog from 'components/AdminApplicationOAuthClientDialog';
|
||||
import useAppAuth from 'hooks/useAppAuth';
|
||||
|
||||
function AdminApplicationCreateAuthClient(props) {
|
||||
function AdminApplicationCreateOAuthClient(props) {
|
||||
const { appKey, onClose } = props;
|
||||
const { data: auth } = useAppAuth(appKey);
|
||||
const formatMessage = useFormatMessage();
|
||||
@@ -24,26 +24,26 @@ function AdminApplicationCreateAuthClient(props) {
|
||||
} = useAdminCreateAppConfig(props.appKey);
|
||||
|
||||
const {
|
||||
mutateAsync: createAppAuthClient,
|
||||
isPending: isCreateAppAuthClientPending,
|
||||
error: createAppAuthClientError,
|
||||
} = useAdminCreateAppAuthClient(appKey);
|
||||
mutateAsync: createOAuthClient,
|
||||
isPending: isCreateOAuthClientPending,
|
||||
error: createOAuthClientError,
|
||||
} = useAdminCreateOAuthClient(appKey);
|
||||
|
||||
const submitHandler = async (values) => {
|
||||
let appConfigKey = appConfig?.data?.key;
|
||||
|
||||
if (!appConfigKey) {
|
||||
const { data: appConfigData } = await createAppConfig({
|
||||
customConnectionAllowed: true,
|
||||
shared: false,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
appConfigKey = appConfigData.key;
|
||||
}
|
||||
|
||||
const { name, active, ...formattedAuthDefaults } = values;
|
||||
|
||||
await createAppAuthClient({
|
||||
await createOAuthClient({
|
||||
appKey,
|
||||
name,
|
||||
active,
|
||||
@@ -81,23 +81,23 @@ function AdminApplicationCreateAuthClient(props) {
|
||||
);
|
||||
|
||||
return (
|
||||
<AdminApplicationAuthClientDialog
|
||||
<AdminApplicationOAuthClientDialog
|
||||
onClose={onClose}
|
||||
error={createAppConfigError || createAppAuthClientError}
|
||||
title={formatMessage('createAuthClient.title')}
|
||||
error={createAppConfigError || createOAuthClientError}
|
||||
title={formatMessage('createOAuthClient.title')}
|
||||
loading={isAppConfigLoading}
|
||||
submitHandler={submitHandler}
|
||||
authFields={auth?.data?.fields}
|
||||
submitting={isCreateAppConfigPending || isCreateAppAuthClientPending}
|
||||
submitting={isCreateAppConfigPending || isCreateOAuthClientPending}
|
||||
defaultValues={defaultValues}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
AdminApplicationCreateAuthClient.propTypes = {
|
||||
AdminApplicationCreateOAuthClient.propTypes = {
|
||||
appKey: PropTypes.string.isRequired,
|
||||
application: AppPropType.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AdminApplicationCreateAuthClient;
|
||||
export default AdminApplicationCreateOAuthClient;
|
||||
@@ -15,7 +15,7 @@ import Switch from 'components/Switch';
|
||||
import TextField from 'components/TextField';
|
||||
import { Form } from './style';
|
||||
|
||||
function AdminApplicationAuthClientDialog(props) {
|
||||
function AdminApplicationOAuthClientDialog(props) {
|
||||
const {
|
||||
error,
|
||||
onClose,
|
||||
@@ -52,12 +52,12 @@ function AdminApplicationAuthClientDialog(props) {
|
||||
<>
|
||||
<Switch
|
||||
name="active"
|
||||
label={formatMessage('authClient.inputActive')}
|
||||
label={formatMessage('oauthClient.inputActive')}
|
||||
/>
|
||||
<TextField
|
||||
required={true}
|
||||
name="name"
|
||||
label={formatMessage('authClient.inputName')}
|
||||
label={formatMessage('oauthClient.inputName')}
|
||||
fullWidth
|
||||
/>
|
||||
{authFields?.map((field) => (
|
||||
@@ -72,7 +72,7 @@ function AdminApplicationAuthClientDialog(props) {
|
||||
loading={submitting}
|
||||
disabled={disabled || !isDirty}
|
||||
>
|
||||
{formatMessage('authClient.buttonSubmit')}
|
||||
{formatMessage('oauthClient.buttonSubmit')}
|
||||
</LoadingButton>
|
||||
</>
|
||||
)}
|
||||
@@ -84,7 +84,7 @@ function AdminApplicationAuthClientDialog(props) {
|
||||
);
|
||||
}
|
||||
|
||||
AdminApplicationAuthClientDialog.propTypes = {
|
||||
AdminApplicationOAuthClientDialog.propTypes = {
|
||||
error: PropTypes.shape({
|
||||
message: PropTypes.string,
|
||||
}),
|
||||
@@ -98,4 +98,4 @@ AdminApplicationAuthClientDialog.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default AdminApplicationAuthClientDialog;
|
||||
export default AdminApplicationOAuthClientDialog;
|
||||
@@ -8,29 +8,30 @@ import CardContent from '@mui/material/CardContent';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import Button from '@mui/material/Button';
|
||||
|
||||
import NoResultFound from 'components/NoResultFound';
|
||||
import * as URLS from 'config/urls';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import useAdminAppAuthClients from 'hooks/useAdminAppAuthClients';
|
||||
import NoResultFound from 'components/NoResultFound';
|
||||
import useAdminOAuthClients from 'hooks/useAdminOAuthClients';
|
||||
|
||||
function AdminApplicationAuthClients(props) {
|
||||
function AdminApplicationOAuthClients(props) {
|
||||
const { appKey } = props;
|
||||
const formatMessage = useFormatMessage();
|
||||
const { data: appAuthClients, isLoading } = useAdminAppAuthClients(appKey);
|
||||
const { data: appOAuthClients, isLoading } = useAdminOAuthClients(appKey);
|
||||
|
||||
if (isLoading)
|
||||
return <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />;
|
||||
|
||||
if (!appAuthClients?.data.length) {
|
||||
if (!appOAuthClients?.data.length) {
|
||||
return (
|
||||
<NoResultFound
|
||||
to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}
|
||||
text={formatMessage('adminAppsAuthClients.noAuthClients')}
|
||||
text={formatMessage('adminAppsOAuthClients.noOauthClients')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const sortedAuthClients = appAuthClients.data.slice().sort((a, b) => {
|
||||
const sortedOAuthClients = appOAuthClients.data.slice().sort((a, b) => {
|
||||
if (a.id < b.id) {
|
||||
return -1;
|
||||
}
|
||||
@@ -42,7 +43,7 @@ function AdminApplicationAuthClients(props) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{sortedAuthClients.map((client) => (
|
||||
{sortedOAuthClients.map((client) => (
|
||||
<Card sx={{ mb: 1 }} key={client.id} data-test="auth-client">
|
||||
<CardActionArea
|
||||
component={Link}
|
||||
@@ -59,8 +60,8 @@ function AdminApplicationAuthClients(props) {
|
||||
variant={client?.active ? 'filled' : 'outlined'}
|
||||
label={formatMessage(
|
||||
client?.active
|
||||
? 'adminAppsAuthClients.statusActive'
|
||||
: 'adminAppsAuthClients.statusInactive',
|
||||
? 'adminAppsOAuthClients.statusActive'
|
||||
: 'adminAppsOAuthClients.statusInactive',
|
||||
)}
|
||||
/>
|
||||
</Stack>
|
||||
@@ -70,8 +71,13 @@ function AdminApplicationAuthClients(props) {
|
||||
))}
|
||||
<Stack justifyContent="flex-end" direction="row">
|
||||
<Link to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}>
|
||||
<Button variant="contained" sx={{ mt: 2 }} component="div" data-test="create-auth-client-button">
|
||||
{formatMessage('createAuthClient.button')}
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ mt: 2 }}
|
||||
component="div"
|
||||
data-test="create-auth-client-button"
|
||||
>
|
||||
{formatMessage('createOAuthClient.button')}
|
||||
</Button>
|
||||
</Link>
|
||||
</Stack>
|
||||
@@ -79,8 +85,8 @@ function AdminApplicationAuthClients(props) {
|
||||
);
|
||||
}
|
||||
|
||||
AdminApplicationAuthClients.propTypes = {
|
||||
AdminApplicationOAuthClients.propTypes = {
|
||||
appKey: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default AdminApplicationAuthClients;
|
||||
export default AdminApplicationOAuthClients;
|
||||
@@ -46,9 +46,8 @@ function AdminApplicationSettings(props) {
|
||||
|
||||
const defaultValues = useMemo(
|
||||
() => ({
|
||||
customConnectionAllowed:
|
||||
appConfig?.data?.customConnectionAllowed || false,
|
||||
shared: appConfig?.data?.shared || false,
|
||||
useOnlyPredefinedAuthClients:
|
||||
appConfig?.data?.useOnlyPredefinedAuthClients || false,
|
||||
disabled: appConfig?.data?.disabled || false,
|
||||
}),
|
||||
[appConfig?.data],
|
||||
@@ -62,21 +61,17 @@ function AdminApplicationSettings(props) {
|
||||
<Paper sx={{ p: 2, mt: 4 }}>
|
||||
<Stack spacing={2} direction="column">
|
||||
<Switch
|
||||
name="customConnectionAllowed"
|
||||
label={formatMessage('adminAppsSettings.customConnectionAllowed')}
|
||||
FormControlLabelProps={{
|
||||
labelPlacement: 'start',
|
||||
}}
|
||||
/>
|
||||
<Divider />
|
||||
<Switch
|
||||
name="shared"
|
||||
label={formatMessage('adminAppsSettings.shared')}
|
||||
name="useOnlyPredefinedAuthClients"
|
||||
label={formatMessage(
|
||||
'adminAppsSettings.useOnlyPredefinedAuthClients',
|
||||
)}
|
||||
FormControlLabelProps={{
|
||||
labelPlacement: 'start',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Switch
|
||||
name="disabled"
|
||||
label={formatMessage('adminAppsSettings.disabled')}
|
||||
@@ -86,6 +81,7 @@ function AdminApplicationSettings(props) {
|
||||
/>
|
||||
<Divider />
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<LoadingButton
|
||||
data-test="submit-button"
|
||||
|
||||
@@ -4,26 +4,26 @@ import { useParams } from 'react-router-dom';
|
||||
|
||||
import { AppPropType } from 'propTypes/propTypes';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import AdminApplicationAuthClientDialog from 'components/AdminApplicationAuthClientDialog';
|
||||
import useAdminAppAuthClient from 'hooks/useAdminAppAuthClient.ee';
|
||||
import useAdminUpdateAppAuthClient from 'hooks/useAdminUpdateAppAuthClient.ee';
|
||||
import AdminApplicationOAuthClientDialog from 'components/AdminApplicationOAuthClientDialog';
|
||||
import useAdminOAuthClient from 'hooks/useAdminOAuthClient.ee';
|
||||
import useAdminUpdateOAuthClient from 'hooks/useAdminUpdateOAuthClient.ee';
|
||||
import useAppAuth from 'hooks/useAppAuth';
|
||||
|
||||
function AdminApplicationUpdateAuthClient(props) {
|
||||
function AdminApplicationUpdateOAuthClient(props) {
|
||||
const { application, onClose } = props;
|
||||
const formatMessage = useFormatMessage();
|
||||
const { clientId } = useParams();
|
||||
|
||||
const { data: adminAppAuthClient, isLoading: isAdminAuthClientLoading } =
|
||||
useAdminAppAuthClient(application.key, clientId);
|
||||
const { data: adminOAuthClient, isLoading: isAdminOAuthClientLoading } =
|
||||
useAdminOAuthClient(application.key, clientId);
|
||||
|
||||
const { data: auth } = useAppAuth(application.key);
|
||||
|
||||
const {
|
||||
mutateAsync: updateAppAuthClient,
|
||||
isPending: isUpdateAppAuthClientPending,
|
||||
error: updateAppAuthClientError,
|
||||
} = useAdminUpdateAppAuthClient(application.key, clientId);
|
||||
mutateAsync: updateOAuthClient,
|
||||
isPending: isUpdateOAuthClientPending,
|
||||
error: updateOAuthClientError,
|
||||
} = useAdminUpdateOAuthClient(application.key, clientId);
|
||||
|
||||
const authFields = auth?.data?.fields?.map((field) => ({
|
||||
...field,
|
||||
@@ -31,13 +31,13 @@ function AdminApplicationUpdateAuthClient(props) {
|
||||
}));
|
||||
|
||||
const submitHandler = async (values) => {
|
||||
if (!adminAppAuthClient) {
|
||||
if (!adminOAuthClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { name, active, ...formattedAuthDefaults } = values;
|
||||
|
||||
await updateAppAuthClient({
|
||||
await updateOAuthClient({
|
||||
name,
|
||||
active,
|
||||
formattedAuthDefaults,
|
||||
@@ -64,31 +64,31 @@ function AdminApplicationUpdateAuthClient(props) {
|
||||
|
||||
const defaultValues = useMemo(
|
||||
() => ({
|
||||
name: adminAppAuthClient?.data?.name || '',
|
||||
active: adminAppAuthClient?.data?.active || false,
|
||||
name: adminOAuthClient?.data?.name || '',
|
||||
active: adminOAuthClient?.data?.active || false,
|
||||
...getAuthFieldsDefaultValues(),
|
||||
}),
|
||||
[adminAppAuthClient, getAuthFieldsDefaultValues],
|
||||
[adminOAuthClient, getAuthFieldsDefaultValues],
|
||||
);
|
||||
|
||||
return (
|
||||
<AdminApplicationAuthClientDialog
|
||||
<AdminApplicationOAuthClientDialog
|
||||
onClose={onClose}
|
||||
error={updateAppAuthClientError}
|
||||
title={formatMessage('updateAuthClient.title')}
|
||||
loading={isAdminAuthClientLoading}
|
||||
error={updateOAuthClientError}
|
||||
title={formatMessage('updateOAuthClient.title')}
|
||||
loading={isAdminOAuthClientLoading}
|
||||
submitHandler={submitHandler}
|
||||
authFields={authFields}
|
||||
submitting={isUpdateAppAuthClientPending}
|
||||
submitting={isUpdateOAuthClientPending}
|
||||
defaultValues={defaultValues}
|
||||
disabled={!adminAppAuthClient}
|
||||
disabled={!adminOAuthClient}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
AdminApplicationUpdateAuthClient.propTypes = {
|
||||
AdminApplicationUpdateOAuthClient.propTypes = {
|
||||
application: AppPropType.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AdminApplicationUpdateAuthClient;
|
||||
export default AdminApplicationUpdateOAuthClient;
|
||||
@@ -1,53 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import * as React from 'react';
|
||||
import useAppAuthClients from 'hooks/useAppAuthClients';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
function AppAuthClientsDialog(props) {
|
||||
const { appKey, onClientClick, onClose } = props;
|
||||
const { data: appAuthClients } = useAppAuthClients(appKey);
|
||||
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
React.useEffect(
|
||||
function autoAuthenticateSingleClient() {
|
||||
if (appAuthClients?.data.length === 1) {
|
||||
onClientClick(appAuthClients.data[0].id);
|
||||
}
|
||||
},
|
||||
[appAuthClients?.data],
|
||||
);
|
||||
|
||||
if (!appAuthClients?.data.length || appAuthClients?.data.length === 1)
|
||||
return <React.Fragment />;
|
||||
|
||||
return (
|
||||
<Dialog onClose={onClose} open={true}>
|
||||
<DialogTitle>{formatMessage('appAuthClientsDialog.title')}</DialogTitle>
|
||||
|
||||
<List sx={{ pt: 0 }}>
|
||||
{appAuthClients.data.map((appAuthClient) => (
|
||||
<ListItem disableGutters key={appAuthClient.id}>
|
||||
<ListItemButton onClick={() => onClientClick(appAuthClient.id)}>
|
||||
<ListItemText primary={appAuthClient.name} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
AppAuthClientsDialog.propTypes = {
|
||||
appKey: PropTypes.string.isRequired,
|
||||
onClientClick: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AppAuthClientsDialog;
|
||||
@@ -11,14 +11,7 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||
import Can from 'components/Can';
|
||||
|
||||
function ContextMenu(props) {
|
||||
const {
|
||||
appKey,
|
||||
connection,
|
||||
onClose,
|
||||
onMenuItemClick,
|
||||
anchorEl,
|
||||
disableReconnection,
|
||||
} = props;
|
||||
const { appKey, connection, onClose, onMenuItemClick, anchorEl } = props;
|
||||
const formatMessage = useFormatMessage();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -73,11 +66,11 @@ function ContextMenu(props) {
|
||||
{(allowed) => (
|
||||
<MenuItem
|
||||
component={Link}
|
||||
disabled={!allowed || disableReconnection}
|
||||
disabled={!allowed}
|
||||
to={URLS.APP_RECONNECT_CONNECTION(
|
||||
appKey,
|
||||
connection.id,
|
||||
connection.appAuthClientId,
|
||||
connection.oauthClientId,
|
||||
)}
|
||||
onClick={createActionHandler({ type: 'reconnect' })}
|
||||
>
|
||||
@@ -109,7 +102,6 @@ ContextMenu.propTypes = {
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
disableReconnection: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default ContextMenu;
|
||||
|
||||
@@ -30,8 +30,7 @@ const countTranslation = (value) => (
|
||||
function AppConnectionRow(props) {
|
||||
const formatMessage = useFormatMessage();
|
||||
const enqueueSnackbar = useEnqueueSnackbar();
|
||||
const { id, key, formattedData, verified, createdAt, reconnectable } =
|
||||
props.connection;
|
||||
const { id, key, formattedData, verified, createdAt } = props.connection;
|
||||
const [verificationVisible, setVerificationVisible] = React.useState(false);
|
||||
const contextButtonRef = React.useRef(null);
|
||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||
@@ -174,7 +173,6 @@ function AppConnectionRow(props) {
|
||||
<ConnectionContextMenu
|
||||
appKey={key}
|
||||
connection={props.connection}
|
||||
disableReconnection={!reconnectable}
|
||||
onClose={handleClose}
|
||||
onMenuItemClick={onContextMenuAction}
|
||||
anchorEl={anchorEl}
|
||||
|
||||
@@ -7,7 +7,7 @@ import TextField from '@mui/material/TextField';
|
||||
import * as React from 'react';
|
||||
|
||||
import AddAppConnection from 'components/AddAppConnection';
|
||||
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
|
||||
import AppOAuthClientsDialog from 'components/OAuthClientsDialog/index.ee';
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import useAppConfig from 'hooks/useAppConfig.ee';
|
||||
import { EditorContext } from 'contexts/Editor';
|
||||
@@ -22,6 +22,7 @@ import useStepConnection from 'hooks/useStepConnection';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import useAppConnections from 'hooks/useAppConnections';
|
||||
import useTestConnection from 'hooks/useTestConnection';
|
||||
import useOAuthClients from 'hooks/useOAuthClients';
|
||||
|
||||
const ADD_CONNECTION_VALUE = 'ADD_CONNECTION';
|
||||
const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION';
|
||||
@@ -53,6 +54,7 @@ function ChooseConnectionSubstep(props) {
|
||||
const [showAddSharedConnectionDialog, setShowAddSharedConnectionDialog] =
|
||||
React.useState(false);
|
||||
const queryClient = useQueryClient();
|
||||
const { data: appOAuthClients } = useOAuthClients(application.key);
|
||||
|
||||
const { authenticate } = useAuthenticateApp({
|
||||
appKey: application.key,
|
||||
@@ -93,30 +95,53 @@ function ChooseConnectionSubstep(props) {
|
||||
appWithConnections?.map((connection) => optionGenerator(connection)) ||
|
||||
[];
|
||||
|
||||
const addCustomConnection = {
|
||||
label: formatMessage('chooseConnectionSubstep.addNewConnection'),
|
||||
value: ADD_CONNECTION_VALUE,
|
||||
};
|
||||
|
||||
const addConnectionWithOAuthClient = {
|
||||
label: formatMessage(
|
||||
'chooseConnectionSubstep.addConnectionWithOAuthClient',
|
||||
),
|
||||
value: ADD_SHARED_CONNECTION_VALUE,
|
||||
};
|
||||
|
||||
// means there is no app config. defaulting to custom connections only
|
||||
if (!appConfig?.data) {
|
||||
return options.concat([addCustomConnection]);
|
||||
}
|
||||
|
||||
// app is disabled.
|
||||
if (appConfig.data.disabled) return options;
|
||||
|
||||
// means only OAuth clients are allowed for connection creation and there is OAuth client
|
||||
if (
|
||||
!appConfig?.data ||
|
||||
(!appConfig.data?.disabled && appConfig.data?.customConnectionAllowed)
|
||||
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
||||
appOAuthClients.data.length > 0
|
||||
) {
|
||||
options.push({
|
||||
label: formatMessage('chooseConnectionSubstep.addNewConnection'),
|
||||
value: ADD_CONNECTION_VALUE,
|
||||
});
|
||||
return options.concat([addConnectionWithOAuthClient]);
|
||||
}
|
||||
|
||||
if (appConfig?.data?.connectionAllowed) {
|
||||
options.push({
|
||||
label: formatMessage('chooseConnectionSubstep.addNewSharedConnection'),
|
||||
value: ADD_SHARED_CONNECTION_VALUE,
|
||||
});
|
||||
// means there is no OAuth client. so we don't show the `addConnectionWithOAuthClient`
|
||||
if (
|
||||
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
||||
appOAuthClients.data.length === 0
|
||||
) {
|
||||
return options;
|
||||
}
|
||||
|
||||
return options;
|
||||
}, [data, formatMessage, appConfig?.data]);
|
||||
if (appOAuthClients.data.length === 0) {
|
||||
return options.concat([addCustomConnection]);
|
||||
}
|
||||
|
||||
const handleClientClick = async (appAuthClientId) => {
|
||||
return options.concat([addCustomConnection, addConnectionWithOAuthClient]);
|
||||
}, [data, formatMessage, appConfig, appOAuthClients]);
|
||||
|
||||
const handleClientClick = async (oauthClientId) => {
|
||||
try {
|
||||
const response = await authenticate?.({
|
||||
appAuthClientId,
|
||||
oauthClientId,
|
||||
});
|
||||
const connectionId = response?.createConnection.id;
|
||||
|
||||
@@ -162,10 +187,7 @@ function ChooseConnectionSubstep(props) {
|
||||
const handleChange = React.useCallback(
|
||||
async (event, selectedOption) => {
|
||||
if (typeof selectedOption === 'object') {
|
||||
// TODO: try to simplify type casting below.
|
||||
const typedSelectedOption = selectedOption;
|
||||
const option = typedSelectedOption;
|
||||
const connectionId = option?.value;
|
||||
const connectionId = selectedOption?.value;
|
||||
|
||||
if (connectionId === ADD_CONNECTION_VALUE) {
|
||||
setShowAddConnectionDialog(true);
|
||||
@@ -270,7 +292,7 @@ function ChooseConnectionSubstep(props) {
|
||||
)}
|
||||
|
||||
{application && showAddSharedConnectionDialog && (
|
||||
<AppAuthClientsDialog
|
||||
<AppOAuthClientsDialog
|
||||
appKey={application.key}
|
||||
onClose={() => setShowAddSharedConnectionDialog(false)}
|
||||
onClientClick={handleClientClick}
|
||||
|
||||
43
packages/web/src/components/OAuthClientsDialog/index.ee.jsx
Normal file
43
packages/web/src/components/OAuthClientsDialog/index.ee.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import * as React from 'react';
|
||||
import useOAuthClients from 'hooks/useOAuthClients';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
function AppOAuthClientsDialog(props) {
|
||||
const { appKey, onClientClick, onClose } = props;
|
||||
const { data: appOAuthClients } = useOAuthClients(appKey);
|
||||
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
if (!appOAuthClients?.data.length) return <React.Fragment />;
|
||||
|
||||
return (
|
||||
<Dialog onClose={onClose} open={true}>
|
||||
<DialogTitle>{formatMessage('appOAuthClientsDialog.title')}</DialogTitle>
|
||||
|
||||
<List sx={{ pt: 0 }}>
|
||||
{appOAuthClients.data.map((oauthClient) => (
|
||||
<ListItem disableGutters key={oauthClient.id}>
|
||||
<ListItemButton onClick={() => onClientClick(oauthClient.id)}>
|
||||
<ListItemText primary={oauthClient.name} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
AppOAuthClientsDialog.propTypes = {
|
||||
appKey: PropTypes.string.isRequired,
|
||||
onClientClick: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AppOAuthClientsDialog;
|
||||
@@ -39,14 +39,14 @@ const PermissionCatalogFieldLoader = () => {
|
||||
{[...Array(5)].map((action, index) => (
|
||||
<TableCell key={index} align="center">
|
||||
<Typography variant="subtitle2">
|
||||
<ControlledCheckbox name="value" />
|
||||
<ControlledCheckbox name="value" disabled />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
))}
|
||||
|
||||
<TableCell>
|
||||
<Stack direction="row" gap={1} justifyContent="right">
|
||||
<IconButton color="info" size="small">
|
||||
<IconButton color="info" size="small" disabled>
|
||||
<SettingsIcon />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
|
||||
@@ -21,13 +21,15 @@ const PermissionCatalogField = ({
|
||||
name = 'permissions',
|
||||
disabled = false,
|
||||
syncIsCreator = false,
|
||||
loading = false,
|
||||
}) => {
|
||||
const { data, isLoading: isPermissionCatalogLoading } =
|
||||
usePermissionCatalog();
|
||||
const permissionCatalog = data?.data;
|
||||
const [dialogName, setDialogName] = React.useState();
|
||||
|
||||
if (isPermissionCatalogLoading) return <PermissionCatalogFieldLoader />;
|
||||
if (isPermissionCatalogLoading || loading)
|
||||
return <PermissionCatalogFieldLoader />;
|
||||
|
||||
return (
|
||||
<TableContainer data-test="permissions-catalog" component={Paper}>
|
||||
@@ -118,6 +120,7 @@ PermissionCatalogField.propTypes = {
|
||||
name: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
syncIsCreator: PropTypes.bool,
|
||||
loading: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default PermissionCatalogField;
|
||||
|
||||
@@ -67,17 +67,12 @@ export default function SplitButton(props) {
|
||||
}}
|
||||
open={open}
|
||||
anchorEl={anchorRef.current}
|
||||
placement="bottom-end"
|
||||
transition
|
||||
disablePortal
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === 'bottom' ? 'center top' : 'center bottom',
|
||||
}}
|
||||
>
|
||||
{({ TransitionProps }) => (
|
||||
<Grow {...TransitionProps}>
|
||||
<Paper>
|
||||
<ClickAwayListener onClickAway={handleClose}>
|
||||
<MenuList autoFocusItem>
|
||||
|
||||
Reference in New Issue
Block a user