Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const GluuCommitDialog = ({
const isDark = themeState.theme === THEME_DARK
const { classes } = useStyles({ isDark })
const [userMessage, setUserMessage] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false)
const { loadingWebhooks, webhookModal } = useSelector((state: RootState) => state.webhookReducer)

const webhookResourceId = useMemo(() => ADMIN_UI_RESOURCES.Webhooks, [])
Expand Down Expand Up @@ -101,13 +102,20 @@ const GluuCommitDialog = ({
setUserMessage('')
}, [handler, onCloseModal])

const handleAccept = useCallback(() => {
const handleAccept = useCallback(async () => {
if (isSubmitting) return
setIsSubmitting(true)
if (formik) {
formik.setFieldValue('action_message', userMessage)
}
onAccept(userMessage)
closeModal()
}, [formik, onAccept, userMessage, closeModal])
try {
const result = onAccept(userMessage)
await Promise.resolve(result)
closeModal()
} finally {
setIsSubmitting(false)
}
}, [formik, onAccept, userMessage, closeModal, isSubmitting])

const handleOverlayKeyDown = useCallback(
(e: React.KeyboardEvent) => {
Expand Down Expand Up @@ -195,7 +203,7 @@ const GluuCommitDialog = ({
<div className={classes.buttonRow}>
<GluuButton
onClick={handleAccept}
disabled={!isValid}
disabled={!isValid || isSubmitting}
backgroundColor={customColors.statusActive}
textColor={customColors.white}
borderColor="transparent"
Expand Down
20 changes: 14 additions & 6 deletions admin-ui/app/routes/Apps/Gluu/GluuCommitDialogLegacy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const GluuCommitDialogLegacy = ({
const themeColors = getThemeColor(selectedTheme)
const [isOpen, setIsOpen] = useState<number | null>(null)
const [userMessage, setUserMessage] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false)
const { loadingWebhooks, webhookModal } = useSelector((state: RootState) => state.webhookReducer)

const webhookResourceId = ADMIN_UI_RESOURCES.Webhooks
Expand Down Expand Up @@ -90,14 +91,21 @@ const GluuCommitDialogLegacy = ({
prevModalRef.current = modal
}, [modal])

function handleAccept() {
async function handleAccept() {
if (isSubmitting) return
if (formik) {
formik.setFieldValue('action_message', userMessage)
}
onAccept(userMessage)
handler()
onCloseModal()
setUserMessage('')
setIsSubmitting(true)
try {
const result = onAccept(userMessage)
await Promise.resolve(result)
} finally {
setIsSubmitting(false)
handler()
onCloseModal()
setUserMessage('')
}
}

const closeModal = () => {
Expand Down Expand Up @@ -324,7 +332,7 @@ const GluuCommitDialogLegacy = ({
backgroundColor={customColors.primaryDark}
textColor={customColors.white}
disableHoverStyles
disabled={!active}
disabled={!active || isSubmitting}
>
<i className="fa fa-check-circle me-2" />
{t('actions.accept')}
Expand Down
13 changes: 7 additions & 6 deletions admin-ui/app/utils/hooks/useWebhookDialogAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useCedarling } from '@/cedarling'
import { ADMIN_UI_RESOURCES } from '@/cedarling/utility'
import { CEDAR_RESOURCE_SCOPES } from '@/cedarling/constants/resourceScopes'
import customColors from '@/customColors'
import GluuLoader from 'Routes/Apps/Gluu/GluuLoader'

interface UseWebhookDialogActionProps {
feature?: string
Expand Down Expand Up @@ -111,9 +112,7 @@ const useWebhookDialogAction = ({ feature, modal }: UseWebhookDialogActionProps)
className="modal-outline-primary"
>
<ModalHeader toggle={closeWebhookTriggerModal}>
{loadingWebhooks ? (
<>Loading....</>
) : (
{!loadingWebhooks && (
<>
<i
onClick={closeWebhookTriggerModal}
Expand All @@ -127,7 +126,11 @@ const useWebhookDialogAction = ({ feature, modal }: UseWebhookDialogActionProps)
</>
)}
</ModalHeader>
{!loadingWebhooks ? (
{loadingWebhooks ? (
<ModalBody>
<GluuLoader blocking />
</ModalBody>
) : (
<>
<ModalBody>
<Box sx={{ display: 'flex', flexDirection: 'column' }} px={2}>
Expand Down Expand Up @@ -184,8 +187,6 @@ const useWebhookDialogAction = ({ feature, modal }: UseWebhookDialogActionProps)
</Button>
</ModalFooter>
</>
) : (
<></>
)}
</Modal>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState, useMemo, useCallback, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { useDispatch, useSelector, useStore } from 'react-redux'
import { useQueryClient } from '@tanstack/react-query'
import { useFormik, setIn } from 'formik'
import * as Yup from 'yup'
Expand Down Expand Up @@ -29,12 +29,7 @@ import { CEDAR_RESOURCE_SCOPES } from '@/cedarling/constants/resourceScopes'
import { ADMIN_UI_RESOURCES } from '@/cedarling/utility'
import { useAppNavigation, ROUTES } from '@/helpers/navigation'
import { useAcrAudit } from '../AuthN/hooks'
import {
generateLabel,
isRenamedKey,
renamedFieldFromObject,
useAuthServerPropertiesActions,
} from './Properties/utils'
import { generateLabel, isRenamedKey, renamedFieldFromObject } from './Properties/utils'
import { createAppConfigurationSchema } from './Properties/utils/validations'
import type { AppConfiguration, RootState, JsonPatch, AcrPutOperation, Script } from './types'
import type { GluuCommitDialogOperation, JsonValue } from 'Routes/Apps/Gluu/types/index'
Expand All @@ -45,12 +40,13 @@ const AuthPage: React.FC = () => {
SetTitle(t('titles.jans_json_property'))

const dispatch = useDispatch()
const store = useStore()
const queryClient = useQueryClient()
const { navigateBack } = useAppNavigation()
const { hasCedarWritePermission, authorizeHelper } = useCedarling()
const { logAuthServerPropertiesUpdate } = useAuthServerPropertiesActions()
const { logAcrUpdate } = useAcrAudit()
const configuration = useSelector((state: RootState) => state.jsonConfigReducer.configuration)
const jsonConfigLoading = useSelector((state: RootState) => state.jsonConfigReducer.loading)
const scripts = useSelector((state: RootState) => state.initReducer.scripts)
const { data: acrs, isLoading: acrLoading } = useGetAcrs({
query: { staleTime: 30000 },
Expand Down Expand Up @@ -294,6 +290,16 @@ const AuthPage: React.FC = () => {
} as unknown as ActionData
buildPayload(userAction, message, postBody)
dispatch(patchJsonConfig({ action: userAction }))
await new Promise<void>((resolve) => {
const unsub = store.subscribe(() => {
const loading = (store.getState() as { jsonConfigReducer?: { loading?: boolean } })
?.jsonConfigReducer?.loading
if (!loading) {
unsub()
resolve()
}
})
})
}
if (put && put.value) {
const newAcr = { defaultAcr: put.value || acrs?.defaultAcr }
Expand All @@ -304,21 +310,8 @@ const AuthPage: React.FC = () => {
console.error('Error updating ACR:', error)
}
}
let auditSuccess = true
try {
const auditPayload = {
requestBody: patches,
...(put && put.value ? { defaultAcr: put.value } : {}),
}
auditSuccess = await logAuthServerPropertiesUpdate(message, auditPayload)
} catch (auditError) {
console.error('Error logging audit:', auditError)
auditSuccess = false
}
if (auditSuccess) {
if (patches.length === 0) {
toast.success(t('messages.success_in_saving'))
} else {
toast.warning(t('messages.success_in_saving_audit_failed'))
}
} catch (err) {
console.error('Error updating auth server properties:', err)
Expand All @@ -327,18 +320,19 @@ const AuthPage: React.FC = () => {
toast.error(errorMsg)
}
},
[patches, put, acrs, dispatch, putAcrsMutation, logAcrUpdate, logAuthServerPropertiesUpdate, t],
[patches, put, acrs, dispatch, store, putAcrsMutation, logAcrUpdate, t],
)
const submitForm = useCallback(
async (message: string) => {
toggle()
await handleSubmit(message)
},
[toggle, handleSubmit],
[handleSubmit],
)

return (
<GluuLoader blocking={isConfigEmpty || acrLoading || putAcrsMutation.isPending}>
<GluuLoader
blocking={isConfigEmpty || acrLoading || putAcrsMutation.isPending || jsonConfigLoading}
>
<Card style={{ borderRadius: 24 }}>
<CardHeader>
<div style={{ display: 'flex' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ const ApiConfigForm: React.FC<ApiConfigFormProps> = ({ configuration, onSubmit }

const submitForm = useCallback(
async (userMessage: string) => {
toggle()
try {
await onSubmit(patches, userMessage)
setPatches([])
Expand All @@ -265,7 +264,7 @@ const ApiConfigForm: React.FC<ApiConfigFormProps> = ({ configuration, onSubmit }
toast.error(t('messages.error_in_saving'))
}
},
[toggle, onSubmit, patches, t],
[onSubmit, patches, t],
)

const handleBack = useCallback(() => {
Expand Down
3 changes: 1 addition & 2 deletions admin-ui/plugins/fido/components/DynamicConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ const DynamicConfiguration: React.FC<DynamicConfigurationProps> = ({
if (readOnly) {
return
}
toggle()
handleSubmit(formik.values, userMessage)
},
[handleSubmit, toggle, formik.values, readOnly],
[handleSubmit, formik.values, readOnly],
)

const handleCancel = useCallback(() => {
Expand Down
3 changes: 1 addition & 2 deletions admin-ui/plugins/fido/components/StaticConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,9 @@ const StaticConfiguration: React.FC<StaticConfigurationProps> = ({
if (readOnly) {
return
}
toggle()
handleSubmit(formik.values, userMessage)
},
[handleSubmit, toggle, formik.values, readOnly],
[handleSubmit, formik.values, readOnly],
)

const handleCancel = useCallback(() => {
Expand Down
10 changes: 6 additions & 4 deletions admin-ui/plugins/scim/components/ScimConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ const ScimConfiguration: React.FC<ScimConfigurationProps> = ({
}, [formik.values])

const submitForm = useCallback(
(userMessage: string): void => {
toggle()
handleSubmit({ ...formik.values, action_message: userMessage })
(userMessage: string): void | Promise<unknown> => {
return handleSubmit({
...formik.values,
action_message: userMessage,
}) as void | Promise<unknown>
},
[handleSubmit, toggle, formik.values],
[handleSubmit, formik.values],
)

const handleCancel = useCallback(() => {
Expand Down
4 changes: 2 additions & 2 deletions admin-ui/plugins/scim/components/ScimPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const ScimPage: React.FC = () => {
})

const handleSubmit = useCallback(
(formValues: ScimFormValues): void => {
(formValues: ScimFormValues): void | Promise<unknown> => {
if (!scimConfiguration) {
dispatch(updateToast(true, 'error', t('messages.no_configuration_loaded')))
return
Expand All @@ -155,7 +155,7 @@ const ScimPage: React.FC = () => {
return
}
userMessageRef.current = action_message || ''
patchScimMutation.mutate({ data: patches })
return patchScimMutation.mutateAsync({ data: patches })
},
[scimConfiguration, patchScimMutation, dispatch, t],
)
Expand Down
2 changes: 1 addition & 1 deletion admin-ui/plugins/scim/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface ScimFormValues {

export interface ScimConfigurationProps {
scimConfiguration: AppConfiguration3 | undefined
handleSubmit: (formValues: ScimFormValues) => void
handleSubmit: (formValues: ScimFormValues) => void | Promise<unknown>
isSubmitting: boolean
canWriteScim?: boolean
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ function SmtpForm(props: Readonly<SmtpFormProps>) {
return
}

toggle()
const trimmedValues = trimObjectStrings(
formik.values as unknown as Record<string, unknown>,
) as unknown as SmtpFormValues
Expand Down
Loading