Merge pull request #2306 from automatisch/AUT-1388

feat: introduce two separate forms in update auth client dialog
This commit is contained in:
Ali BARIN
2025-01-27 10:57:04 +01:00
committed by GitHub
4 changed files with 212 additions and 25 deletions

View File

@@ -0,0 +1,148 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import LoadingButton from '@mui/lab/LoadingButton';
import Alert from '@mui/material/Alert';
import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import CircularProgress from '@mui/material/CircularProgress';
import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import Stack from '@mui/material/Stack';
import CloseIcon from '@mui/icons-material/Close';
import { FieldPropType } from 'propTypes/propTypes';
import useFormatMessage from 'hooks/useFormatMessage';
import InputCreator from 'components/InputCreator';
import Switch from 'components/Switch';
import TextField from 'components/TextField';
import { Form } from './style';
function AdminApplicationOAuthClientUpdateDialog(props) {
const {
error,
onClose,
title,
loading,
authFields,
defaultValues,
disabled = false,
submitAuthDefault,
submitBasicData,
submittingBasicData,
submittingAuthDefaults,
} = props;
const formatMessage = useFormatMessage();
const { name, active, ...formattedAuthDefaults } = defaultValues;
return (
<Dialog open={true} onClose={onClose}>
<IconButton
aria-label="delete"
sx={{ position: 'absolute', top: 10, right: 10 }}
onClick={onClose}
>
<CloseIcon />
</IconButton>
<DialogTitle>{title}</DialogTitle>
{error && (
<Alert severity="error" sx={{ mt: 1, wordBreak: 'break-all' }}>
{error.message}
</Alert>
)}
<DialogContent>
{loading ? (
<CircularProgress
data-test="search-for-app-loader"
sx={{ display: 'block', margin: '20px auto' }}
/>
) : (
<DialogContentText tabIndex={-1} component="div">
<Stack spacing={4}>
<Form
data-test="auth-client-form-update-basic-data"
onSubmit={submitBasicData}
defaultValues={{
active,
name,
}}
render={({ formState: { isDirty } }) => (
<>
<Switch
name="active"
label={formatMessage('oauthClient.inputActive')}
/>
<TextField
required={true}
name="name"
label={formatMessage('oauthClient.inputName')}
fullWidth
/>
<LoadingButton
data-test="submit-auth-client-form-update-basic-data"
type="submit"
variant="contained"
color="primary"
sx={{ boxShadow: 2 }}
loading={submittingBasicData}
disabled={disabled || !isDirty}
>
{formatMessage('oauthClient.buttonSubmit')}
</LoadingButton>
</>
)}
/>
{authFields?.length > 0 && (
<>
<Divider />
<Form
data-test="auth-client-form-update-auth-defaults"
onSubmit={submitAuthDefault}
defaultValues={formattedAuthDefaults}
render={({ formState: { isDirty } }) => (
<>
{authFields?.map((field) => (
<InputCreator key={field.key} schema={field} />
))}
<LoadingButton
data-test="submit-auth-client-form-update-auth-defaults"
type="submit"
variant="contained"
color="primary"
sx={{ boxShadow: 2 }}
loading={submittingAuthDefaults}
disabled={disabled || !isDirty}
>
{formatMessage('oauthClient.buttonSubmit')}
</LoadingButton>
</>
)}
/>
</>
)}
</Stack>
</DialogContentText>
)}
</DialogContent>
</Dialog>
);
}
AdminApplicationOAuthClientUpdateDialog.propTypes = {
error: PropTypes.shape({
message: PropTypes.string,
}),
onClose: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
loading: PropTypes.bool.isRequired,
submitAuthDefault: PropTypes.func.isRequired,
submitBasicData: PropTypes.func.isRequired,
authFields: PropTypes.arrayOf(FieldPropType),
submittingBasicData: PropTypes.bool.isRequired,
submittingAuthDefaults: PropTypes.bool.isRequired,
defaultValues: PropTypes.object.isRequired,
disabled: PropTypes.bool,
};
export default AdminApplicationOAuthClientUpdateDialog;

View File

@@ -0,0 +1,8 @@
import { styled } from '@mui/material/styles';
import BaseForm from 'components/Form';
export const Form = styled(BaseForm)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
paddingTop: theme.spacing(1),
}));

View File

