diff --git a/src/fireedge/src/client/apps/sunstone/_app.js b/src/fireedge/src/client/apps/sunstone/_app.js
index 7b8948d326..cdc73aff7a 100644
--- a/src/fireedge/src/client/apps/sunstone/_app.js
+++ b/src/fireedge/src/client/apps/sunstone/_app.js
@@ -28,14 +28,17 @@ const APP_NAME = _APPS.sunstone.name
const SunstoneApp = () => {
const { isLogged, jwt, firstRender } = useAuth()
- const { getAuthUser, logout } = useAuthApi()
+ const { getAuthUser, logout, getSunstoneViews } = useAuthApi()
const { changeTitle } = useGeneralApi()
React.useEffect(() => {
(async () => {
try {
- jwt && changeTitle(APP_NAME)
- jwt && getAuthUser()
+ if (jwt) {
+ changeTitle(APP_NAME)
+ getAuthUser()
+ getSunstoneViews()
+ }
} catch {
logout()
}
diff --git a/src/fireedge/src/client/components/Header/View.js b/src/fireedge/src/client/components/Header/View.js
new file mode 100644
index 0000000000..854ae848f1
--- /dev/null
+++ b/src/fireedge/src/client/components/Header/View.js
@@ -0,0 +1,56 @@
+import * as React from 'react'
+
+import { Button } from '@material-ui/core'
+import { ViewGrid as ViewIcon, VerifiedBadge as SelectIcon } from 'iconoir-react'
+
+import { useAuth, useAuthApi } from 'client/features/Auth'
+import Search from 'client/components/Search'
+
+import HeaderPopover from 'client/components/Header/Popover'
+import headerStyles from 'client/components/Header/styles'
+
+const View = () => {
+ const classes = headerStyles()
+ const { view, views } = useAuth()
+ const { changeView } = useAuthApi()
+
+ const handleChangeView = newView => {
+ newView && newView !== view && changeView(newView)
+ }
+
+ const renderResult = (viewName, handleClose) => (
+
+ )
+
+ const viewNames = React.useMemo(() => Object.keys(views), [view])
+
+ return (
+ }
+ buttonProps={{ 'data-cy': 'header-view-button', variant: 'outlined' }}
+ headerTitle='Switch view'
+ >
+ {({ handleClose }) => (
+ renderResult(item, handleClose)}
+ />
+ )}
+
+ )
+}
+
+export default View
diff --git a/src/fireedge/src/client/components/Header/index.js b/src/fireedge/src/client/components/Header/index.js
index baead97c8a..f443247c0a 100644
--- a/src/fireedge/src/client/components/Header/index.js
+++ b/src/fireedge/src/client/components/Header/index.js
@@ -31,6 +31,7 @@ import { useAuth } from 'client/features/Auth'
import { useGeneral, useGeneralApi } from 'client/features/General'
import User from 'client/components/Header/User'
+import View from 'client/components/Header/View'
import Group from 'client/components/Header/Group'
import Zone from 'client/components/Header/Zone'
import headerStyles from 'client/components/Header/styles'
@@ -75,6 +76,7 @@ const Header = ({ scrollContainer }) => {
)}
+
{!isOneAdmin && }
diff --git a/src/fireedge/src/client/features/Auth/actionsView.js b/src/fireedge/src/client/features/Auth/actionsView.js
new file mode 100644
index 0000000000..8c8bf2e949
--- /dev/null
+++ b/src/fireedge/src/client/features/Auth/actionsView.js
@@ -0,0 +1,29 @@
+import { createAsyncThunk, createAction } from '@reduxjs/toolkit'
+
+import { authService } from 'client/features/Auth/services'
+import { logout } from 'client/features/Auth/actions'
+
+import { httpCodes } from 'server/utils/constants'
+import { T } from 'client/constants'
+
+export const getSunstoneViews = createAsyncThunk(
+ 'sunstone/views',
+ async (_, { dispatch }) => {
+ try {
+ const views = await authService.getSunstoneViews() ?? {}
+ // const config = await authService.getSunstoneConfig()
+
+ return {
+ views,
+ view: Object.keys(views)[0]
+ }
+ } catch (error) {
+ status === httpCodes.unauthorized.id && dispatch(logout(T.SessionExpired))
+ }
+ }
+)
+
+export const changeView = createAction(
+ 'sunstone/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 e102edc5d9..cf27917d2e 100644
--- a/src/fireedge/src/client/features/Auth/hooks.js
+++ b/src/fireedge/src/client/features/Auth/hooks.js
@@ -3,6 +3,7 @@ import { useDispatch, useSelector, shallowEqual } from 'react-redux'
import { unwrapResult } from '@reduxjs/toolkit'
import * as actions from 'client/features/Auth/actions'
+import * as actionsView from 'client/features/Auth/actionsView'
export const useAuth = () => {
const auth = useSelector(state => state.auth, shallowEqual)
@@ -32,6 +33,9 @@ export const useAuthApi = () => {
login: user => unwrapDispatch(actions.login(user)),
getAuthUser: () => dispatch(actions.getUser()),
changeGroup: data => unwrapDispatch(actions.changeGroup(data)),
- logout: () => dispatch(actions.logout())
+ logout: () => dispatch(actions.logout()),
+
+ getSunstoneViews: () => unwrapDispatch(actionsView.getSunstoneViews()),
+ changeView: data => unwrapDispatch(actionsView.changeView(data))
}
}
diff --git a/src/fireedge/src/client/features/Auth/services.js b/src/fireedge/src/client/features/Auth/services.js
index c17500afcf..6abfe75428 100644
--- a/src/fireedge/src/client/features/Auth/services.js
+++ b/src/fireedge/src/client/features/Auth/services.js
@@ -14,5 +14,15 @@ export const authService = ({
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
return res?.data?.USER ?? {}
+ }),
+ getSunstoneViews: () => RestClient.get('/api/sunstone/views').then(res => {
+ if (!res?.id || res?.id !== httpCodes.ok.id) throw res
+
+ return res?.data ?? {}
+ }),
+ getSunstoneConfig: () => RestClient.get('/api/user/config').then(res => {
+ if (!res?.id || res?.id !== httpCodes.ok.id) throw res
+
+ return res?.data ?? {}
})
})
diff --git a/src/fireedge/src/client/features/Auth/slice.js b/src/fireedge/src/client/features/Auth/slice.js
index facd4ed3a3..8c9300b697 100644
--- a/src/fireedge/src/client/features/Auth/slice.js
+++ b/src/fireedge/src/client/features/Auth/slice.js
@@ -1,6 +1,7 @@
import { createSlice } from '@reduxjs/toolkit'
import { login, getUser, logout, changeFilter, changeGroup } from 'client/features/Auth/actions'
+import { getSunstoneViews, changeView } from 'client/features/Auth/actionsView'
import { JWT_NAME, FILTER_POOL, DEFAULT_SCHEME, DEFAULT_LANGUAGE } from 'client/constants'
import { isBackend } from 'client/utils'
@@ -38,7 +39,10 @@ const { actions, reducer } = createSlice({
changeFilter.type,
login.fulfilled.type,
getUser.fulfilled.type,
- changeGroup.fulfilled.type
+ changeGroup.fulfilled.type,
+ // sunstone views
+ getSunstoneViews.fulfilled.type,
+ changeView.type
].includes(type)
},
(state, { payload }) => ({ ...state, ...payload })