diff --git a/admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.js b/admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.js
index c36a61d51..037eb02fe 100644
--- a/admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.js
+++ b/admin-ui/app/routes/Apps/Gluu/GluuTypeAhead.js
@@ -24,6 +24,7 @@ function GluuTypeAhead({
required,
doc_category,
doc_entry,
+ forwardRef = null,
}) {
const { t } = useTranslation()
return (
@@ -37,6 +38,7 @@ function GluuTypeAhead({
{
diff --git a/admin-ui/plugins/admin/components/Mapping/MappingItem.js b/admin-ui/plugins/admin/components/Mapping/MappingItem.js
index 58dd56a5e..37a93170f 100644
--- a/admin-ui/plugins/admin/components/Mapping/MappingItem.js
+++ b/admin-ui/plugins/admin/components/Mapping/MappingItem.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react'
+import React, { useEffect, useState, useRef } from 'react'
import {
Row,
Badge,
@@ -6,43 +6,145 @@ import {
Button,
FormGroup,
Accordion,
+ Form,
} from '../../../../app/components'
+import { useDispatch, useSelector } from 'react-redux'
+import {
+ updateMapping,
+ addPermissionsToRole,
+ updatePermissionsToServer,
+ updatePermissionsServerResponse,
+} from '../../redux/actions/MappingActions'
+import GluuTypeAhead from '../../../../app/routes/Apps/Gluu/GluuTypeAhead'
+import applicationStyle from '../../../../app/routes/Apps/Gluu/styles/applicationstyle'
+
+import { Formik } from 'formik'
+
+function MappingItem({ candidate }) {
+ const dispatch = useDispatch()
+ const autocompleteRef = useRef(null)
+ const permissions = useSelector((state) => state.apiPermissionReducer.items)
+ const [searchablePermissions, setSearchAblePermissions] = useState([])
+ const [serverPermissions, setServerPermissions] = useState(null)
+ const getPermissionsForSearch = () => {
+ const selectedPermissions = candidate.permissions
+ let filteredArr = []
+ for (let i in permissions) {
+ if (!selectedPermissions.includes(permissions[i].permission)) {
+ filteredArr.push(permissions[i].permission)
+ }
+ }
+ setSearchAblePermissions(filteredArr)
+ }
-function MappingItem({ candidate, key }) {
- const [item, setItem] = useState(candidate || {})
- function doRemove(perm) {
- const candidate = item
- candidate['permissions'] = ['one', 'two']
- setItem(candidate)
+ const revertLocalChanges = () => {
+ dispatch(updatePermissionsServerResponse(JSON.parse(serverPermissions)))
}
+
+ const setServerPermissionsToLocalState = () => {
+ setServerPermissions(JSON.stringify(candidate))
+ }
+
+ useEffect(() => {
+ setServerPermissionsToLocalState()
+ }, [false])
+
+ useEffect(() => {
+ getPermissionsForSearch()
+ }, [permissions, candidate?.permissions?.length])
+
+ const doRemove = (id, role) => {
+ dispatch(
+ updateMapping({
+ id,
+ role,
+ }),
+ )
+ }
+
+ const initialValues = {}
+
+ const handleAddPermission = (values, { resetForm }) => {
+ if (values?.mappingAddPermissions?.length) {
+ dispatch(
+ addPermissionsToRole({
+ data: values?.mappingAddPermissions,
+ userRole: candidate.role,
+ }),
+ )
+ }
+ resetForm()
+ autocompleteRef.current.clear()
+ }
+
return (
-
+
- {item.role}
+ {candidate.role}
- {item.permissions.length}
+ {candidate.permissions.length}
- {item.permissions.map((permission, id) => (
+
+
+ {(formik) => (
+ <>
+
+ >
+ )}
+
+ {candidate.permissions.map((permission, id) => (
{permission}
))}
+ {/* Bottom Buttons */}
+
+
+
+
+
+
+
+
+
+ {/* Bottom Buttons */}
diff --git a/admin-ui/plugins/admin/components/Mapping/MappingPage.js b/admin-ui/plugins/admin/components/Mapping/MappingPage.js
index 75a8f506e..3dbe431d4 100644
--- a/admin-ui/plugins/admin/components/Mapping/MappingPage.js
+++ b/admin-ui/plugins/admin/components/Mapping/MappingPage.js
@@ -12,8 +12,10 @@ import {
} from '../../../../app/components'
import GluuViewWrapper from '../../../../app/routes/Apps/Gluu/GluuViewWrapper'
import GluuRibbon from '../../../../app/routes/Apps/Gluu/GluuRibbon'
+import GluuLoader from '../../../../app/routes/Apps/Gluu/GluuLoader'
import { getMapping } from '../../redux/actions/MappingActions'
import { getRoles } from '../../redux/actions/ApiRoleActions'
+import { getPermissions } from '../../redux/actions/ApiPermissionActions'
import MappingItem from './MappingItem'
import {
hasPermission,
@@ -21,15 +23,29 @@ import {
ROLE_READ,
} from '../../../../app/utils/PermChecker'
-function MappingPage({ mapping, apiRoles, permissions, dispatch }) {
+function MappingPage({
+ mapping,
+ apiRoles,
+ permissions,
+ permissionLoading,
+ loading,
+ dispatch,
+}) {
const { t } = useTranslation()
const [modal, setModal] = useState(false)
const toggle = () => setModal(!modal)
const options = []
const userAction = {}
+
+ function doFetchPermissionsList() {
+ buildPayload(userAction, 'PERMISSIONS', options)
+ dispatch(getPermissions(userAction))
+ }
+
useEffect(() => {
doFetchList()
doFetchRoles()
+ doFetchPermissionsList()
}, [])
function onAddConfirmed(mappingData) {
@@ -51,46 +67,51 @@ function MappingPage({ mapping, apiRoles, permissions, dispatch }) {
toggle()
}
return (
-
-
-
-
-
-
-
-
-
-
-
-
- {mapping.map((candidate, idx) => (
-
- ))}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {mapping.map((candidate, idx) => (
+
+ ))}
+
+
+
+
+
+
)
}
const mapStateToProps = (state) => {
return {
mapping: state.mappingReducer.items,
+ loading: state.mappingReducer.loading,
apiRoles: state.apiRoleReducer.items,
permissions: state.authReducer.permissions,
+ permissionLoading: state.apiPermissionReducer.loading,
}
}
diff --git a/admin-ui/plugins/admin/redux/actions/MappingActions.js b/admin-ui/plugins/admin/redux/actions/MappingActions.js
index d902e2e44..788eb1dfa 100644
--- a/admin-ui/plugins/admin/redux/actions/MappingActions.js
+++ b/admin-ui/plugins/admin/redux/actions/MappingActions.js
@@ -1,4 +1,12 @@
-import { GET_MAPPING, GET_MAPPING_RESPONSE } from './types'
+import {
+ GET_MAPPING,
+ GET_MAPPING_RESPONSE,
+ UPDATE_MAPPING,
+ ADD_PERMISSIONS_TO_ROLE,
+ UPDATE_PERMISSIONS_TO_SERVER,
+ UPDATE_PERMISSIONS_LOADING,
+ UPDATE_PERMISSIONS_SERVER_RESPONSE,
+} from './types'
export const getMapping = (action) => ({
type: GET_MAPPING,
@@ -9,3 +17,27 @@ export const getMappingResponse = (data) => ({
type: GET_MAPPING_RESPONSE,
payload: { data },
})
+
+export const updateMapping = (data) => ({
+ type: UPDATE_MAPPING,
+ payload: { data },
+})
+
+export const updatePermissionsLoading = (data) => ({
+ type: UPDATE_PERMISSIONS_LOADING,
+ payload: { data },
+})
+
+export const updatePermissionsServerResponse = (data) => ({
+ type: UPDATE_PERMISSIONS_SERVER_RESPONSE,
+ payload: { data },
+})
+export const addPermissionsToRole = (data) => ({
+ type: ADD_PERMISSIONS_TO_ROLE,
+ payload: { data },
+})
+
+export const updatePermissionsToServer = (data) => ({
+ type: UPDATE_PERMISSIONS_TO_SERVER,
+ payload: { data },
+})
diff --git a/admin-ui/plugins/admin/redux/actions/types.js b/admin-ui/plugins/admin/redux/actions/types.js
index ff0a1836a..27a89893b 100644
--- a/admin-ui/plugins/admin/redux/actions/types.js
+++ b/admin-ui/plugins/admin/redux/actions/types.js
@@ -46,7 +46,12 @@ export const SET_PERMISSION_ITEM = 'SET_PERMISSION_ITEM'
//ROLE-PERMISSION Mapping
export const GET_MAPPING = 'GET_MAPPING'
export const GET_MAPPING_RESPONSE = 'GET_MAPPING_RESPONSE'
-
+export const UPDATE_MAPPING = 'UPDATE_MAPPING'
+export const ADD_PERMISSIONS_TO_ROLE = 'ADD_PERMISSIONS_TO_ROLE'
+export const UPDATE_PERMISSIONS_TO_SERVER = 'UPDATE_PERMISSIONS_TO_SERVER'
+export const UPDATE_PERMISSIONS_SERVER_RESPONSE =
+ 'UPDATE_PERMISSIONS_SERVER_RESPONSE'
+export const UPDATE_PERMISSIONS_LOADING = 'UPDATE_PERMISSIONS_LOADING'
//License Details
export const GET_LICENSE_DETAILS = 'GET_LICENSE_DETAILS'
diff --git a/admin-ui/plugins/admin/redux/api/MappingApi.js b/admin-ui/plugins/admin/redux/api/MappingApi.js
index a36ac8b94..d43fb1aeb 100644
--- a/admin-ui/plugins/admin/redux/api/MappingApi.js
+++ b/admin-ui/plugins/admin/redux/api/MappingApi.js
@@ -10,6 +10,16 @@ export default class MappingApi {
})
}
+ updateMapping = (data) => {
+ const options = {}
+ options['rolePermissionMapping'] = data
+ return new Promise((resolve, reject) => {
+ this.api.mapPermissionsToRole(options, (error, options) => {
+ this.handleResponse(error, reject, resolve, data)
+ })
+ })
+ }
+
handleResponse(error, reject, resolve, data) {
if (error) {
reject(error)
diff --git a/admin-ui/plugins/admin/redux/reducers/MappingReducer.js b/admin-ui/plugins/admin/redux/reducers/MappingReducer.js
index a500e282a..f468f6878 100644
--- a/admin-ui/plugins/admin/redux/reducers/MappingReducer.js
+++ b/admin-ui/plugins/admin/redux/reducers/MappingReducer.js
@@ -1,8 +1,17 @@
-import { GET_MAPPING, GET_MAPPING_RESPONSE, RESET } from '../actions/types'
+import {
+ GET_MAPPING,
+ GET_MAPPING_RESPONSE,
+ UPDATE_MAPPING,
+ ADD_PERMISSIONS_TO_ROLE,
+ UPDATE_PERMISSIONS_LOADING,
+ RESET,
+ UPDATE_PERMISSIONS_SERVER_RESPONSE,
+} from '../actions/types'
import reducerRegistry from '../../../../app/redux/reducers/ReducerRegistry'
const INIT_STATE = {
items: [],
+ serverItems: [],
loading: false,
}
const reducerName = 'mappingReducer'
@@ -10,7 +19,6 @@ const reducerName = 'mappingReducer'
export default function mappingReducer(state = INIT_STATE, action) {
switch (action.type) {
case GET_MAPPING:
- console.log("==================>")
return handleLoading()
case GET_MAPPING_RESPONSE:
if (action.payload.data) {
@@ -18,7 +26,46 @@ export default function mappingReducer(state = INIT_STATE, action) {
} else {
return handleDefault()
}
-
+ case ADD_PERMISSIONS_TO_ROLE:
+ const { data, userRole } = action.payload.data
+ let roleIndex = state.items.findIndex(
+ (element) => element.role == userRole,
+ )
+ let existingPermissions = state.items[roleIndex].permissions
+ let newArr = existingPermissions.concat(data)
+ let addedPermissions = state.items
+ addedPermissions[roleIndex].permissions = newArr
+ return {
+ ...state,
+ items: [...addedPermissions],
+ }
+ case UPDATE_PERMISSIONS_LOADING:
+ return {
+ ...state,
+ loading: action.payload.data,
+ }
+ case UPDATE_PERMISSIONS_SERVER_RESPONSE:
+ let indexToUpdatePermissions = state.items.findIndex(
+ (element) => element.role == action.payload?.data?.role,
+ )
+ let changedData = state.items
+ changedData[indexToUpdatePermissions] = action.payload.data
+ return {
+ ...state,
+ items: [...changedData],
+ loading: false,
+ }
+ case UPDATE_MAPPING:
+ const { id, role } = action.payload.data
+ let index = state.items.findIndex((element) => element.role == role)
+ let permissions = state.items[index].permissions
+ permissions.splice(id, 1)
+ let changedPermissions = state.items
+ changedPermissions[index].permissions = permissions
+ return {
+ ...state,
+ items: [...changedPermissions],
+ }
case RESET:
return {
...state,
diff --git a/admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js b/admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js
index 4a455042e..1b6439e05 100644
--- a/admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js
+++ b/admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js
@@ -5,7 +5,7 @@ import PermissionApi from '../api/PermissionApi'
import { getClient } from '../../../../app/redux/api/base'
import { postUserAction } from '../../../../app/redux/api/backend-api'
import {
- getPermissionsResponse,
+ getPermissionResponse,
addPermissionResponse,
editPermissionResponse,
deletePermissionResponse,
@@ -46,10 +46,10 @@ export function* getPermissions({ payload }) {
addAdditionalData(audit, FETCH, API_PERMISSION, payload)
const permApi = yield* newFunction()
const data = yield call(permApi.getPermissions)
- yield put(getPermissionsResponse(data))
+ yield put(getPermissionResponse(data))
yield call(postUserAction, audit)
} catch (e) {
- yield put(getPermissionsResponse(null))
+ yield put(getPermissionResponse(null))
if (isFourZeroOneError(e)) {
const jwt = yield select((state) => state.authReducer.userinfo_jwt)
yield put(getAPIAccessToken(jwt))
diff --git a/admin-ui/plugins/admin/redux/sagas/MappingSaga.js b/admin-ui/plugins/admin/redux/sagas/MappingSaga.js
index 5d984072a..1fd26175c 100644
--- a/admin-ui/plugins/admin/redux/sagas/MappingSaga.js
+++ b/admin-ui/plugins/admin/redux/sagas/MappingSaga.js
@@ -1,5 +1,17 @@
-import { call, all, put, fork, takeLatest, select } from 'redux-saga/effects'
-import { getMappingResponse } from '../actions/MappingActions'
+import {
+ call,
+ all,
+ put,
+ fork,
+ takeLatest,
+ select,
+ takeEvery,
+} from 'redux-saga/effects'
+import {
+ getMappingResponse,
+ updatePermissionsServerResponse,
+ updatePermissionsLoading,
+} from '../actions/MappingActions'
import { API_MAPPING } from '../audit/Resources'
import { FETCH } from '../../../../app/audit/UserActionType'
import { getAPIAccessToken } from '../../../../app/redux/actions/AuthActions'
@@ -7,7 +19,7 @@ import {
isFourZeroOneError,
addAdditionalData,
} from '../../../../app/utils/TokenController'
-import { GET_MAPPING } from '../actions/types'
+import { GET_MAPPING, UPDATE_PERMISSIONS_TO_SERVER } from '../actions/types'
import MappingApi from '../api/MappingApi'
import { getClient } from '../../../../app/redux/api/base'
import { postUserAction } from '../../../../app/redux/api/backend-api'
@@ -40,8 +52,25 @@ export function* fetchMapping({ payload }) {
}
}
+export function* updateMapping({ payload }) {
+ yield put(updatePermissionsLoading(true))
+ try {
+ const mappingApi = yield* newFunction()
+ const data = yield call(mappingApi.updateMapping, payload.data)
+ yield put(updatePermissionsServerResponse(data))
+ } catch (e) {
+ yield put(updatePermissionsLoading(false))
+ yield put(getMappingResponse(null))
+ if (isFourZeroOneError(e)) {
+ const jwt = yield select((state) => state.authReducer.userinfo_jwt)
+ yield put(getAPIAccessToken(jwt))
+ }
+ }
+}
+
export function* watchGetMapping() {
yield takeLatest(GET_MAPPING, fetchMapping)
+ yield takeEvery(UPDATE_PERMISSIONS_TO_SERVER, updateMapping)
}
export default function* rootSaga() {