@@ -1,10 +1,11 @@
import PropTypes from 'prop-types';
import React, { useCallback, useMemo } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { AppPropType } from 'propTypes/propTypes';
import useFormatMessage from 'hooks/useFormatMessage';
import AdminApplicationOAuthClientDialog from 'components/AdminApplicationOAuthClientDialog';
import AdminApplicationOAuthClientUpdateDialog from 'components/AdminApplicationOAuthClientUpdateDialog';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
import useAdminOAuthClient from 'hooks/useAdminOAuthClient.ee';
import useAdminUpdateOAuthClient from 'hooks/useAdminUpdateOAuthClient.ee';
import useAppAuth from 'hooks/useAppAuth';
@@ -13,40 +14,68 @@ function AdminApplicationUpdateOAuthClient(props) {
const { application, onClose } = props;
const formatMessage = useFormatMessage();
const { clientId } = useParams();
const enqueueSnackbar = useEnqueueSnackbar();
const [defaultValues, setDefaultValues] = useState({
name: '',
active: false,
});
const { data: adminOAuthClient, isLoading: isAdminOAuthClientLoading } =
useAdminOAuthClient(application.key, clientId);
const { data: auth } = useAppAuth(application.key);
const {
mutateAsync: updateOAuthClient,
isPending: isUpdateOAuthClientPending,
error: updateOAuthClientError,
} = useAdminUpdateOAuthClient(application.key, clientId);
const { mutateAsync: updateOAuthClient, error: updateOAuthClientError } =
useAdminUpdateOAuthClient(application.key, clientId);
const [basicDataUpdatePending, setBasicDataUpdatePending] = useState(false);
const [authDefaultsUpdatePending, setAuthDefaultsUpdatePending] =
useState(false);
const authFields = auth?.data?.fields?.map((field) => ({
...field,
required: false,
}));
const authFields = auth?.data?.fields;
const submitHandler = async (values) => {
const handleUpdateAuthDefaults = async (values) => {
if (!adminOAuthClient) {
return;
}
const { name, active, ...formattedAuthDefaults } = values;
setAuthDefaultsUpdatePending(true);
await updateOAuthClient({
formattedAuthDefaults,
}).finally(() => {
setAuthDefaultsUpdatePending(false);
});
setDefaultValues((prev) => ({
name: prev.name,
active: prev.active,
...formattedAuthDefaults,
}));
enqueueSnackbar(formatMessage('updateOAuthClient.success'), {
variant: 'success',
});
};
const handleUpdateBasicData = async (values) => {
if (!adminOAuthClient) {
return;
}
const { name, active } = values;
setBasicDataUpdatePending(true);
await updateOAuthClient({
name,
active,
formattedAuthDefaults,
}).finally(() => {
setBasicDataUpdatePending(false);
});
onClose();
enqueueSnackbar(formatMessage('updateOAuthClient.success'), {
variant: 'success',
});
};
const getAuthFieldsDefaultValues = useCallback(() => {
const authFieldsDefaultValue = useMemo(() => {
if (!authFields) {
return {};
}
@@ -62,24 +91,25 @@ function AdminApplicationUpdateOAuthClient(props) {
return defaultValues;
}, [auth?.fields]);
const defaultValues = useMemo(
() => ({
useEffect(() => {
setDefaultValues({
name: adminOAuthClient?.data?.name || '',
active: adminOAuthClient?.data?.active || false,
...getAuthFieldsDefaultValues(),
}),
[adminOAuthClient, getAuthFieldsDefaultValues],
);
...authFieldsDefaultValue,
});
}, [adminOAuthClient, authFieldsDefaultValue]);
return (
<AdminApplicationOAuthClientDialog
<AdminApplicationOAuthClientUpdateDialog
onClose={onClose}
error={updateOAuthClientError}
title={formatMessage('updateOAuthClient.title')}
loading={isAdminOAuthClientLoading}
submitHandler={submitHandler}
submitAuthDefault={handleUpdateAuthDefaults}
submitBasicData={handleUpdateBasicData}
submittingBasicData={basicDataUpdatePending}
submittingAuthDefaults={authDefaultsUpdatePending}
authFields={authFields}
submitting={isUpdateOAuthClientPending}
defaultValues={defaultValues}
disabled={!adminOAuthClient}
/>

View File

@@ -318,6 +318,7 @@
"oauthClient.inputName": "Name",
"oauthClient.inputActive": "Active",
"updateOAuthClient.title": "Update OAuth client",
"updateOAuthClient.success": "OAuth client successfully updated",
"notFoundPage.title": "We can't seem to find a page you're looking for.",
"notFoundPage.button": "Back to home page",
"importFlowDialog.title": "Import flow",