Skip to content

Commit

Permalink
feat(admin-ui): setup the jans assets management structure #1635
Browse files Browse the repository at this point in the history
  • Loading branch information
syntrydy committed Mar 29, 2024
1 parent 34f3e17 commit ccf7287
Show file tree
Hide file tree
Showing 11 changed files with 672 additions and 3 deletions.
2 changes: 2 additions & 0 deletions admin-ui/app/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@
"portuguese": "Portuguese"
},
"menus": {
"assets": "Assets",
"scim": "SCIM",
"saml": "SAML",
"trust_relationships": "Trust Relationships",
Expand Down Expand Up @@ -756,6 +757,7 @@
"titles": {
"acrs": "ACRs",
"active_users": "Actives Users && Access Token Stats",
"assets": "Jans Assets",
"introspection_object": "Introspection Object",
"acrs_logging": "ACRs && Logging",
"algorithmic_keys": "Algorithmic Keys",
Expand Down
2 changes: 2 additions & 0 deletions admin-ui/app/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"menus": {
"adminui": "Administratrice",
"assets": "Assets",
"config-api": "Config-API",
"webhooks": "Webhooks",
"add_source": "Ajouter une source",
Expand Down Expand Up @@ -680,6 +681,7 @@
},
"titles": {
"acrs": "ACR",
"assets": "Jans Assets",
"algorithmic_keys": "Clés algorithmiques",
"introspection_object": "Objet d'inspection",
"all_attributes": "Tous les attributs",
Expand Down
2 changes: 2 additions & 0 deletions admin-ui/app/locales/pt/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"menus": {
"adminui": "Admin",
"assets": "Assets",
"config-api": "Config-API",
"saml": "SAML",
"add_source": "Adicionar Fonte",
Expand Down Expand Up @@ -676,6 +677,7 @@
},
"titles": {
"acrs": "ACRs",
"assets": "Jans Assets",
"algorithmic_keys": "Chaves Algorítmicas",
"introspection_object": "Objeto de introspecção",
"all_attributes": "Todos os Atributos",
Expand Down
3 changes: 3 additions & 0 deletions admin-ui/app/utils/PermChecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ export const MESSAGE_WRITE = BASE_URL + '/config/message.write'
export const WEBHOOK_READ = BASE_URL + '/jans-auth-server/config/adminui/webhook.readonly'
export const WEBHOOK_WRITE = BASE_URL + '/jans-auth-server/config/adminui/webhook.write'
export const WEBHOOK_DELETE = BASE_URL + '/jans-auth-server/config/adminui/webhook.delete'
export const ASSETS_READ = BASE_URL + '/jans_asset-read'
export const ASSETS_WRITE = BASE_URL + '/config/jans_asset-write'
export const ASSETS_DELETE = BASE_URL + '/config/jans_asset-delete'

export const hasPermission = (scopes, scope) => {
let available = false
Expand Down
20 changes: 20 additions & 0 deletions admin-ui/plugins/admin/components/Assets/JansAssetAddPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import { Card } from 'Components'
import applicationStyle from 'Routes/Apps/Gluu/styles/applicationstyle'
import WebhookForm from '../Webhook/WebhookForm'
import GluuLoader from 'Routes/Apps/Gluu/GluuLoader'
import { useSelector } from 'react-redux'

const JansAssetAddPage = () => {
const loading = useSelector((state) => state.assetReducer.loading)

return (
<GluuLoader blocking={loading}>
<Card style={applicationStyle.mainCard}>
<WebhookForm />
</Card>
</GluuLoader>
)
}

export default JansAssetAddPage
28 changes: 28 additions & 0 deletions admin-ui/plugins/admin/components/Assets/JansAssetEditPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useEffect } from 'react'
import { Card } from 'Components'
import applicationStyle from 'Routes/Apps/Gluu/styles/applicationstyle'
import WebhookForm from '../Webhook/WebhookForm'
import GluuLoader from 'Routes/Apps/Gluu/GluuLoader'
import { useDispatch, useSelector } from 'react-redux'
import { getAssets, getAssetResponse } from 'Plugins/admin/redux/features/assetSlice'
import { useParams } from 'react-router'

const JansAssetEditPage = () => {
const { id } = useParams()
const dispatch = useDispatch()
const { loading } = useSelector((state) => state.assetReducer)

useEffect(() => {

}, [])

return (
<GluuLoader blocking={loading}>
<Card style={applicationStyle.mainCard}>
<WebhookForm />
</Card>
</GluuLoader>
)
}

export default JansAssetEditPage
255 changes: 255 additions & 0 deletions admin-ui/plugins/admin/components/Assets/JansAssetListPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
import React, { useEffect, useState, useContext, useCallback } from 'react'
import MaterialTable from '@material-table/core'
import { DeleteOutlined } from '@mui/icons-material'
import { Paper, TablePagination } from '@mui/material'

import { Card, CardBody } from 'Components'
import GluuViewWrapper from 'Routes/Apps/Gluu/GluuViewWrapper'
import applicationStyle from 'Routes/Apps/Gluu/styles/applicationstyle'
import GluuAdvancedSearch from 'Routes/Apps/Gluu/GluuAdvancedSearch'
import {
hasPermission,
ASSETS_WRITE,
ASSETS_READ,
ASSETS_DELETE,
buildPayload
} from 'Utils/PermChecker'
import GluuCommitDialog from 'Routes/Apps/Gluu/GluuCommitDialog'
import GluuLoader from 'Routes/Apps/Gluu/GluuLoader'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import { ThemeContext } from 'Context/theme/themeContext'
import getThemeColor from 'Context/theme/config'
import { LIMIT_ID, PATTERN_ID } from 'Plugins/admin/common/Constants'
import SetTitle from 'Utils/SetTitle'
import { useNavigate } from 'react-router'
import { getAssets, deleteAsset, setSelectedAsset } from 'Plugins/admin/redux/features/assetSlice'

const JansAssetListPage = () => {
const dispatch = useDispatch()
const navigate = useNavigate()
const { t } = useTranslation()
const [pageNumber, setPageNumber] = useState(0)
const { totalItems, assets } = useSelector((state) => state.assetReducer)
const permissions = useSelector((state) => state.authReducer.permissions)
const loading = useSelector((state) => state.assetReducer.loading)
const PaperContainer = useCallback(
(props) => <Paper {...props} elevation={0} />,
[]
)

const theme = useContext(ThemeContext)
const themeColors = getThemeColor(theme.state.theme)
const bgThemeColor = { background: themeColors.background }
SetTitle(t('titles.assets'))

const [modal, setModal] = useState(false)
const [deleteData, setDeleteData] = useState(null)
const toggle = () => setModal(!modal)
const submitForm = (userMessage) => {
const userAction = {}
toggle()
buildPayload(userAction, userMessage, deleteData)
dispatch(deleteAsset({ action: userAction }))
}

const myActions = []
const options = {}

const [limit, setLimit] = useState(10)
const [pattern, setPattern] = useState(null)

useEffect(() => {
options['limit'] = 10
dispatch(getAssets({ action: options }))
}, [])

let memoLimit = limit
let memoPattern = pattern

function handleOptionsChange(event) {
if (event.target.name == 'limit') {
memoLimit = event.target.value
} else if (event.target.name == 'pattern') {
memoPattern = event.target.value
}
}

const onPageChangeClick = (page) => {
let startCount = page * limit
options['startIndex'] = parseInt(startCount)
options['limit'] = limit
options['pattern'] = pattern
setPageNumber(page)
dispatch(getAssets({ action: options }))
}
const onRowCountChangeClick = (count) => {
options['limit'] = count
options['pattern'] = pattern
setPageNumber(0)
setLimit(count)
dispatch(getAssets({ action: options }))
}

const PaginationWrapper = useCallback(
(props) => (
<TablePagination
count={totalItems}
page={pageNumber}
onPageChange={(prop, page) => {
onPageChangeClick(page)
}}
rowsPerPage={limit}
onRowsPerPageChange={(prop, count) =>
onRowCountChangeClick(count.props.value)
}
/>
),
[pageNumber, totalItems, onPageChangeClick, limit, onRowCountChangeClick]
)

const navigateToAddPage = useCallback(() => {
dispatch(setSelectedAsset({}))
navigate('/adm/asset/add')
}, [])

const navigateToEditPage = useCallback((data) => {
dispatch(setSelectedAsset(data))
navigate(`/adm/asset/edit/${data.inum}`)
}, [])

const DeleteOutlinedIcon = useCallback(() => <DeleteOutlined />, [])

const GluuSearch = useCallback(() => {
return (
<GluuAdvancedSearch
limitId={LIMIT_ID}
patternId={PATTERN_ID}
limit={limit}
pattern={pattern}
handler={handleOptionsChange}
showLimit={false}
/>
)
}, [limit, pattern, handleOptionsChange])

if (hasPermission(permissions, ASSETS_READ)) {
myActions.push({
icon: GluuSearch,
tooltip: `${t('messages.advanced_search')}`,
iconProps: { color: 'primary' },
isFreeAction: true,
onClick: () => { },
})
}

if (hasPermission(permissions, ASSETS_READ)) {
myActions.push({
icon: 'refresh',
tooltip: `${t('messages.refresh')}`,
iconProps: { color: 'primary' },
isFreeAction: true,
onClick: () => {
setLimit(memoLimit)
setPattern(memoPattern)
dispatch(getAssets({ action: { limit: memoLimit, pattern: memoPattern } }))
},
})
}

if (hasPermission(permissions, ASSETS_WRITE)) {
myActions.push({
icon: 'add',
tooltip: `${t('messages.add_asset')}`,
iconProps: { color: 'primary' },
isFreeAction: true,
onClick: () => navigateToAddPage(),
})
}

if (hasPermission(permissions, ASSETS_WRITE)) {
myActions.push((rowData) => ({
icon: 'edit',
iconProps: {
id: 'editScope' + rowData.inum,
},
onClick: (event, rowData) => navigateToEditPage(rowData),
disabled: !hasPermission(permissions, ASSETS_WRITE),
}))
}

if (hasPermission(permissions, ASSETS_DELETE)) {
myActions.push((rowData) => ({
icon: DeleteOutlinedIcon,
iconProps: {
color: 'secondary',
id: 'deleteClient' + rowData.inum,
},
onClick: (event, rowData) => {
setDeleteData(rowData)
toggle()
},
disabled: false,
}))
}

return (
<GluuLoader blocking={loading}>
<Card style={applicationStyle.mainCard}>
<CardBody>
<GluuViewWrapper canShow={hasPermission(permissions, ASSETS_READ)}>
<MaterialTable
components={{
Container: PaperContainer,
Pagination: PaginationWrapper,
}}
columns={[
{
title: `${t('fields.name')}`,
field: 'displayName',
},
{
title: `${t('fields.url')}`,
field: 'url',
width: '40%',
render: rowData => (
<div style={{ wordWrap: 'break-word', maxWidth: '420px' }}>
{rowData.url}
</div>
)
},
{ title: `${t('fields.http_method')}`, field: 'httpMethod' },
{ title: `${t('fields.enabled')}`, field: 'jansEnabled' }
]}
data={assets}
isLoading={loading}
title=''
actions={myActions}
options={{
search: false,
searchFieldAlignment: 'left',
selection: false,
pageSize: limit,
rowStyle: (rowData) => ({
backgroundColor: rowData.enabled ? '#33AE9A' : '#FFF',
}),
headerStyle: {
...applicationStyle.tableHeaderStyle,
...bgThemeColor,
},
actionsColumnIndex: -1,
}}
/>
</GluuViewWrapper>
</CardBody>
<GluuCommitDialog
handler={toggle}
modal={modal}
onAccept={submitForm}
/>
</Card>
</GluuLoader>
)
}

export default JansAssetListPage
Loading

0 comments on commit ccf7287

Please sign in to comment.