diff --git a/src/fireedge/src/client/apps/provision/_app.js b/src/fireedge/src/client/apps/provision/_app.js
index bd5f20e550..e41f8129cb 100644
--- a/src/fireedge/src/client/apps/provision/_app.js
+++ b/src/fireedge/src/client/apps/provision/_app.js
@@ -20,14 +20,14 @@ import { ENDPOINTS, PATH } from 'client/apps/provision/routes'
import { ENDPOINTS as DEV_ENDPOINTS } from 'client/router/dev'
import { useGeneral, useGeneralApi } from 'client/features/General'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuth } from 'client/features/Auth'
import provisionApi from 'client/features/OneApi/provision'
import providerApi from 'client/features/OneApi/provider'
import { useSocket } from 'client/hooks'
import Sidebar from 'client/components/Sidebar'
import Notifier from 'client/components/Notifier'
-import LoadingScreen from 'client/components/LoadingScreen'
+import { AuthLayout } from 'client/components/HOC'
import { isDevelopment } from 'client/utils'
import { _APPS } from 'client/constants'
@@ -42,27 +42,14 @@ const MESSAGE_PROVISION_SUCCESS_CREATED = 'Provision successfully created'
*/
const ProvisionApp = () => {
const { getProvisionSocket } = useSocket()
- const { isLogged, jwt, firstRender } = useAuth()
- const { getAuthUser, logout } = useAuthApi()
+ const { isLogged, jwt } = useAuth()
- const { appTitle, zone } = useGeneral()
- const { changeAppTitle, enqueueSuccess } = useGeneralApi()
-
- const queryProps = [undefined, { skip: !jwt }]
- provisionApi.endpoints.getProvisionTemplates.useQuery(...queryProps)
- providerApi.endpoints.getProviderConfig.useQuery(...queryProps)
+ const { zone } = useGeneral()
+ const { enqueueSuccess, changeAppTitle } = useGeneralApi()
useEffect(() => {
- ;(async () => {
- appTitle !== APP_NAME && changeAppTitle(APP_NAME)
-
- try {
- jwt && getAuthUser()
- } catch {
- logout()
- }
- })()
- }, [jwt])
+ changeAppTitle(APP_NAME)
+ }, [])
useEffect(() => {
if (!jwt || !zone) return
@@ -86,12 +73,13 @@ const ProvisionApp = () => {
[]
)
- if (jwt && firstRender) {
- return
- }
-
return (
- <>
+
{isLogged && (
<>
@@ -99,7 +87,7 @@ const ProvisionApp = () => {
>
)}
- >
+
)
}
diff --git a/src/fireedge/src/client/apps/sunstone/_app.js b/src/fireedge/src/client/apps/sunstone/_app.js
index 6bea61cc29..a20376f067 100644
--- a/src/fireedge/src/client/apps/sunstone/_app.js
+++ b/src/fireedge/src/client/apps/sunstone/_app.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { useEffect, useMemo, JSXElementConstructor } from 'react'
+import { useEffect, useMemo, ReactElement } from 'react'
import Router from 'client/router'
import {
@@ -24,13 +24,12 @@ import {
import { ENDPOINTS as ONE_ENDPOINTS } from 'client/apps/sunstone/routesOne'
import { ENDPOINTS as DEV_ENDPOINTS } from 'client/router/dev'
-import { useGeneral, useGeneralApi } from 'client/features/General'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuth, useViews } from 'client/features/Auth'
+import { useGeneralApi } from 'client/features/General'
import systemApi from 'client/features/OneApi/system'
-
import Sidebar from 'client/components/Sidebar'
import Notifier from 'client/components/Notifier'
-import LoadingScreen from 'client/components/LoadingScreen'
+import { AuthLayout } from 'client/components/HOC'
import { isDevelopment } from 'client/utils'
import { _APPS } from 'client/constants'
@@ -39,47 +38,38 @@ export const APP_NAME = _APPS.sunstone.name
/**
* Sunstone App component.
*
- * @returns {JSXElementConstructor} App rendered.
+ * @returns {ReactElement} App rendered.
*/
const SunstoneApp = () => {
- const { isLogged, jwt, firstRender, view } = useAuth()
- const { getAuthUser, logout } = useAuthApi()
-
- const { appTitle } = useGeneral()
const { changeAppTitle } = useGeneralApi()
-
- const queryProps = [undefined, { skip: !jwt }]
- systemApi.endpoints.getOneConfig.useQuery(...queryProps)
- systemApi.endpoints.getSunstoneConfig.useQuery(...queryProps)
- const views = systemApi.endpoints.getSunstoneViews.useQuery(...queryProps)
+ const { isLogged } = useAuth()
+ const { views, view } = useViews()
useEffect(() => {
- ;(async () => {
- appTitle !== APP_NAME && changeAppTitle(APP_NAME)
+ changeAppTitle(APP_NAME)
+ }, [])
- try {
- jwt && getAuthUser()
- } catch {
- logout()
- }
- })()
- }, [jwt])
-
- const endpoints = useMemo(
- () => [
+ const endpoints = useMemo(() => {
+ const fixedEndpoints = [
...ENDPOINTS,
- ...(view ? getEndpointsByView(views?.data?.[view], ONE_ENDPOINTS) : []),
...(isDevelopment() ? DEV_ENDPOINTS : []),
- ],
- [view]
- )
+ ]
- if (jwt && firstRender) {
- return
- }
+ if (!view) return fixedEndpoints
+
+ const viewEndpoints = getEndpointsByView(views?.[view], ONE_ENDPOINTS)
+
+ return fixedEndpoints.concat(viewEndpoints)
+ }, [view])
return (
- <>
+
{isLogged && (
<>
@@ -87,7 +77,7 @@ const SunstoneApp = () => {
>
)}
- >
+
)
}
diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js
index 6deda3e3b1..3c1e80e385 100644
--- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js
+++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/index.js
@@ -15,12 +15,12 @@
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
// eslint-disable-next-line no-unused-vars
-import { useMemo, JSXElementConstructor } from 'react'
+import { useMemo, ReactElement } from 'react'
import PropTypes from 'prop-types'
// eslint-disable-next-line no-unused-vars
import { useFormContext, FieldErrors } from 'react-hook-form'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { Translate } from 'client/components/HOC'
import Tabs from 'client/components/Tabs'
@@ -36,13 +36,13 @@ import Numa from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfi
import { STEP_ID as GENERAL_ID } from 'client/components/Forms/VmTemplate/CreateForm/Steps/General'
import { SCHEMA } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema'
import { getActionsAvailable as getSectionsAvailable } from 'client/models/Helper'
-import { T } from 'client/constants'
+import { T, RESOURCE_NAMES } from 'client/constants'
/**
* @typedef {object} TabType
* @property {string} id - Id will be to use in view yaml to hide/display the tab
* @property {string} name - Label of tab
- * @property {JSXElementConstructor} Content - Content tab
+ * @property {ReactElement} Content - Content tab
* @property {object} [icon] - Icon of tab
* @property {function(FieldErrors):boolean} [getError] - Returns `true` if the tab contains an error in form
*/
@@ -67,12 +67,13 @@ const Content = ({ data, setFormData }) => {
formState: { errors },
control,
} = useFormContext()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const hypervisor = useMemo(() => watch(`${GENERAL_ID}.HYPERVISOR`), [])
const sectionsAvailable = useMemo(() => {
- const dialog = getResourceView('VM-TEMPLATE')?.dialogs?.create_dialog
+ const resource = RESOURCE_NAMES.VM_TEMPLATE
+ const dialog = getResourceView(resource)?.dialogs?.create_dialog
return getSectionsAvailable(dialog, hypervisor)
}, [view])
diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/General/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/General/index.js
index a257e0b4ec..04b82c9145 100644
--- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/General/index.js
+++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/General/index.js
@@ -18,7 +18,7 @@ import { useMemo } from 'react'
import PropTypes from 'prop-types'
import { useWatch } from 'react-hook-form'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import FormWithSchema from 'client/components/Forms/FormWithSchema'
import useStyles from 'client/components/Forms/VmTemplate/CreateForm/Steps/General/styles'
@@ -28,17 +28,18 @@ import {
SECTIONS,
} from 'client/components/Forms/VmTemplate/CreateForm/Steps/General/schema'
import { getActionsAvailable as getSectionsAvailable } from 'client/models/Helper'
-import { T } from 'client/constants'
+import { T, RESOURCE_NAMES } from 'client/constants'
export const STEP_ID = 'general'
const Content = ({ isUpdate }) => {
const classes = useStyles()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const hypervisor = useWatch({ name: `${STEP_ID}.HYPERVISOR` })
const sections = useMemo(() => {
- const dialog = getResourceView('VM-TEMPLATE')?.dialogs?.create_dialog
+ const resource = RESOURCE_NAMES.VM_TEMPLATE
+ const dialog = getResourceView(resource)?.dialogs?.create_dialog
const sectionsAvailable = getSectionsAvailable(dialog, hypervisor)
return SECTIONS(hypervisor, isUpdate).filter(
diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/index.js
index 953905c4c4..737d457b4b 100644
--- a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/index.js
+++ b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/index.js
@@ -17,7 +17,7 @@
import { useMemo } from 'react'
import { useFormContext } from 'react-hook-form'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import FormWithSchema from 'client/components/Forms/FormWithSchema'
import useStyles from 'client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/styles'
@@ -27,18 +27,19 @@ import {
FIELDS,
} from 'client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/schema'
import { getActionsAvailable as getSectionsAvailable } from 'client/models/Helper'
-import { T } from 'client/constants'
+import { T, RESOURCE_NAMES } from 'client/constants'
export const STEP_ID = 'configuration'
const Content = () => {
const classes = useStyles()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { watch } = useFormContext()
const sections = useMemo(() => {
const hypervisor = watch(`${TEMPLATE_ID}[0].TEMPLATE.HYPERVISOR`)
- const dialog = getResourceView('VM-TEMPLATE')?.dialogs?.instantiate_dialog
+ const resource = RESOURCE_NAMES.VM_TEMPLATE
+ const dialog = getResourceView(resource)?.dialogs?.instantiate_dialog
const sectionsAvailable = getSectionsAvailable(dialog, hypervisor)
return FIELDS(hypervisor).filter(({ id }) => sectionsAvailable.includes(id))
diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/informationSchema.js b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/informationSchema.js
index 7552752eed..ed3c0fc172 100644
--- a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/informationSchema.js
+++ b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/BasicConfiguration/informationSchema.js
@@ -17,9 +17,9 @@
import { useMemo } from 'react'
import { string, number, boolean } from 'yup'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { getActionsAvailable } from 'client/models/Helper'
-import { INPUT_TYPES, VM_ACTIONS } from 'client/constants'
+import { RESOURCE_NAMES, INPUT_TYPES, VM_ACTIONS } from 'client/constants'
const NAME = {
name: 'name',
@@ -51,10 +51,11 @@ const HOLD = {
label: 'Start VM on hold state',
type: INPUT_TYPES.SWITCH,
htmlType: () => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
return useMemo(() => {
- const actions = getResourceView('VM')?.actions
+ const resource = RESOURCE_NAMES.VM
+ const actions = getResourceView(resource)?.actions
const actionsAvailable = getActionsAvailable(actions)
return (
diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/index.js
index bbabe39264..d7624fee79 100644
--- a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/index.js
+++ b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/index.js
@@ -19,7 +19,7 @@ import PropTypes from 'prop-types'
import { useFormContext } from 'react-hook-form'
import { SystemShut as OsIcon } from 'iconoir-react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { Translate } from 'client/components/HOC'
import Tabs from 'client/components/Tabs'
@@ -33,7 +33,7 @@ import BootOrder from 'client/components/Forms/VmTemplate/CreateForm/Steps/Extra
import { STEP_ID as TEMPLATE_ID } from 'client/components/Forms/VmTemplate/InstantiateForm/Steps/VmTemplatesTable'
import { SCHEMA } from 'client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/schema'
import { getActionsAvailable as getSectionsAvailable } from 'client/models/Helper'
-import { T } from 'client/constants'
+import { T, RESOURCE_NAMES } from 'client/constants'
export const STEP_ID = 'extra'
@@ -58,12 +58,13 @@ const Content = ({ data, setFormData }) => {
formState: { errors },
control,
} = useFormContext()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const hypervisor = useMemo(() => watch(`${TEMPLATE_ID}.0.HYPERVISOR`), [])
const sectionsAvailable = useMemo(() => {
- const dialog = getResourceView('VM-TEMPLATE')?.dialogs?.instantiate_dialog
+ const resource = RESOURCE_NAMES.VM_TEMPLATE
+ const dialog = getResourceView(resource)?.dialogs?.instantiate_dialog
return getSectionsAvailable(dialog, hypervisor)
}, [view])
diff --git a/src/fireedge/src/client/components/HOC/AuthLayout.js b/src/fireedge/src/client/components/HOC/AuthLayout.js
new file mode 100644
index 0000000000..4d8464bc7c
--- /dev/null
+++ b/src/fireedge/src/client/components/HOC/AuthLayout.js
@@ -0,0 +1,82 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may *
+ * not use this file except in compliance with the License. You may obtain *
+ * a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ * ------------------------------------------------------------------------- */
+import { useEffect, ReactElement } from 'react'
+import { useDispatch } from 'react-redux'
+import PropTypes from 'prop-types'
+
+import { useAuth, useAuthApi } from 'client/features/Auth'
+import { authApi } from 'client/features/AuthApi'
+import groupApi from 'client/features/OneApi/group'
+import FullscreenProgress from 'client/components/LoadingScreen'
+import { findStorageData } from 'client/utils'
+import { JWT_NAME } from 'client/constants'
+
+/**
+ * Renders loading screen while validate JWT.
+ *
+ * @param {object} props - Props
+ * @param {object[]} [props.subscriptions] - Subscriptions after login
+ * @param {ReactElement} [props.children] - Children
+ * @returns {ReactElement} App rendered.
+ */
+const AuthLayout = ({ subscriptions = [], children }) => {
+ const dispatch = useDispatch()
+ const { changeJwt, stopFirstRender } = useAuthApi()
+ const { jwt, isLogged, isLoginInProgress, firstRender } = useAuth()
+
+ useEffect(() => {
+ if (!jwt) return
+
+ const endpoints = [
+ groupApi.endpoints.getGroups,
+ authApi.endpoints.getAuthUser,
+ ...subscriptions,
+ ].map((endpoint) =>
+ dispatch(endpoint.initiate(undefined, { forceRefetch: true }))
+ )
+
+ return () => {
+ endpoints.forEach((endpoint) => {
+ endpoint.unsubscribe()
+ })
+ }
+ }, [dispatch, jwt])
+
+ useEffect(() => {
+ if (!jwt) {
+ const token = findStorageData(JWT_NAME)
+ token && changeJwt(token)
+ }
+
+ // first rendering on client
+ stopFirstRender()
+ }, [])
+
+ if ((jwt && !isLoginInProgress && !isLogged) || firstRender) {
+ return
+ }
+
+ return <>{children}>
+}
+
+AuthLayout.propTypes = {
+ subscriptions: PropTypes.array,
+ children: PropTypes.any,
+}
+
+AuthLayout.displayName = 'AuthLayout'
+
+export default AuthLayout
diff --git a/src/fireedge/src/client/components/HOC/Translate.js b/src/fireedge/src/client/components/HOC/Translate.js
index c6c2da67ad..7cd6fa405a 100644
--- a/src/fireedge/src/client/components/HOC/Translate.js
+++ b/src/fireedge/src/client/components/HOC/Translate.js
@@ -56,7 +56,7 @@ const RemoveScript = () => {
const TranslateProvider = ({ children = [] }) => {
const [hash, setHash] = useState({})
- const { settings: { lang } = {} } = useAuth()
+ const { settings: { LANG: lang } = {} } = useAuth()
useEffect(() => {
GenerateScript(lang, setHash)
@@ -71,14 +71,8 @@ const TranslateProvider = ({ children = [] }) => {
GenerateScript(language, setHash)
}
- const value = {
- lang,
- hash,
- changeLang,
- }
-
return (
-
+
{children}
)
diff --git a/src/fireedge/src/client/components/HOC/index.js b/src/fireedge/src/client/components/HOC/index.js
index ab794d3632..efe0d8fb7c 100644
--- a/src/fireedge/src/client/components/HOC/index.js
+++ b/src/fireedge/src/client/components/HOC/index.js
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+export { default as AuthLayout } from 'client/components/HOC/AuthLayout'
export { default as ConditionalWrap } from 'client/components/HOC/ConditionalWrap'
export { default as InternalLayout } from 'client/components/HOC/InternalLayout'
export * from 'client/components/HOC/Translate'
diff --git a/src/fireedge/src/client/components/Header/Group.js b/src/fireedge/src/client/components/Header/Group.js
index f9b1b098a6..cc0064af18 100644
--- a/src/fireedge/src/client/components/Header/Group.js
+++ b/src/fireedge/src/client/components/Header/Group.js
@@ -16,10 +16,11 @@
import { useMemo, memo, JSXElementConstructor } from 'react'
import PropTypes from 'prop-types'
-import { Button } from '@mui/material'
+import { Button, Stack, CircularProgress } from '@mui/material'
import { Group as GroupIcon, VerifiedBadge as SelectIcon } from 'iconoir-react'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuth } from 'client/features/Auth'
+import { useChangeAuthGroupMutation } from 'client/features/AuthApi'
import Search from 'client/components/Search'
import HeaderPopover from 'client/components/Header/Popover'
import { Tr, Translate } from 'client/components/HOC'
@@ -28,10 +29,8 @@ import { T, FILTER_POOL } from 'client/constants'
const { ALL_RESOURCES, PRIMARY_GROUP_RESOURCES } = FILTER_POOL
const ButtonGroup = memo(
- ({ group, handleClick }) => {
- const { changeGroup } = useAuthApi()
+ ({ group, handleClick, disabled }) => {
const { user, filterPool } = useAuth()
-
const { ID, NAME } = group
const isSelected =
@@ -41,12 +40,10 @@ const ButtonGroup = memo(
return (
)
},
- (prev, next) => prev.group.ID === next.group.ID
+ (prev, next) =>
+ prev.group.ID === next.group.ID && prev.disabled === next.disabled
)
/**
@@ -68,6 +66,7 @@ const ButtonGroup = memo(
* @returns {JSXElementConstructor} Returns group list
*/
const Group = () => {
+ const [changeGroup, { isLoading }] = useChangeAuthGroupMutation()
const { user, groups } = useAuth()
const sortGroupAsMainFirst = (a, b) =>
@@ -86,7 +85,12 @@ const Group = () => {
icon={}
tooltip={}
buttonProps={{ 'data-cy': 'header-group-button' }}
- headerTitle={}
+ headerTitle={
+
+
+ {isLoading && }
+
+ }
>
{({ handleClose }) => (
{
{
+ group?.ID && (await changeGroup({ group: group.ID }))
+ handleClose()
+ }}
/>
)}
/>
@@ -111,11 +119,9 @@ const Group = () => {
}
ButtonGroup.propTypes = {
- group: PropTypes.shape({
- ID: PropTypes.string,
- NAME: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
- }).isRequired,
+ group: PropTypes.object,
handleClick: PropTypes.func,
+ disabled: PropTypes.bool,
}
ButtonGroup.displayName = 'ButtonGroup'
diff --git a/src/fireedge/src/client/components/Header/User.js b/src/fireedge/src/client/components/Header/User.js
index 45723999f1..0b49eb079f 100644
--- a/src/fireedge/src/client/components/Header/User.js
+++ b/src/fireedge/src/client/components/Header/User.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement } from 'react'
import { MenuItem, MenuList, Link } from '@mui/material'
import { ProfileCircled as UserIcon } from 'iconoir-react'
@@ -28,7 +28,7 @@ import { T, APPS, APP_URL } from 'client/constants'
/**
* Menu with actions about App: signOut, etc.
*
- * @returns {JSXElementConstructor} Returns user actions list
+ * @returns {ReactElement} Returns user actions list
*/
const User = () => {
const { user } = useAuth()
diff --git a/src/fireedge/src/client/components/Header/View.js b/src/fireedge/src/client/components/Header/View.js
index 5b14304aa0..55b23651c3 100644
--- a/src/fireedge/src/client/components/Header/View.js
+++ b/src/fireedge/src/client/components/Header/View.js
@@ -22,7 +22,7 @@ import {
VerifiedBadge as SelectIcon,
} from 'iconoir-react'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuthApi, useViews } from 'client/features/Auth'
import Search from 'client/components/Search'
import HeaderPopover from 'client/components/Header/Popover'
import { Translate } from 'client/components/HOC'
@@ -31,7 +31,7 @@ import { T } from 'client/constants'
const ButtonView = memo(
({ view, handleClick }) => {
const { changeView } = useAuthApi()
- const { view: currentView } = useAuth()
+ const { view: currentView } = useViews()
const isCurrentView = currentView === view
return (
@@ -73,7 +73,7 @@ ButtonView.displayName = 'ButtonView'
* @returns {ReactElement} Returns interface views list
*/
const View = () => {
- const { view: currentView, views = {} } = useAuth()
+ const { view: currentView, views = {} } = useViews()
const viewNames = useMemo(() => Object.keys(views), [currentView])
return (
diff --git a/src/fireedge/src/client/components/LoadingScreen/index.js b/src/fireedge/src/client/components/LoadingScreen/index.js
index 8b63fe2ebe..916f131ebf 100644
--- a/src/fireedge/src/client/components/LoadingScreen/index.js
+++ b/src/fireedge/src/client/components/LoadingScreen/index.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement } from 'react'
import { Box } from '@mui/material'
import { OpenNebulaLogo } from 'client/components/Icons'
@@ -21,21 +21,10 @@ import { OpenNebulaLogo } from 'client/components/Icons'
/**
* Component with OpenNebula logo as spinner in full width and height.
*
- * @returns {JSXElementConstructor} Container with logo inside
+ * @returns {ReactElement} Container with logo inside
*/
const LoadingScreen = () => (
-
+
)
diff --git a/src/fireedge/src/client/components/Route/NoAuthRoute.js b/src/fireedge/src/client/components/Route/NoAuthRoute.js
index da908e133b..822b1e1175 100644
--- a/src/fireedge/src/client/components/Route/NoAuthRoute.js
+++ b/src/fireedge/src/client/components/Route/NoAuthRoute.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement } from 'react'
import PropTypes from 'prop-types'
import { Redirect, Route } from 'react-router-dom'
@@ -23,14 +23,13 @@ import { useAuth } from 'client/features/Auth'
* Public route.
*
* @param {object} props - Route props
- * @param {JSXElementConstructor} props.redirectWhenAuth
+ * @param {ReactElement} props.redirectWhenAuth
* - Route to redirect in case of user is authenticated
* @returns {Redirect|Route}
* - If current user is authenticated, then redirect to private route
*/
const NoAuthRoute = ({ redirectWhenAuth, ...props }) => {
- const { isLogged, isLoginInProgress, isLoading } = useAuth()
- const isAuthenticated = isLogged && !isLoginInProgress && !isLoading
+ const { isLogged: isAuthenticated } = useAuth()
return isAuthenticated ? (
diff --git a/src/fireedge/src/client/components/Route/ProtectedRoute.js b/src/fireedge/src/client/components/Route/ProtectedRoute.js
index 584fcf5131..419eaf6243 100644
--- a/src/fireedge/src/client/components/Route/ProtectedRoute.js
+++ b/src/fireedge/src/client/components/Route/ProtectedRoute.js
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuth } from 'client/features/Auth'
/**
* Private route.
@@ -26,14 +25,9 @@ import { useAuth, useAuthApi } from 'client/features/Auth'
* - If current user isn't authenticated, then redirect to landing page
*/
const ProtectedRoute = (props) => {
- const { isLogged, jwt } = useAuth()
- const { getAuthUser } = useAuthApi()
+ const { isLogged: isAuthenticated } = useAuth()
- useEffect(() => {
- jwt && getAuthUser()
- }, [])
-
- return isLogged ? :
+ return isAuthenticated ? :
}
export default ProtectedRoute
diff --git a/src/fireedge/src/client/components/Tables/Clusters/index.js b/src/fireedge/src/client/components/Tables/Clusters/index.js
index 506f7ab054..feedb470e3 100644
--- a/src/fireedge/src/client/components/Tables/Clusters/index.js
+++ b/src/fireedge/src/client/components/Tables/Clusters/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetClustersQuery } from 'client/features/OneApi/cluster'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const ClustersTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetClustersQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Datastores/index.js b/src/fireedge/src/client/components/Tables/Datastores/index.js
index 2b1ea66a49..4d0563b2f2 100644
--- a/src/fireedge/src/client/components/Tables/Datastores/index.js
+++ b/src/fireedge/src/client/components/Tables/Datastores/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetDatastoresQuery } from 'client/features/OneApi/datastore'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -39,7 +39,7 @@ const DatastoresTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js b/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js
index 8214a71e7e..dcccab6b20 100644
--- a/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js
+++ b/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js
@@ -20,8 +20,8 @@ import { GlobalAction } from 'client/components/Tables/Enhanced/Utils/GlobalActi
/**
* Add filters defined in view yaml to columns.
*
- * @param {object} config -
- * @param {object[]} config.filters - List of criteria to filter the columns.
+ * @param {object} config - Config
+ * @param {object} config.filters - List of criteria to filter the columns.
* @param {Column[]} config.columns - Columns
* @returns {object} Column with filters
*/
@@ -64,7 +64,7 @@ export const createCategoryFilter = (title) => ({
* Add filters defined in view yaml to bulk actions.
*
* @param {object} params - Config parameters
- * @param {object[]} params.filters - Which buttons are visible to operate over the resources
+ * @param {object} params.filters - Which buttons are visible to operate over the resources
* @param {GlobalAction[]} params.actions - Actions
* @returns {object} Action with filters
*/
@@ -82,7 +82,7 @@ export const createActions = ({ filters = {}, actions = [] }) => {
if (accessor) return action
const groupActions = options?.filter(
- (option) => filters[String(option.accessor?.toLowerCase())] === true
+ (option) => filters[`${option.accessor?.toLowerCase()}`] === true
)
return groupActions?.length > 0
diff --git a/src/fireedge/src/client/components/Tables/Groups/index.js b/src/fireedge/src/client/components/Tables/Groups/index.js
index e1bf553eb8..c3431dee52 100644
--- a/src/fireedge/src/client/components/Tables/Groups/index.js
+++ b/src/fireedge/src/client/components/Tables/Groups/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetGroupsQuery } from 'client/features/OneApi/group'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const GroupsTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetGroupsQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Hosts/index.js b/src/fireedge/src/client/components/Tables/Hosts/index.js
index eaa7e79c5a..f8b56e7d71 100644
--- a/src/fireedge/src/client/components/Tables/Hosts/index.js
+++ b/src/fireedge/src/client/components/Tables/Hosts/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetHostsQuery } from 'client/features/OneApi/host'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -39,7 +39,7 @@ const HostsTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Images/index.js b/src/fireedge/src/client/components/Tables/Images/index.js
index 6c54036937..f075620f09 100644
--- a/src/fireedge/src/client/components/Tables/Images/index.js
+++ b/src/fireedge/src/client/components/Tables/Images/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetImagesQuery } from 'client/features/OneApi/image'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const ImagesTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetImagesQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js b/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js
index 2188e75c9b..0f5ed1813c 100644
--- a/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js
+++ b/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js
@@ -18,7 +18,7 @@ import { useMemo } from 'react'
import { useHistory } from 'react-router-dom'
import { AddSquare, CloudDownload } from 'iconoir-react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGeneralApi } from 'client/features/General'
import { Translate } from 'client/components/HOC'
import { useExportAppMutation } from 'client/features/OneApi/marketplaceApp'
@@ -48,7 +48,7 @@ MessageToConfirmAction.displayName = 'MessageToConfirmAction'
const Actions = () => {
const history = useHistory()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { enqueueSuccess } = useGeneralApi()
const [exportApp] = useExportAppMutation()
diff --git a/src/fireedge/src/client/components/Tables/MarketplaceApps/index.js b/src/fireedge/src/client/components/Tables/MarketplaceApps/index.js
index 0c10a3bbc4..f9ef57497e 100644
--- a/src/fireedge/src/client/components/Tables/MarketplaceApps/index.js
+++ b/src/fireedge/src/client/components/Tables/MarketplaceApps/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetMarketplaceAppsQuery } from 'client/features/OneApi/marketplaceApp'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const MarketplaceAppsTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetMarketplaceAppsQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Marketplaces/index.js b/src/fireedge/src/client/components/Tables/Marketplaces/index.js
index 99651fe7a4..7d88d25c46 100644
--- a/src/fireedge/src/client/components/Tables/Marketplaces/index.js
+++ b/src/fireedge/src/client/components/Tables/Marketplaces/index.js
@@ -16,7 +16,7 @@
import { useMemo, ReactElement } from 'react'
import PropTypes from 'prop-types'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetMarketplacesQuery } from 'client/features/OneApi/marketplace'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -41,7 +41,7 @@ const MarketplacesTable = ({ filter, ...props }) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Users/index.js b/src/fireedge/src/client/components/Tables/Users/index.js
index b2b5531317..8d5bef5f93 100644
--- a/src/fireedge/src/client/components/Tables/Users/index.js
+++ b/src/fireedge/src/client/components/Tables/Users/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetUsersQuery } from 'client/features/OneApi/user'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const UsersTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetUsersQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/VNetworkTemplates/index.js b/src/fireedge/src/client/components/Tables/VNetworkTemplates/index.js
index 94d726ebd3..a44adad230 100644
--- a/src/fireedge/src/client/components/Tables/VNetworkTemplates/index.js
+++ b/src/fireedge/src/client/components/Tables/VNetworkTemplates/index.js
@@ -16,7 +16,7 @@
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVNTemplatesQuery } from 'client/features/OneApi/networkTemplate'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -35,7 +35,7 @@ const VNetworkTemplatesTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetVNTemplatesQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/VNetworks/index.js b/src/fireedge/src/client/components/Tables/VNetworks/index.js
index 4bd98630ee..28f4d41dd6 100644
--- a/src/fireedge/src/client/components/Tables/VNetworks/index.js
+++ b/src/fireedge/src/client/components/Tables/VNetworks/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVNetworksQuery } from 'client/features/OneApi/network'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -39,7 +39,7 @@ const VNetworksTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/VRouters/index.js b/src/fireedge/src/client/components/Tables/VRouters/index.js
index dfeceb8794..e657fd48ac 100644
--- a/src/fireedge/src/client/components/Tables/VRouters/index.js
+++ b/src/fireedge/src/client/components/Tables/VRouters/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVRoutersQuery } from 'client/features/OneApi/vrouter'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const VRoutersTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetVRoutersQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/VmTemplates/actions.js b/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
index 646c1c4850..13f8af2034 100644
--- a/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
+++ b/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
@@ -26,7 +26,7 @@ import {
Cart,
} from 'iconoir-react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import {
useLockTemplateMutation,
useUnlockTemplateMutation,
@@ -66,7 +66,7 @@ MessageToConfirmAction.displayName = 'MessageToConfirmAction'
const Actions = () => {
const history = useHistory()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const [lock] = useLockTemplateMutation()
const [unlock] = useUnlockTemplateMutation()
const [clone] = useCloneTemplateMutation()
@@ -281,7 +281,7 @@ const Actions = () => {
const marketplaceAppActions = useMemo(
() =>
createActions({
- filters: getResourceView('MARKETPLACE-APP')?.actions,
+ filters: getResourceView(RESOURCE_NAMES.APP)?.actions,
actions: [
{
accessor: MARKETPLACE_APP_ACTIONS.CREATE_DIALOG,
diff --git a/src/fireedge/src/client/components/Tables/VmTemplates/index.js b/src/fireedge/src/client/components/Tables/VmTemplates/index.js
index 9a3cfce018..9ab8d03303 100644
--- a/src/fireedge/src/client/components/Tables/VmTemplates/index.js
+++ b/src/fireedge/src/client/components/Tables/VmTemplates/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetTemplatesQuery } from 'client/features/OneApi/vmTemplate'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const VmTemplatesTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetTemplatesQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tables/Vms/actions.js b/src/fireedge/src/client/components/Tables/Vms/actions.js
index c272cd06b3..6fe8ed70eb 100644
--- a/src/fireedge/src/client/components/Tables/Vms/actions.js
+++ b/src/fireedge/src/client/components/Tables/Vms/actions.js
@@ -28,7 +28,7 @@ import {
Cart,
} from 'iconoir-react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGeneralApi } from 'client/features/General'
import { useGetDatastoresQuery } from 'client/features/OneApi/datastore'
import {
@@ -106,7 +106,7 @@ const MessageToConfirmAction = (rows) => (
*/
const Actions = () => {
const history = useHistory()
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { enqueueSuccess } = useGeneralApi()
const [saveAsTemplate] = useSaveAsTemplateMutation()
diff --git a/src/fireedge/src/client/components/Tables/Vms/index.js b/src/fireedge/src/client/components/Tables/Vms/index.js
index 3611d83ee1..a87b2d95bf 100644
--- a/src/fireedge/src/client/components/Tables/Vms/index.js
+++ b/src/fireedge/src/client/components/Tables/Vms/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useState, useEffect, useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVmsQuery } from 'client/features/OneApi/vm'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -43,7 +43,7 @@ const VmsTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const [totalData, setTotalData] = useState(() => [])
const [args, setArgs] = useState(() => INITIAL_ARGS)
const { data, isSuccess, isFetching } = useGetVmsQuery(args, {
diff --git a/src/fireedge/src/client/components/Tables/Zones/index.js b/src/fireedge/src/client/components/Tables/Zones/index.js
index 3f4834f083..7ea2ce0fb8 100644
--- a/src/fireedge/src/client/components/Tables/Zones/index.js
+++ b/src/fireedge/src/client/components/Tables/Zones/index.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { useMemo, ReactElement } from 'react'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetZonesQuery } from 'client/features/OneApi/zone'
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
@@ -34,7 +34,7 @@ const ZonesTable = (props) => {
rootProps['data-cy'] ??= DEFAULT_DATA_CY
searchProps['data-cy'] ??= `search-${DEFAULT_DATA_CY}`
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { data = [], isFetching, refetch } = useGetZonesQuery()
const columns = useMemo(
diff --git a/src/fireedge/src/client/components/Tabs/Cluster/index.js b/src/fireedge/src/client/components/Tabs/Cluster/index.js
index 0e08ba49eb..3a1973a057 100644
--- a/src/fireedge/src/client/components/Tabs/Cluster/index.js
+++ b/src/fireedge/src/client/components/Tabs/Cluster/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetClusterQuery } from 'client/features/OneApi/cluster'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const ClusterTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetClusterQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Datastore/index.js b/src/fireedge/src/client/components/Tabs/Datastore/index.js
index 60a6c21d5f..612801fdf1 100644
--- a/src/fireedge/src/client/components/Tabs/Datastore/index.js
+++ b/src/fireedge/src/client/components/Tabs/Datastore/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetDatastoreQuery } from 'client/features/OneApi/datastore'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const DatastoreTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetDatastoreQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Group/index.js b/src/fireedge/src/client/components/Tabs/Group/index.js
index e718c37ea9..704513778b 100644
--- a/src/fireedge/src/client/components/Tabs/Group/index.js
+++ b/src/fireedge/src/client/components/Tabs/Group/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetGroupQuery } from 'client/features/OneApi/group'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const GroupTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetGroupQuery(id)
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Image/index.js b/src/fireedge/src/client/components/Tabs/Image/index.js
index 12e7e22359..0f2e741ebb 100644
--- a/src/fireedge/src/client/components/Tabs/Image/index.js
+++ b/src/fireedge/src/client/components/Tabs/Image/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetImageQuery } from 'client/features/OneApi/image'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const ImageTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetImageQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Marketplace/index.js b/src/fireedge/src/client/components/Tabs/Marketplace/index.js
index 9e17719f1c..49b60ea7ce 100644
--- a/src/fireedge/src/client/components/Tabs/Marketplace/index.js
+++ b/src/fireedge/src/client/components/Tabs/Marketplace/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetMarketplaceQuery } from 'client/features/OneApi/marketplace'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const MarketplaceTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetMarketplaceQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/MarketplaceApp/index.js b/src/fireedge/src/client/components/Tabs/MarketplaceApp/index.js
index bb0900ce7d..0dc5ee59ac 100644
--- a/src/fireedge/src/client/components/Tabs/MarketplaceApp/index.js
+++ b/src/fireedge/src/client/components/Tabs/MarketplaceApp/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetMarketplaceAppQuery } from 'client/features/OneApi/marketplaceApp'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -33,7 +33,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const MarketplaceAppTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetMarketplaceAppQuery(id)
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/User/index.js b/src/fireedge/src/client/components/Tabs/User/index.js
index c1baaa0d5b..0291dd9623 100644
--- a/src/fireedge/src/client/components/Tabs/User/index.js
+++ b/src/fireedge/src/client/components/Tabs/User/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetUserQuery } from 'client/features/OneApi/user'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const UserTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetUserQuery(id)
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/VNetwork/index.js b/src/fireedge/src/client/components/Tabs/VNetwork/index.js
index 98e84067fd..e845e91105 100644
--- a/src/fireedge/src/client/components/Tabs/VNetwork/index.js
+++ b/src/fireedge/src/client/components/Tabs/VNetwork/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVNetworkQuery } from 'client/features/OneApi/network'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const VNetworkTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetVNetworkQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/VNetworkTemplate/index.js b/src/fireedge/src/client/components/Tabs/VNetworkTemplate/index.js
index 9b4185751c..5b74f12d43 100644
--- a/src/fireedge/src/client/components/Tabs/VNetworkTemplate/index.js
+++ b/src/fireedge/src/client/components/Tabs/VNetworkTemplate/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVNTemplateQuery } from 'client/features/OneApi/networkTemplate'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const VNetTemplateTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetVNTemplateQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Vm/index.js b/src/fireedge/src/client/components/Tabs/Vm/index.js
index 1b46e3736c..2a53db92a3 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetVmQuery } from 'client/features/OneApi/vm'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -45,7 +45,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const VmTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetVmQuery(id)
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/VmTemplate/index.js b/src/fireedge/src/client/components/Tabs/VmTemplate/index.js
index cbca687d2f..b4c3b0e959 100644
--- a/src/fireedge/src/client/components/Tabs/VmTemplate/index.js
+++ b/src/fireedge/src/client/components/Tabs/VmTemplate/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetTemplateQuery } from 'client/features/OneApi/vmTemplate'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -33,7 +33,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const VmTemplateTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetTemplateQuery({ id })
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/components/Tabs/Zone/index.js b/src/fireedge/src/client/components/Tabs/Zone/index.js
index 2a9d1d8197..58fc377c36 100644
--- a/src/fireedge/src/client/components/Tabs/Zone/index.js
+++ b/src/fireedge/src/client/components/Tabs/Zone/index.js
@@ -17,7 +17,7 @@ import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
+import { useViews } from 'client/features/Auth'
import { useGetZoneQuery } from 'client/features/OneApi/zone'
import { getAvailableInfoTabs } from 'client/models/Helper'
import { RESOURCE_NAMES } from 'client/constants'
@@ -31,7 +31,7 @@ const getTabComponent = (tabName) =>
}[tabName])
const ZoneTabs = memo(({ id }) => {
- const { view, getResourceView } = useAuth()
+ const { view, getResourceView } = useViews()
const { isLoading } = useGetZoneQuery(id)
const tabsAvailable = useMemo(() => {
diff --git a/src/fireedge/src/client/constants/index.js b/src/fireedge/src/client/constants/index.js
index 71edd034f3..3a674cbe3a 100644
--- a/src/fireedge/src/client/constants/index.js
+++ b/src/fireedge/src/client/constants/index.js
@@ -27,7 +27,6 @@ export const BY = {
url: 'https://opennebula.io/',
}
-export const TIME_HIDE_LOGO = 1500
export const _APPS = defaultApps
export const APPS = Object.keys(defaultApps)
export const APPS_IN_BETA = [_APPS.sunstone.name]
diff --git a/src/fireedge/src/client/containers/Dashboard/Provision/index.js b/src/fireedge/src/client/containers/Dashboard/Provision/index.js
index 061d136fb3..0d73d4eda9 100644
--- a/src/fireedge/src/client/containers/Dashboard/Provision/index.js
+++ b/src/fireedge/src/client/containers/Dashboard/Provision/index.js
@@ -37,12 +37,12 @@ import { T } from 'client/constants'
/** @returns {ReactElement} Provision dashboard container */
function ProvisionDashboard() {
- const { settings: { disableanimations } = {} } = useAuth()
+ const { settings: { DISABLE_ANIMATIONS } = {} } = useAuth()
return (
theme.breakpoints.only('xs'))
- const {
- error,
- isLoading: authLoading,
- isLoginInProgress: needGroupToContinue,
- } = useAuth()
+ const { error: otherError, isLoginInProgress: needGroupToContinue } =
+ useAuth()
+ const { logout } = useAuthApi()
- const { login, getAuthUser, changeGroup, logout } = useAuthApi()
- const { fetchRequest: fetchLogin, loading: loginIsLoading } = useFetch(login)
+ const [changeAuthGroup, changeAuthGroupState] = useChangeAuthGroupMutation()
+ const [login, loginState] = useLoginMutation()
+ const isLoading = loginState.isLoading || changeAuthGroupState.isLoading
+ const errorMessage = loginState.error?.data?.message ?? otherError
const [dataUserForm, setDataUserForm] = useState(undefined)
const [step, setStep] = useState(() =>
@@ -56,19 +59,20 @@ function Login() {
)
const handleSubmitUser = async (dataForm) => {
- const response = await fetchLogin({ ...dataUserForm, ...dataForm })
- const { jwt, user, isLoginInProgress } = response || {}
+ try {
+ const response = await login({ ...dataUserForm, ...dataForm }).unwrap()
+ const { jwt, user, isLoginInProgress } = response || {}
- if (jwt && isLoginInProgress) {
- getAuthUser()
- setStep(STEPS.GROUP_FORM)
- } else if (!jwt && user?.ID) {
- setStep(STEPS.FA2_FORM)
- setDataUserForm(dataForm)
- }
+ if (jwt && isLoginInProgress) {
+ setStep(STEPS.GROUP_FORM)
+ } else if (!jwt && user?.ID) {
+ setStep(STEPS.FA2_FORM)
+ setDataUserForm(dataForm)
+ }
+ } catch {}
}
- const handleSubmitGroup = (dataForm) => changeGroup(dataForm)
+ const handleSubmitGroup = (dataForm) => changeAuthGroup(dataForm)
const handleBack = () => {
logout()
@@ -76,8 +80,6 @@ function Login() {
setStep(STEPS.USER_FORM)
}
- const isLoading = loginIsLoading || authLoading
-
return (
)}
@@ -125,7 +127,7 @@ function Login() {
onSubmit={handleSubmitUser}
resolver={FORMS.FORM_2FA_SCHEMA}
fields={FORMS.FORM_2FA_FIELDS}
- error={error}
+ error={errorMessage}
isLoading={isLoading}
/>
)}
@@ -139,7 +141,7 @@ function Login() {
onSubmit={handleSubmitGroup}
resolver={FORMS.FORM_GROUP_SCHEMA}
fields={FORMS.FORM_GROUP_FIELDS}
- error={error}
+ error={errorMessage}
isLoading={isLoading}
/>
)}
diff --git a/src/fireedge/src/client/containers/Settings/index.js b/src/fireedge/src/client/containers/Settings/index.js
index 6b8c2bb986..4875dc1136 100644
--- a/src/fireedge/src/client/containers/Settings/index.js
+++ b/src/fireedge/src/client/containers/Settings/index.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement, useMemo } from 'react'
import { Container, Paper, Box, Typography, Divider } from '@mui/material'
import { useForm, FormProvider } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup'
@@ -21,7 +21,8 @@ import { yupResolver } from '@hookform/resolvers/yup'
import FormWithSchema from 'client/components/Forms/FormWithSchema'
import SubmitButton from 'client/components/FormControl/SubmitButton'
-import { useAuth, useAuthApi } from 'client/features/Auth'
+import { useAuth } from 'client/features/Auth'
+import { useLazyGetAuthUserQuery } from 'client/features/AuthApi'
import { useUpdateUserMutation } from 'client/features/OneApi/user'
import { useGeneralApi } from 'client/features/General'
import { Translate, Tr } from 'client/components/HOC'
@@ -30,24 +31,28 @@ import { T } from 'client/constants'
import { FORM_FIELDS, FORM_SCHEMA } from 'client/containers/Settings/schema'
import * as Helper from 'client/models/Helper'
-/** @returns {JSXElementConstructor} Settings container */
+/** @returns {ReactElement} Settings container */
const Settings = () => {
const { user, settings } = useAuth()
- const { getAuthUser } = useAuthApi()
+ const [getAuthUser] = useLazyGetAuthUserQuery()
const [updateUser] = useUpdateUserMutation()
const { enqueueError } = useGeneralApi()
- const { handleSubmit, setError, reset, formState, ...methods } = useForm({
+ const { handleSubmit, reset, formState, ...methods } = useForm({
reValidateMode: 'onSubmit',
- defaultValues: FORM_SCHEMA.cast(settings),
+ defaultValues: useMemo(() => FORM_SCHEMA.cast(settings), [settings]),
resolver: yupResolver(FORM_SCHEMA),
})
- const onSubmit = async (dataForm) => {
+ const onSubmit = async (formData) => {
try {
- const template = Helper.jsonToXml({ FIREEDGE: dataForm })
+ const data = FORM_SCHEMA.cast(formData, { isSubmit: true })
+ const template = Helper.jsonToXml({ FIREEDGE: data })
await updateUser({ id: user.ID, template })
- getAuthUser()
+ await getAuthUser()
+
+ // Reset either the entire form state or part of the form state
+ reset(formData)
} catch {
enqueueError(T.SomethingWrong)
}
diff --git a/src/fireedge/src/client/containers/Settings/schema.js b/src/fireedge/src/client/containers/Settings/schema.js
index f29a3629b4..ea403b9bf5 100644
--- a/src/fireedge/src/client/containers/Settings/schema.js
+++ b/src/fireedge/src/client/containers/Settings/schema.js
@@ -24,7 +24,7 @@ import {
import { getValidationFromFields } from 'client/utils'
const SCHEME = {
- name: 'scheme',
+ name: 'SCHEME',
label: T.Schema,
type: INPUT_TYPES.SELECT,
values: [
@@ -40,7 +40,7 @@ const SCHEME = {
}
const LANGUAGES = {
- name: 'lang',
+ name: 'LANG',
label: T.Language,
type: INPUT_TYPES.SELECT,
values: () =>
@@ -53,7 +53,7 @@ const LANGUAGES = {
}
const DISABLE_ANIMATIONS = {
- name: 'disableanimations',
+ name: 'DISABLE_ANIMATIONS',
label: T.DisableDashboardAnimations,
type: INPUT_TYPES.CHECKBOX,
validation: boolean()
diff --git a/src/fireedge/src/client/dev/_app.js b/src/fireedge/src/client/dev/_app.js
index 03e89edd28..e42daeeb5c 100644
--- a/src/fireedge/src/client/dev/_app.js
+++ b/src/fireedge/src/client/dev/_app.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement } from 'react'
import SunstoneApp from 'client/apps/sunstone'
import ProvisionApp from 'client/apps/provision'
@@ -26,7 +26,7 @@ import { _APPS, APPS } from 'client/constants'
* Render App by url: http:///fireedge/.
*
* @param {object} props - Props from server
- * @returns {JSXElementConstructor} Returns App
+ * @returns {ReactElement} Returns App
*/
const DevelopmentApp = (props) => {
let appName = ''
diff --git a/src/fireedge/src/client/features/Auth/actions.js b/src/fireedge/src/client/features/Auth/actions.js
deleted file mode 100644
index 437478ef90..0000000000
--- a/src/fireedge/src/client/features/Auth/actions.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
- * *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may *
- * not use this file except in compliance with the License. You may obtain *
- * a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, software *
- * distributed under the License is distributed on an "AS IS" BASIS, *
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
- * See the License for the specific language governing permissions and *
- * limitations under the License. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { createAction, createAsyncThunk } from '@reduxjs/toolkit'
-
-import { authService } from 'client/features/Auth/services'
-import { dismissSnackbar } from 'client/features/General/actions'
-import apiUser from 'client/features/OneApi/user'
-
-import { httpCodes } from 'server/utils/constants'
-import { removeStoreData, storage } from 'client/utils'
-import { FILTER_POOL, JWT_NAME, ONEADMIN_ID, T } from 'client/constants'
-
-export const login = createAsyncThunk(
- 'auth/login',
- async ({ remember, ...user }, { rejectWithValue, dispatch }) => {
- try {
- const response = await authService.login({ ...user, remember })
- const { id, token } = response
- const isOneAdmin = id === ONEADMIN_ID
-
- if (token) {
- storage(JWT_NAME, token, remember)
- dispatch(dismissSnackbar({ dismissAll: true }))
- }
-
- return {
- jwt: token,
- user: { ID: id },
- isOneAdmin,
- isLoginInProgress: !!token && !isOneAdmin,
- }
- } catch (error) {
- const { message, data, statusText } = error
-
- return rejectWithValue({ error: message ?? data?.message ?? statusText })
- }
- }
-)
-
-export const getUser = createAsyncThunk(
- 'auth/user',
- async (_, { dispatch, getState }) => {
- try {
- const { auth = {} } = getState()
-
- const user = await authService.getUser()
- const isOneAdmin = user?.ID === ONEADMIN_ID
- const userSettings = user?.TEMPLATE?.FIREEDGE ?? {}
-
- // Merge user settings with the existing one
- const settings = {
- ...auth?.settings,
- ...Object.entries(userSettings).reduce(
- (res, [key, value]) => ({
- ...res,
- [String(key).toLowerCase()]: value,
- }),
- {}
- ),
- }
-
- return { user, settings, isOneAdmin }
- } catch (error) {
- console.log({ error })
- dispatch(logout(T.SessionExpired))
- }
- },
- {
- condition: (_, { getState }) => {
- const { isLoading } = getState().auth
-
- return !isLoading
- },
- }
-)
-
-export const logout = createAction('logout', (errorMessage) => {
- removeStoreData([JWT_NAME])
-
- return { error: errorMessage }
-})
-
-export const changeFilter = createAction(
- 'auth/change-filter',
- (filterPool) => ({ payload: { filterPool, isLoginInProgress: false } })
-)
-
-export const changeGroup = createAsyncThunk(
- 'auth/change-group',
- async ({ group }, { getState, dispatch, rejectWithValue }) => {
- try {
- if (group === FILTER_POOL.ALL_RESOURCES) {
- dispatch(changeFilter(FILTER_POOL.ALL_RESOURCES))
- } else {
- const { user } = getState().auth
-
- const data = { id: user?.ID, group }
- dispatch(apiUser.endpoints.changeGroup.initiate(data)).reset()
-
- dispatch(changeFilter(FILTER_POOL.PRIMARY_GROUP_RESOURCES))
-
- return {
- user: {
- ...user,
- GID: group,
- },
- }
- }
- } catch (error) {
- const { message, data, status, statusText } = error
-
- status === httpCodes.unauthorized.id && dispatch(logout(T.SessionExpired))
-
- return rejectWithValue({ error: message ?? data?.message ?? statusText })
- }
- }
-)
-
-export const changeView = createAction('auth/change-view', (view) => ({
- payload: { view },
-}))
diff --git a/src/fireedge/src/client/features/Auth/hooks.js b/src/fireedge/src/client/features/Auth/hooks.js
index 7e4755d78f..55b08a3481 100644
--- a/src/fireedge/src/client/features/Auth/hooks.js
+++ b/src/fireedge/src/client/features/Auth/hooks.js
@@ -14,29 +14,38 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
+import { useCallback, useMemo } from 'react'
import { useDispatch, useSelector, shallowEqual } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-import * as actions from 'client/features/Auth/actions'
-import { name as authSlice } from 'client/features/Auth/slice'
-import apiGroup from 'client/features/OneApi/group'
-import apiSystem from 'client/features/OneApi/system'
-import { RESOURCE_NAMES } from 'client/constants'
+import { name as generalSlice } from 'client/features/General/slice'
+import { name as authSlice, actions } from 'client/features/Auth/slice'
+import groupApi from 'client/features/OneApi/group'
+import systemApi from 'client/features/OneApi/system'
+import { _APPS, RESOURCE_NAMES, ONEADMIN_ID } from 'client/constants'
+import { ResourceView } from 'client/apps/sunstone/routes'
+
+const APPS_WITH_VIEWS = [_APPS.sunstone.name].map((app) => app.toLowerCase())
+
+const appNeedViews = () => {
+ const { appTitle } = useSelector((state) => state[generalSlice], shallowEqual)
+
+ return useMemo(() => APPS_WITH_VIEWS.includes(appTitle), [appTitle])
+}
+
+// --------------------------------------------------------------
+// Authenticate Hooks
+// --------------------------------------------------------------
export const useAuth = () => {
const auth = useSelector((state) => state[authSlice], shallowEqual)
- const { user, jwt, view, isLoginInProgress } = auth
+ const { jwt, user, view, settings, isLoginInProgress } = auth
- const { data: views } = apiSystem.endpoints.getSunstoneViews.useQuery(
- undefined,
- { skip: !jwt }
- )
+ const waitViewToLogin = appNeedViews() ? !!view : true
- const { data: userGroups } = apiGroup.endpoints.getGroups.useQuery(
+ const { data: authGroups } = groupApi.endpoints.getGroups.useQueryState(
undefined,
{
- skip: !jwt,
+ skip: !jwt || !user?.GROUPS?.ID,
selectFromResult: ({ data: groups = [] }) => ({
data: [user?.GROUPS?.ID]
.flat()
@@ -46,52 +55,62 @@ export const useAuth = () => {
}
)
- const isLogged = !!jwt && !!userGroups?.length && !isLoginInProgress
-
- /**
- * Looking for resource view of user authenticated.
- *
- * @param {RESOURCE_NAMES} resourceName - Name of resource
- * @returns {{
- * resource_name: string,
- * actions: object[],
- * filters: object[],
- * info-tabs: object,
- * dialogs: object[]
- * }} Returns view of resource
- */
- const getResourceView = useCallback(
- (resourceName) =>
- views?.[view]?.find(
- ({ resource_name: name }) =>
- String(name).toLowerCase() === String(resourceName).toLowerCase()
- ),
- [view]
+ return useMemo(
+ () => ({
+ ...auth,
+ user,
+ isOneAdmin: user?.ID === ONEADMIN_ID,
+ groups: authGroups,
+ // Merge user settings with the existing one
+ settings: { ...settings, ...(user?.TEMPLATE?.FIREEDGE ?? {}) },
+ isLogged:
+ !!jwt &&
+ !!user &&
+ !!authGroups?.length &&
+ !isLoginInProgress &&
+ waitViewToLogin,
+ }),
+ [user, jwt, isLoginInProgress, authGroups, auth, waitViewToLogin]
)
-
- return {
- ...auth,
- groups: userGroups,
- isLogged,
- getResourceView,
- views,
- }
}
export const useAuthApi = () => {
const dispatch = useDispatch()
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
return {
- login: (user) => unwrapDispatch(actions.login(user)),
- getAuthUser: () => dispatch(actions.getUser()),
- changeGroup: (group) => unwrapDispatch(actions.changeGroup(group)),
+ stopFirstRender: () => dispatch(actions.stopFirstRender()),
logout: () => dispatch(actions.logout()),
-
changeView: (view) => dispatch(actions.changeView(view)),
+ changeJwt: (jwt) => dispatch(actions.changeJwt(jwt)),
}
}
+
+// --------------------------------------------------------------
+// View Hooks
+// --------------------------------------------------------------
+
+export const useViews = () => {
+ const { jwt, view } = useSelector((state) => state[authSlice], shallowEqual)
+
+ const { data: views } = systemApi.endpoints.getSunstoneViews.useQueryState(
+ undefined,
+ { skip: !jwt }
+ )
+
+ /**
+ * Looking for resource view of user authenticated.
+ *
+ * @param {RESOURCE_NAMES} resourceName - Name of resource
+ * @returns {ResourceView} Returns view of resource
+ */
+ const getResourceView = useCallback(
+ (resourceName) =>
+ views?.[view]?.find(
+ ({ resource_name: name }) =>
+ `${name}`.toLowerCase() === `${resourceName}`.toLowerCase()
+ ),
+ [view]
+ )
+
+ return useMemo(() => ({ getResourceView, views, view }), [views, view])
+}
diff --git a/src/fireedge/src/client/features/Auth/slice.js b/src/fireedge/src/client/features/Auth/slice.js
index a1689d8e20..63a375dea4 100644
--- a/src/fireedge/src/client/features/Auth/slice.js
+++ b/src/fireedge/src/client/features/Auth/slice.js
@@ -13,82 +13,65 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { createSlice } from '@reduxjs/toolkit'
+import { createAction, createSlice } from '@reduxjs/toolkit'
-import {
- login,
- getUser,
- logout,
- changeFilter,
- changeGroup,
- changeView,
-} from 'client/features/Auth/actions'
+import { removeStoreData } from 'client/utils'
import {
JWT_NAME,
FILTER_POOL,
DEFAULT_SCHEME,
DEFAULT_LANGUAGE,
} from 'client/constants'
-import { isBackend } from 'client/utils'
+
+export const logout = createAction('logout')
const initial = () => ({
- jwt: !isBackend()
- ? window.localStorage.getItem(JWT_NAME) ??
- window.sessionStorage.getItem(JWT_NAME) ??
- null
- : null,
+ jwt: null,
user: null,
- error: null,
filterPool: FILTER_POOL.ALL_RESOURCES,
settings: {
- scheme: DEFAULT_SCHEME,
- lang: DEFAULT_LANGUAGE,
- disableanimations: 'NO',
+ SCHEME: DEFAULT_SCHEME,
+ LANG: DEFAULT_LANGUAGE,
+ DISABLE_ANIMATIONS: 'NO',
},
isLoginInProgress: false,
- isLoading: false,
})
-const { name, actions, reducer } = createSlice({
+const slice = createSlice({
name: 'auth',
initialState: { ...initial(), firstRender: true },
+ reducers: {
+ changeAuthUser: (state, { payload }) => ({
+ ...state,
+ ...payload,
+ }),
+ changeJwt: (state, { payload }) => {
+ state.jwt = payload
+ },
+ changeSettings: (state, { payload }) => {
+ state.settings = { ...state.settings, payload }
+ },
+ changeFilterPool: (state, { payload: filterPool }) => {
+ state.filterPool = filterPool
+ state.isLoginInProgress = false
+ },
+ changeView: (state, { payload }) => {
+ state.view = payload
+ },
+ stopFirstRender: (state) => {
+ state.firstRender = false
+ },
+ },
extraReducers: (builder) => {
- builder
- .addMatcher(
- ({ type }) => type === logout.type,
- (_, { error }) => ({ ...initial(), error })
- )
- .addMatcher(
- ({ type }) =>
- [
- changeFilter.type,
- login.fulfilled.type,
- getUser.fulfilled.type,
- changeGroup.fulfilled.type,
- changeView.type,
- ].includes(type),
- (state, { payload }) => ({ ...state, ...payload })
- )
- .addMatcher(
- ({ type }) => type.startsWith('auth/') && type.endsWith('/pending'),
- (state) => ({ ...state, isLoading: true, error: null })
- )
- .addMatcher(
- ({ type }) => type.startsWith('auth/') && type.endsWith('/fulfilled'),
- (state) => ({ ...state, isLoading: false, firstRender: false })
- )
- .addMatcher(
- ({ type }) => type.startsWith('auth/') && type.endsWith('/rejected'),
- (state, { payload }) => ({
- ...state,
- ...payload,
- isLoginInProgress: false,
- isLoading: false,
- firstRender: false,
- jwt: null,
- })
- )
+ builder.addCase(logout, (_, { payload }) => {
+ removeStoreData([JWT_NAME])
+
+ return { ...initial(), error: payload }
+ })
},
})
-export { name, actions, reducer }
+export const { name, reducer } = slice
+
+const actions = { ...slice.actions, logout }
+export { actions }
diff --git a/src/fireedge/src/client/features/AuthApi/index.js b/src/fireedge/src/client/features/AuthApi/index.js
new file mode 100644
index 0000000000..61d59013a5
--- /dev/null
+++ b/src/fireedge/src/client/features/AuthApi/index.js
@@ -0,0 +1,131 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may *
+ * not use this file except in compliance with the License. You may obtain *
+ * a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ * ------------------------------------------------------------------------- */
+import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
+
+import { dismissSnackbar } from 'client/features/General/actions'
+import { actions } from 'client/features/Auth/slice'
+import userApi from 'client/features/OneApi/user'
+
+import { storage } from 'client/utils'
+import { APP_URL, JWT_NAME, FILTER_POOL, ONEADMIN_ID } from 'client/constants'
+
+const { ALL_RESOURCES, PRIMARY_GROUP_RESOURCES } = FILTER_POOL
+
+const authApi = createApi({
+ reducerPath: 'authApi',
+ baseQuery: fetchBaseQuery({
+ baseUrl: `${APP_URL}/api/`,
+ prepareHeaders: (headers, { getState }) => {
+ const token = getState().auth.jwt
+
+ // If we have a token set in state,
+ // let's assume that we should be passing it.
+ token && headers.set('authorization', `Bearer ${token}`)
+
+ return headers
+ },
+ }),
+ endpoints: (builder) => ({
+ getAuthUser: builder.query({
+ /**
+ * @returns {object} Information about authenticated user
+ * @throws Fails when response isn't code 200
+ */
+ query: () => ({ url: 'user/info' }),
+ transformResponse: (response) => response?.data?.USER,
+ async onQueryStarted(_, { queryFulfilled, dispatch }) {
+ try {
+ const { data: user } = await queryFulfilled
+ dispatch(actions.changeAuthUser({ user }))
+ } catch {}
+ },
+ }),
+ login: builder.mutation({
+ /**
+ * @param {object} data - User credentials
+ * @param {string} data.user - Username
+ * @param {string} data.token - Password
+ * @param {boolean} [data.remember] - Remember session
+ * @param {string} [data.token2fa] - Token for Two factor authentication
+ * @returns {object} Response data from request
+ * @throws Fails when response isn't code 200
+ */
+ query: (data) => ({ url: 'auth', method: 'POST', body: data }),
+ transformResponse: (response) => {
+ const { id, token } = response?.data
+ const isOneAdmin = id === ONEADMIN_ID
+
+ return {
+ jwt: token,
+ user: { ID: id },
+ isLoginInProgress: !!token && !isOneAdmin,
+ }
+ },
+ async onQueryStarted({ remember }, { queryFulfilled, dispatch }) {
+ try {
+ const { data: queryData } = await queryFulfilled
+
+ if (queryData?.jwt) {
+ storage(JWT_NAME, queryData?.jwt, remember)
+ dispatch(dismissSnackbar({ dismissAll: true }))
+ }
+
+ dispatch(actions.changeAuthUser(queryData))
+ } catch {}
+ },
+ }),
+ changeAuthGroup: builder.mutation({
+ /**
+ * @param {object} data - User credentials
+ * @param {string} data.group - Group id
+ * @returns {Promise} Response data from request
+ * @throws Fails when response isn't code 200
+ */
+ queryFn: async ({ group } = {}, { getState, dispatch }) => {
+ try {
+ if (group === ALL_RESOURCES) {
+ dispatch(actions.changeFilterPool(ALL_RESOURCES))
+
+ return { data: '' }
+ }
+
+ const authUser = getState().auth.user
+ const queryData = { id: authUser.ID, group: group }
+
+ const response = await dispatch(
+ userApi.endpoints.changeGroup.initiate(queryData)
+ ).unwrap()
+
+ dispatch(actions.changeFilterPool(PRIMARY_GROUP_RESOURCES))
+
+ return { data: response }
+ } catch (error) {
+ return { error }
+ }
+ },
+ }),
+ }),
+})
+
+export const {
+ useGetAuthUserQuery,
+ useLazyGetAuthUserQuery,
+
+ useLoginMutation,
+ useChangeAuthGroupMutation,
+} = authApi
+
+export { authApi }
diff --git a/src/fireedge/src/client/features/General/slice.js b/src/fireedge/src/client/features/General/slice.js
index 90aaf88b57..f9c20023bb 100644
--- a/src/fireedge/src/client/features/General/slice.js
+++ b/src/fireedge/src/client/features/General/slice.js
@@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
import { createSlice } from '@reduxjs/toolkit'
-import { logout } from 'client/features/Auth/actions'
+import { actions as authActions } from 'client/features/Auth/slice'
import * as actions from 'client/features/General/actions'
import { generateKey } from 'client/utils'
import { APPS_IN_BETA } from 'client/constants'
@@ -36,6 +36,13 @@ const { name, reducer } = createSlice({
initialState: initial,
extraReducers: (builder) => {
builder
+ /* LOGOUT ACTION */
+ .addCase(authActions.logout, (state) => ({
+ ...initial,
+ appTitle: state.appTitle,
+ isBeta: state.isBeta,
+ }))
+
/* UI ACTIONS */
.addCase(actions.fixMenu, (state, { payload }) => ({
...state,
@@ -92,10 +99,6 @@ const { name, reducer } = createSlice({
})
/* REQUESTS API MATCHES */
- .addMatcher(
- ({ type }) => type === logout.type,
- () => initial
- )
.addMatcher(
({ type }) => type.endsWith('/pending') && !type.includes('auth'),
(state) => ({ ...state, isLoading: true })
diff --git a/src/fireedge/src/client/features/OneApi/index.js b/src/fireedge/src/client/features/OneApi/index.js
index b6f26edda4..5ddaba709c 100644
--- a/src/fireedge/src/client/features/OneApi/index.js
+++ b/src/fireedge/src/client/features/OneApi/index.js
@@ -16,10 +16,8 @@
import { createApi } from '@reduxjs/toolkit/query/react'
import { enqueueSnackbar } from 'client/features/General/actions'
-import { logout } from 'client/features/Auth/actions'
import { httpCodes } from 'server/utils/constants'
import { requestConfig, generateKey } from 'client/utils'
-import { T } from 'client/constants'
import http from 'client/utils/rest'
const ONE_RESOURCES = {
@@ -92,15 +90,14 @@ const oneApi = createApi({
const error = message ?? errorFromOned ?? messageFromServer ?? statusText
- status === httpCodes.unauthorized.id
- ? dispatch(logout(T.SessionExpired))
- : dispatch(
- enqueueSnackbar({
- key: generateKey(),
- message: error,
- options: { variant: 'error' },
- })
- )
+ status !== httpCodes.unauthorized.id &&
+ dispatch(
+ enqueueSnackbar({
+ key: generateKey(),
+ message: error,
+ options: { variant: 'error' },
+ })
+ )
return {
error: {
diff --git a/src/fireedge/src/client/features/OneApi/marketplaceApp.js b/src/fireedge/src/client/features/OneApi/marketplaceApp.js
index 007f134472..31db9d2194 100644
--- a/src/fireedge/src/client/features/OneApi/marketplaceApp.js
+++ b/src/fireedge/src/client/features/OneApi/marketplaceApp.js
@@ -297,7 +297,7 @@ const marketAppApi = oneApi.injectEndpoints({
* @returns {number} Marketplace app id
* @throws Fails when response isn't code 200
*/
- queryFn: async (params) => {
+ query: (params) => {
const name = ExtraActions.MARKETAPP_IMPORT
const command = { name, ...ExtraCommands[name] }
diff --git a/src/fireedge/src/client/features/OneApi/system.js b/src/fireedge/src/client/features/OneApi/system.js
index 39b47657b4..71d99f9b0d 100644
--- a/src/fireedge/src/client/features/OneApi/system.js
+++ b/src/fireedge/src/client/features/OneApi/system.js
@@ -18,7 +18,7 @@ import {
Actions as SunstoneActions,
Commands as SunstoneCommands,
} from 'server/routes/api/sunstone/routes'
-import { changeView } from 'client/features/Auth/actions'
+import { actions } from 'client/features/Auth/slice'
import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
const { SYSTEM } = ONE_RESOURCES
@@ -86,10 +86,12 @@ const systemApi = oneApi.injectEndpoints({
return { command }
},
- async onQueryStarted(_, { dispatch, queryFulfilled }) {
+ async onQueryStarted(_, { dispatch, getState, queryFulfilled }) {
try {
const { data: views = {} } = await queryFulfilled
- dispatch(changeView(Object.keys(views)[0]))
+
+ const currentView = getState().auth?.view
+ !currentView && dispatch(actions.changeView(Object.keys(views)[0]))
} catch {}
},
providesTags: [{ type: SYSTEM, id: 'sunstone-views' }],
diff --git a/src/fireedge/src/client/features/OneApi/user.js b/src/fireedge/src/client/features/OneApi/user.js
index 6e41952fbf..ce3d6bb4a1 100644
--- a/src/fireedge/src/client/features/OneApi/user.js
+++ b/src/fireedge/src/client/features/OneApi/user.js
@@ -192,6 +192,12 @@ const userApi = oneApi.injectEndpoints({
user && (user.GID = group)
})
)
+
+ dispatch(
+ userApi.util.updateQueryData('getUser', id, (draftUser) => {
+ draftUser.GID = group
+ })
+ )
} catch {}
},
}),
diff --git a/src/fireedge/src/client/features/Auth/services.js b/src/fireedge/src/client/features/middleware.js
similarity index 52%
rename from src/fireedge/src/client/features/Auth/services.js
rename to src/fireedge/src/client/features/middleware.js
index 1eed1e62ac..d3b1cb330c 100644
--- a/src/fireedge/src/client/features/Auth/services.js
+++ b/src/fireedge/src/client/features/middleware.js
@@ -13,42 +13,21 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { httpCodes } from 'server/utils/constants'
-import { RestClient } from 'client/utils'
+import { isRejectedWithValue, Middleware, Dispatch } from '@reduxjs/toolkit'
+import { actions } from 'client/features/Auth/slice'
+import { T } from 'client/constants'
-export const authService = {
- /**
- * @param {object} data - User credentials
- * @param {string} data.user - Username
- * @param {string} data.token - Password
- * @param {boolean} [data.remember] - Remember session
- * @param {string} [data.token2fa] - Token for Two factor authentication
- * @returns {object} Response data from request
- * @throws Fails when response isn't code 200
- */
- login: async (data) => {
- const res = await RestClient.request({
- url: '/api/auth',
- data,
- method: 'POST',
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
+/**
+ * @param {{ dispatch: Dispatch }} params - Redux parameters
+ * @returns {Middleware} - Unauthenticated middleware
+ */
+export const unauthenticatedMiddleware =
+ ({ dispatch }) =>
+ (next) =>
+ (action) => {
+ if (isRejectedWithValue(action) && action.payload.status === 401) {
+ dispatch(actions.logout(T.SessionExpired))
}
- return res?.data
- },
- /**
- * @returns {object} Information about user authenticated
- * @throws Fails when response isn't code 200
- */
- getUser: async () => {
- const res = await RestClient.request({ url: '/api/user/info' })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.USER ?? {}
- },
-}
+ return next(action)
+ }
diff --git a/src/fireedge/src/client/providers/muiProvider.js b/src/fireedge/src/client/providers/muiProvider.js
index 233a94215c..a05bfc49c0 100644
--- a/src/fireedge/src/client/providers/muiProvider.js
+++ b/src/fireedge/src/client/providers/muiProvider.js
@@ -34,12 +34,12 @@ import { SCHEMES } from 'client/constants'
const { DARK, LIGHT, SYSTEM } = SCHEMES
const MuiProvider = ({ theme: appTheme, children }) => {
- const { settings: { scheme } = {} } = useAuth()
+ const { settings: { SCHEME } = {} } = useAuth()
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)')
const changeScheme = () => {
const prefersScheme = prefersDarkMode ? DARK : LIGHT
- const newScheme = scheme === SYSTEM ? prefersScheme : scheme
+ const newScheme = SCHEME === SYSTEM ? prefersScheme : SCHEME
return createTheme(appTheme, newScheme)
}
@@ -55,7 +55,7 @@ const MuiProvider = ({ theme: appTheme, children }) => {
useEffect(() => {
setTheme(changeScheme)
- }, [scheme, prefersDarkMode])
+ }, [SCHEME, prefersDarkMode])
return (
diff --git a/src/fireedge/src/client/store/index.js b/src/fireedge/src/client/store/index.js
index 0b64f7f8da..decb2bae74 100644
--- a/src/fireedge/src/client/store/index.js
+++ b/src/fireedge/src/client/store/index.js
@@ -20,7 +20,9 @@ import { isDevelopment } from 'client/utils'
import * as Auth from 'client/features/Auth/slice'
import * as General from 'client/features/General/slice'
+import { authApi } from 'client/features/AuthApi'
import { oneApi } from 'client/features/OneApi'
+import { unauthenticatedMiddleware } from 'client/features/middleware'
/**
* @param {object} props - Props
@@ -32,13 +34,18 @@ export const createStore = ({ initState = {} }) => {
reducer: {
[Auth.name]: Auth.reducer,
[General.name]: General.reducer,
+ [authApi.reducerPath]: authApi.reducer,
[oneApi.reducerPath]: oneApi.reducer,
},
devTools: isDevelopment(),
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: true,
- }).concat(oneApi.middleware),
+ }).concat([
+ unauthenticatedMiddleware,
+ authApi.middleware,
+ oneApi.middleware,
+ ]),
preloadedState: initState,
})
diff --git a/src/fireedge/src/client/store/reducers.js b/src/fireedge/src/client/store/reducers.js
index a2c46410f9..742a8b2165 100644
--- a/src/fireedge/src/client/store/reducers.js
+++ b/src/fireedge/src/client/store/reducers.js
@@ -13,14 +13,16 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-const { combineReducers } = require('redux')
+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,
})
diff --git a/src/fireedge/src/client/theme/defaults.js b/src/fireedge/src/client/theme/defaults.js
index a648bbfae5..7c22fda1f0 100644
--- a/src/fireedge/src/client/theme/defaults.js
+++ b/src/fireedge/src/client/theme/defaults.js
@@ -71,7 +71,7 @@ const buttonSvgStyle = {
*/
export default (appTheme, mode = SCHEMES.DARK) => {
const { primary, secondary } = appTheme.palette
- const isDarkMode = mode === SCHEMES.DARK
+ const isDarkMode = `${mode}`.toLowerCase() === SCHEMES.DARK
return {
palette: {
@@ -237,6 +237,16 @@ export default (appTheme, mode = SCHEMES.DARK) => {
MuiCssBaseline: {
styleOverrides: {
'@font-face': UbuntuFont,
+ '.loading_screen': {
+ width: '100%',
+ height: '100vh',
+ backgroundColor: 'background.default',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ position: 'fixed',
+ zIndex: 10000,
+ },
'.description__link': {
margin: 0,
color: isDarkMode ? secondary.main : secondary.dark,