mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
parent
b59dc6b355
commit
b81b3e3d24
@ -18,8 +18,8 @@ import { useDispatch } from 'react-redux'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { useAuth, useAuthApi } from 'client/features/Auth'
|
||||
import { authApi } from 'client/features/AuthApi'
|
||||
import { oneApi } from 'client/features/OneApi'
|
||||
import authApi from 'client/features/OneApi/auth'
|
||||
import groupApi from 'client/features/OneApi/group'
|
||||
import FullscreenProgress from 'client/components/LoadingScreen'
|
||||
import { findStorageData, findExternalToken, storage } from 'client/utils'
|
||||
@ -47,7 +47,6 @@ const AuthLayout = ({ subscriptions = [], children }) => {
|
||||
|
||||
return () => {
|
||||
authSubscription.unsubscribe()
|
||||
dispatch(authApi.util.resetApiState())
|
||||
dispatch(oneApi.util.resetApiState())
|
||||
}
|
||||
}, [dispatch, jwt])
|
||||
|
@ -16,11 +16,11 @@
|
||||
import { useMemo, memo, JSXElementConstructor } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { Button, Stack, CircularProgress } from '@mui/material'
|
||||
import { Group as GroupIcon, VerifiedBadge as SelectIcon } from 'iconoir-react'
|
||||
import { Stack, Button, Typography, CircularProgress } from '@mui/material'
|
||||
import { Group as GroupIcon, VerifiedUser, Check } from 'iconoir-react'
|
||||
|
||||
import { useAuth } from 'client/features/Auth'
|
||||
import { useChangeAuthGroupMutation } from 'client/features/AuthApi'
|
||||
import { useChangeAuthGroupMutation } from 'client/features/OneApi/auth'
|
||||
import Search from 'client/components/Search'
|
||||
import HeaderPopover from 'client/components/Header/Popover'
|
||||
import { Tr, Translate } from 'client/components/HOC'
|
||||
@ -33,25 +33,32 @@ const ButtonGroup = memo(
|
||||
const { user, filterPool } = useAuth()
|
||||
const { ID, NAME } = group
|
||||
|
||||
const isPrimaryGroup = user?.GID === ID
|
||||
|
||||
const isSelected =
|
||||
(filterPool === ALL_RESOURCES && ALL_RESOURCES === ID) ||
|
||||
(filterPool === PRIMARY_GROUP_RESOURCES && user?.GID === ID)
|
||||
(filterPool === PRIMARY_GROUP_RESOURCES && isPrimaryGroup)
|
||||
|
||||
return (
|
||||
<Button
|
||||
fullWidth
|
||||
disabled={disabled}
|
||||
color="debug"
|
||||
variant="outlined"
|
||||
variant={isSelected ? 'contained' : 'outlined'}
|
||||
color="secondary"
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
color: (theme) => theme.palette.text.primary,
|
||||
boxShadow: 'none !important',
|
||||
justifyContent: 'start',
|
||||
'& svg:first-of-type': { my: 0, mx: 2 },
|
||||
}}
|
||||
>
|
||||
{NAME}
|
||||
{isSelected && <SelectIcon />}
|
||||
<Stack component="span" direction="row" alignItems="center" gap=".5em">
|
||||
{isSelected && <Check style={{ margin: 0 }} />}
|
||||
<Typography component="span" noWrap variant="subtitle2">
|
||||
{NAME}
|
||||
</Typography>
|
||||
{isPrimaryGroup && <VerifiedUser />}
|
||||
</Stack>
|
||||
</Button>
|
||||
)
|
||||
},
|
||||
@ -88,7 +95,7 @@ const Group = () => {
|
||||
headerTitle={
|
||||
<Stack direction="row" alignItems="center" gap="1em" component="span">
|
||||
<Translate word={T.SwitchGroup} />
|
||||
{isLoading && <CircularProgress size={20} />}
|
||||
{isLoading && <CircularProgress size={20} color="secondary" />}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
|
@ -18,7 +18,7 @@ import { useCallback, useMemo } from 'react'
|
||||
import { useDispatch, useSelector, shallowEqual } from 'react-redux'
|
||||
|
||||
import { name as generalSlice } from 'client/features/General/slice'
|
||||
import { name as authSlice, actions } from 'client/features/Auth/slice'
|
||||
import { name as authSlice, actions, logout } from 'client/features/Auth/slice'
|
||||
import groupApi from 'client/features/OneApi/group'
|
||||
import systemApi from 'client/features/OneApi/system'
|
||||
import { ResourceView } from 'client/apps/sunstone/routes'
|
||||
@ -91,10 +91,10 @@ export const useAuthApi = () => {
|
||||
|
||||
return {
|
||||
stopFirstRender: () => dispatch(actions.stopFirstRender()),
|
||||
logout: () => dispatch(actions.logout()),
|
||||
logout: () => dispatch(logout()),
|
||||
changeView: (view) => dispatch(actions.changeView(view)),
|
||||
changeJwt: (jwt) => dispatch(actions.changeJwt(jwt)),
|
||||
changeAuthUser: (user) => dispatch(actions.changeAuthUser({ user })),
|
||||
changeAuthUser: (user) => dispatch(actions.changeAuthUser(user)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,10 +31,13 @@ const slice = createSlice({
|
||||
name: 'auth',
|
||||
initialState: { ...initial(), firstRender: true },
|
||||
reducers: {
|
||||
changeAuthUser: (state, { payload }) => ({
|
||||
...state,
|
||||
...payload,
|
||||
}),
|
||||
changeAuthUser: (state, { payload: { isLoginInProgress, ...user } }) => {
|
||||
state.user = { ...state.user, ...user }
|
||||
|
||||
if (isLoginInProgress !== undefined) {
|
||||
state.isLoginInProgress = isLoginInProgress
|
||||
}
|
||||
},
|
||||
changeJwt: (state, { payload }) => {
|
||||
state.jwt = payload
|
||||
},
|
||||
@ -58,7 +61,4 @@ const slice = createSlice({
|
||||
},
|
||||
})
|
||||
|
||||
export const { name, reducer } = slice
|
||||
|
||||
const actions = { ...slice.actions, logout }
|
||||
export { actions }
|
||||
export const { name, reducer, actions } = slice
|
||||
|
@ -15,7 +15,7 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { actions as authActions } from 'client/features/Auth/slice'
|
||||
import { logout } from 'client/features/Auth/slice'
|
||||
import * as actions from 'client/features/General/actions'
|
||||
import { generateKey } from 'client/utils'
|
||||
import { APPS_IN_BETA, APPS_WITH_SWITCHER } from 'client/constants'
|
||||
@ -30,13 +30,13 @@ const initial = {
|
||||
notifications: [],
|
||||
}
|
||||
|
||||
const { name, reducer } = createSlice({
|
||||
const slice = createSlice({
|
||||
name: 'general',
|
||||
initialState: initial,
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
/* LOGOUT ACTION */
|
||||
.addCase(authActions.logout, (state) => ({
|
||||
.addCase(logout, (state) => ({
|
||||
...initial,
|
||||
// persistent app state
|
||||
appTitle: state.appTitle,
|
||||
@ -127,4 +127,4 @@ const { name, reducer } = createSlice({
|
||||
},
|
||||
})
|
||||
|
||||
export { name, reducer }
|
||||
export const { name, reducer } = slice
|
||||
|
@ -16,7 +16,7 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { Status } from 'guacamole-common-js'
|
||||
|
||||
import { actions as authActions } from 'client/features/Auth/slice'
|
||||
import { logout } from 'client/features/Auth/slice'
|
||||
import { GUACAMOLE_STATES_STR } from 'client/constants'
|
||||
|
||||
const {
|
||||
@ -119,7 +119,8 @@ const slice = createSlice({
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(authActions.logout, () => ({}))
|
||||
/* LOGOUT ACTION */
|
||||
builder.addCase(logout, () => ({}))
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -13,37 +13,20 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { createApi } from '@reduxjs/toolkit/query/react'
|
||||
|
||||
import { Actions, Commands } from 'server/routes/api/auth/routes'
|
||||
|
||||
import { actions as authActions } from 'client/features/Auth/slice'
|
||||
import { dismissSnackbar } from 'client/features/General/actions'
|
||||
import { actions } from 'client/features/Auth/slice'
|
||||
import { oneApi, ONE_RESOURCES_POOL } from 'client/features/OneApi'
|
||||
import userApi from 'client/features/OneApi/user'
|
||||
|
||||
import http from 'client/utils/rest'
|
||||
import { requestConfig, storage } from 'client/utils'
|
||||
import { storage } from 'client/utils'
|
||||
import { JWT_NAME, FILTER_POOL, ONEADMIN_ID } from 'client/constants'
|
||||
|
||||
const { GROUP_POOL, ...restOfPool } = ONE_RESOURCES_POOL
|
||||
const { ALL_RESOURCES, PRIMARY_GROUP_RESOURCES } = FILTER_POOL
|
||||
|
||||
const authApi = createApi({
|
||||
reducerPath: 'authApi',
|
||||
baseQuery: async ({ params, command, needState }, { getState, signal }) => {
|
||||
try {
|
||||
const config = requestConfig(params, command)
|
||||
const response = await http.request({ ...config, signal })
|
||||
const state = needState ? getState() : {}
|
||||
|
||||
return { data: response.data ?? {}, meta: { state } }
|
||||
} catch (axiosError) {
|
||||
const { message, data = {}, status, statusText } = axiosError
|
||||
const { message: messageFromServer, data: errorFromOned } = data
|
||||
|
||||
const error = message ?? errorFromOned ?? messageFromServer ?? statusText
|
||||
|
||||
return { error: { status: status, data: error } }
|
||||
}
|
||||
},
|
||||
const authApi = oneApi.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
getAuthUser: builder.query({
|
||||
/**
|
||||
@ -55,7 +38,7 @@ const authApi = createApi({
|
||||
async onQueryStarted(_, { queryFulfilled, dispatch }) {
|
||||
try {
|
||||
const { data: user } = await queryFulfilled
|
||||
dispatch(actions.changeAuthUser({ user }))
|
||||
dispatch(authActions.changeAuthUser(user))
|
||||
} catch {}
|
||||
},
|
||||
}),
|
||||
@ -91,13 +74,15 @@ const authApi = createApi({
|
||||
async onQueryStarted(_, { queryFulfilled, dispatch }) {
|
||||
try {
|
||||
const { data: queryData } = await queryFulfilled
|
||||
const { jwt, ...user } = queryData
|
||||
|
||||
if (queryData?.jwt) {
|
||||
storage(JWT_NAME, queryData?.jwt)
|
||||
if (jwt) {
|
||||
storage(JWT_NAME, jwt)
|
||||
dispatch(dismissSnackbar({ dismissAll: true }))
|
||||
}
|
||||
|
||||
dispatch(actions.changeAuthUser(queryData))
|
||||
dispatch(authActions.changeJwt(queryData))
|
||||
dispatch(authActions.changeAuthUser(user))
|
||||
} catch {}
|
||||
},
|
||||
}),
|
||||
@ -111,35 +96,39 @@ const authApi = createApi({
|
||||
queryFn: async ({ group } = {}, { getState, dispatch }) => {
|
||||
try {
|
||||
if (group === ALL_RESOURCES) {
|
||||
dispatch(actions.changeFilterPool(ALL_RESOURCES))
|
||||
dispatch(authActions.changeFilterPool(ALL_RESOURCES))
|
||||
|
||||
return { data: '' }
|
||||
}
|
||||
|
||||
const authUser = getState().auth.user
|
||||
const queryData = { id: authUser.ID, group: group }
|
||||
const queryData = { id: authUser.ID, group }
|
||||
|
||||
const response = await dispatch(
|
||||
const newGroup = await dispatch(
|
||||
userApi.endpoints.changeGroup.initiate(queryData)
|
||||
).unwrap()
|
||||
|
||||
dispatch(actions.changeFilterPool(PRIMARY_GROUP_RESOURCES))
|
||||
dispatch(authActions.changeFilterPool(PRIMARY_GROUP_RESOURCES))
|
||||
dispatch(authActions.changeAuthUser({ GID: `${group}` }))
|
||||
|
||||
return { data: response }
|
||||
return { data: newGroup }
|
||||
} catch (error) {
|
||||
return { error }
|
||||
}
|
||||
},
|
||||
invalidatesTags: [...Object.values(restOfPool)],
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const {
|
||||
// Queries
|
||||
useGetAuthUserQuery,
|
||||
useLazyGetAuthUserQuery,
|
||||
|
||||
// Mutations
|
||||
useLoginMutation,
|
||||
useChangeAuthGroupMutation,
|
||||
} = authApi
|
||||
|
||||
export { authApi }
|
||||
export default authApi
|
@ -78,12 +78,21 @@ const PROVISION_RESOURCES = {
|
||||
|
||||
const oneApi = createApi({
|
||||
reducerPath: 'oneApi',
|
||||
baseQuery: async ({ params, command }, { dispatch, signal }) => {
|
||||
baseQuery: async (
|
||||
{ params = {}, command, needStateInMeta = false },
|
||||
{ getState, dispatch, signal }
|
||||
) => {
|
||||
try {
|
||||
// set filter flag if filter is present in command params
|
||||
if (command?.params?.filter) {
|
||||
params.filter = getState().auth?.filterPool
|
||||
}
|
||||
|
||||
const config = requestConfig(params, command)
|
||||
const response = await http.request({ ...config, signal })
|
||||
const state = needStateInMeta ? getState() : {}
|
||||
|
||||
return { data: response.data ?? {} }
|
||||
return { data: response.data ?? {}, meta: { state } }
|
||||
} catch (axiosError) {
|
||||
const { message, data = {}, status, statusText } = axiosError
|
||||
const { message: messageFromServer, data: errorFromOned } = data
|
||||
|
@ -14,12 +14,13 @@
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { Actions, Commands } from 'server/utils/constants/commands/user'
|
||||
|
||||
import {
|
||||
oneApi,
|
||||
ONE_RESOURCES,
|
||||
ONE_RESOURCES_POOL,
|
||||
} from 'client/features/OneApi'
|
||||
import { authApi } from 'client/features/AuthApi'
|
||||
import authApi from 'client/features/OneApi/auth'
|
||||
import { User } from 'client/constants'
|
||||
|
||||
const { USER } = ONE_RESOURCES
|
||||
|
@ -21,7 +21,6 @@ import { isDevelopment } from 'client/utils'
|
||||
import * as Auth from 'client/features/Auth/slice'
|
||||
import * as General from 'client/features/General/slice'
|
||||
import * as Guacamole from 'client/features/Guacamole/slice'
|
||||
import { authApi } from 'client/features/AuthApi'
|
||||
import { oneApi } from 'client/features/OneApi'
|
||||
import { unauthenticatedMiddleware } from 'client/features/middleware'
|
||||
|
||||
@ -37,7 +36,6 @@ export const createStore = ({ initState = {}, extraMiddleware = [] }) => {
|
||||
[Auth.name]: Auth.reducer,
|
||||
[General.name]: General.reducer,
|
||||
[Guacamole.name]: Guacamole.reducer,
|
||||
[authApi.reducerPath]: authApi.reducer,
|
||||
[oneApi.reducerPath]: oneApi.reducer,
|
||||
},
|
||||
devTools: isDevelopment(),
|
||||
@ -47,7 +45,6 @@ export const createStore = ({ initState = {}, extraMiddleware = [] }) => {
|
||||
}).concat([
|
||||
...extraMiddleware,
|
||||
unauthenticatedMiddleware,
|
||||
authApi.middleware,
|
||||
oneApi.middleware,
|
||||
]),
|
||||
preloadedState: initState,
|
||||
|
@ -16,13 +16,11 @@
|
||||
const { combineReducers } = require('@reduxjs/toolkit')
|
||||
const Auth = require('client/features/Auth/slice')
|
||||
const General = require('client/features/General/slice')
|
||||
const { authApi } = require('client/features/AuthApi')
|
||||
const { oneApi } = require('client/features/OneApi')
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
general: General.reducer,
|
||||
auth: Auth.reducer,
|
||||
[authApi.reducerPath]: authApi.reducer,
|
||||
[oneApi.reducerPath]: oneApi.reducer,
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user