Skip to content

Commit 6cd05ac

Browse files
authored
Merge branch 'main' into admin-ui-2462
2 parents 9274d52 + f0ac17b commit 6cd05ac

File tree

84 files changed

+1376
-915
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1376
-915
lines changed

admin-ui/app/types/yaml.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
interface YamlModuleContent {
2+
components?: {
3+
schemas?: Record<string, unknown>
4+
}
5+
[key: string]: unknown
6+
}
7+
8+
declare module '*.yaml' {
9+
const content: YamlModuleContent
10+
export default content
11+
}
12+
13+
declare module '*.yml' {
14+
const content: YamlModuleContent
15+
export default content
16+
}

admin-ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "gluu-admin-ui",
3-
"version": "5.14.0",
3+
"version": "0.0.0",
44
"description": "UI to administer the jans-sever features",
55
"keywords": [
66
"jans-server",

admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.js

Lines changed: 0 additions & 123 deletions
This file was deleted.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import React, { useCallback, useState, useEffect } from 'react'
2+
import GluuCommitDialog from 'Routes/Apps/Gluu/GluuCommitDialog'
3+
import { FormGroup } from 'Components'
4+
import { useNavigate } from 'react-router-dom'
5+
import spec from '../../../../../configApiSpecs.yaml'
6+
import { API_CONFIG_WRITE } from 'Utils/PermChecker'
7+
import { useCedarling } from '@/cedarling'
8+
import GluuCommitFooter from 'Routes/Apps/Gluu/GluuCommitFooter'
9+
import JsonPropertyBuilderConfigApi from './JsonPropertyBuilderConfigApi'
10+
import { toast } from 'react-toastify'
11+
import type { ApiAppConfiguration, JsonPatch } from './types'
12+
13+
interface ApiConfigFormProps {
14+
configuration: ApiAppConfiguration
15+
onSubmit: (patches: JsonPatch[], message: string) => Promise<void>
16+
}
17+
18+
interface SpecSchema {
19+
components: {
20+
schemas: {
21+
ApiAppConfiguration: {
22+
properties: Record<string, unknown>
23+
}
24+
}
25+
}
26+
}
27+
28+
const { properties: schema } = (spec as unknown as SpecSchema).components?.schemas
29+
?.ApiAppConfiguration ?? { properties: {} }
30+
31+
const ApiConfigForm: React.FC<ApiConfigFormProps> = ({ configuration, onSubmit }) => {
32+
const { hasCedarPermission, authorize } = useCedarling()
33+
const navigate = useNavigate()
34+
const [modal, setModal] = useState(false)
35+
const [patches, setPatches] = useState<JsonPatch[]>([])
36+
37+
const operations = patches
38+
39+
useEffect(() => {
40+
const authorizePermissions = async () => {
41+
try {
42+
await authorize([API_CONFIG_WRITE])
43+
} catch (error) {
44+
console.error('Error authorizing API config permissions:', error)
45+
}
46+
}
47+
48+
authorizePermissions()
49+
}, [authorize])
50+
51+
const toggle = useCallback(() => {
52+
if (patches?.length > 0) {
53+
setModal((prev) => !prev)
54+
} else {
55+
toast.error('No changes to update')
56+
}
57+
}, [patches])
58+
59+
const submitForm = useCallback(
60+
async (userMessage: string) => {
61+
toggle()
62+
await onSubmit(patches, userMessage)
63+
},
64+
[toggle, onSubmit, patches],
65+
)
66+
67+
function generateLabel(name: string): string {
68+
const result = name.replace(/([A-Z])/g, ' $1')
69+
return result.charAt(0).toUpperCase() + result.slice(1)
70+
}
71+
72+
const patchHandler = (patch: JsonPatch) => {
73+
setPatches((existingPatches) => [...existingPatches, patch])
74+
}
75+
76+
const handleBack = () => {
77+
navigate('/home/dashboard')
78+
}
79+
80+
return (
81+
<>
82+
{Object.keys(configuration).map((propKey) => (
83+
<JsonPropertyBuilderConfigApi
84+
key={propKey}
85+
propKey={propKey}
86+
propValue={configuration[propKey as keyof ApiAppConfiguration]}
87+
lSize={6}
88+
handler={patchHandler}
89+
schema={schema[propKey] as { type?: string; items?: { type?: string; enum?: string[] } }}
90+
doc_category="config_api_properties"
91+
/>
92+
))}
93+
94+
<FormGroup row></FormGroup>
95+
{hasCedarPermission(API_CONFIG_WRITE) && (
96+
<GluuCommitFooter
97+
saveHandler={toggle}
98+
hideButtons={{ back: false }}
99+
backButtonLabel="Back"
100+
backButtonHandler={handleBack}
101+
/>
102+
)}
103+
104+
{hasCedarPermission(API_CONFIG_WRITE) && (
105+
<GluuCommitDialog
106+
handler={toggle}
107+
modal={modal}
108+
operations={operations}
109+
onAccept={submitForm}
110+
/>
111+
)}
112+
</>
113+
)
114+
}
115+
116+
export default ApiConfigForm

admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ConfigApiPage.js

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React, { useState } from 'react'
2+
import ApiConfigForm from './ApiConfigForm'
3+
import { Card } from 'Components'
4+
import GluuLoader from 'Routes/Apps/Gluu/GluuLoader'
5+
import applicationStyle from 'Routes/Apps/Gluu/styles/applicationstyle'
6+
import SetTitle from 'Utils/SetTitle'
7+
import { useTranslation } from 'react-i18next'
8+
import { useGetConfigApiProperties, usePatchConfigApiProperties } from 'JansConfigApi'
9+
import { useConfigApiActions } from './hooks'
10+
import { toast } from 'react-toastify'
11+
import type { JsonPatch } from './types'
12+
13+
function ConfigApiPage(): JSX.Element {
14+
const { t } = useTranslation()
15+
const { logConfigApiUpdate } = useConfigApiActions()
16+
const [errorMessage, setErrorMessage] = useState<string | null>(null)
17+
18+
SetTitle(t('titles.config_api_configuration'))
19+
20+
const { data: configuration, isLoading, error } = useGetConfigApiProperties()
21+
22+
const patchConfigMutation = usePatchConfigApiProperties()
23+
24+
const handleSubmit = async (patches: JsonPatch[], message: string) => {
25+
try {
26+
setErrorMessage(null)
27+
28+
await patchConfigMutation.mutateAsync({ data: patches })
29+
30+
let auditSuccess = true
31+
try {
32+
await logConfigApiUpdate(message, { requestBody: patches })
33+
} catch (auditError) {
34+
console.error('Error logging audit:', auditError)
35+
auditSuccess = false
36+
}
37+
38+
if (auditSuccess) {
39+
toast.success(t('messages.success_in_saving'))
40+
} else {
41+
toast.warning(t('messages.success_in_saving_audit_failed'))
42+
}
43+
} catch (err) {
44+
console.error('Error updating config:', err)
45+
const errorMsg = err instanceof Error ? err.message : t('messages.error_in_saving')
46+
setErrorMessage(errorMsg)
47+
toast.error(errorMsg)
48+
}
49+
}
50+
51+
const loading = patchConfigMutation.isPending || isLoading
52+
53+
if (error) {
54+
return (
55+
<Card style={applicationStyle.mainCard}>
56+
<div className="p-4 text-danger">
57+
{t('messages.error_in_loading')}: {error instanceof Error ? error.message : String(error)}
58+
</div>
59+
</Card>
60+
)
61+
}
62+
63+
return (
64+
<GluuLoader blocking={loading}>
65+
<Card style={applicationStyle.mainCard}>
66+
{configuration && <ApiConfigForm configuration={configuration} onSubmit={handleSubmit} />}
67+
{errorMessage && (
68+
<div className="alert alert-danger mt-3" role="alert">
69+
{errorMessage}
70+
</div>
71+
)}
72+
</Card>
73+
</GluuLoader>
74+
)
75+
}
76+
77+
export default ConfigApiPage

0 commit comments

Comments
 (0)