1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-25 23:21:29 +03:00

F #5422: Optimise group and view switches (#1509)

This commit is contained in:
Sergio Betanzos 2021-10-07 15:52:23 +02:00 committed by GitHub
parent 33bf5e1f4c
commit 6f6d0fb55f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 106 additions and 58 deletions

View File

@ -86,10 +86,6 @@ const ButtonToTriggerForm = ({
onClose={handleClose}
TransitionComponent={Grow}
sx={{ zIndex: 2 }}
MenuListProps={{
dense: true,
disablePadding: true
}}
>
{options.map(({ cy, disabled, icon: Icon, name, ...option }) => (
<MenuItem

View File

@ -14,59 +14,68 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
import { useMemo, memo } from 'react'
import PropTypes from 'prop-types'
import { Button } from '@mui/material'
import { Group as GroupIcon, 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 { Translate } from 'client/components/HOC'
import { Tr, Translate } from 'client/components/HOC'
import { T, FILTER_POOL } from 'client/constants'
const { ALL_RESOURCES, PRIMARY_GROUP_RESOURCES } = FILTER_POOL
const Group = () => {
const { user, groups, filterPool } = useAuth()
const ButtonGroup = memo(({ group, handleClick }) => {
const { changeGroup } = useAuthApi()
const { user, filterPool } = useAuth()
const renderResult = ({ ID, NAME }, handleClose) => {
const isSelected =
const { ID, NAME } = group
const isSelected =
(filterPool === ALL_RESOURCES && ALL_RESOURCES === ID) ||
(filterPool === PRIMARY_GROUP_RESOURCES && user?.GID === ID)
return (
<Button
key={`switcher-group-${ID}`}
fullWidth
tooltip={<Translate Word={T.Group} />}
onClick={() => {
ID && changeGroup({ id: user.ID, group: ID })
handleClose()
}}
sx={{
color: theme => theme.palette.text.primary,
justifyContent: 'start',
'& svg:first-of-type': { my: 0, mx: 2 }
}}
>
{NAME}
{isSelected && <SelectIcon />}
</Button>
)
}
return (
<Button
key={`switcher-group-${ID}`}
fullWidth
color='debug'
variant='outlined'
tooltip={<Translate Word={T.Group} />}
onClick={() => {
ID && changeGroup({ id: user.ID, group: ID })
handleClick()
}}
sx={{
color: theme => theme.palette.text.primary,
justifyContent: 'start',
'& svg:first-of-type': { my: 0, mx: 2 }
}}
>
{NAME}
{isSelected && <SelectIcon />}
</Button>
)
}, (prev, next) => prev.group.ID === next.group.ID)
const Group = () => {
const { user, groups } = useAuth()
const sortGroupAsMainFirst = (a, b) => {
if (a.ID === user?.GUID) {
return -1
} else if (b.ID === user?.GUID) {
return 1
}
return 0
return a.ID === user?.GUID
? -1
: b.ID === user?.GUID ? 1 : 0
}
const sortMainGroupFirst = groups
?.concat({ ID: ALL_RESOURCES, NAME: 'Show All' })
?.sort(sortGroupAsMainFirst)
const sortMainGroupFirst = useMemo(
() => [{ ID: ALL_RESOURCES, NAME: Tr(T.ShowAll) }]
?.concat(groups)
?.sort(sortGroupAsMainFirst),
[user?.GUID]
)
return (
<HeaderPopover
@ -85,11 +94,26 @@ const Group = () => {
keys: ['NAME']
}}
maxResults={5}
renderResult={group => renderResult(group, handleClose)}
renderResult={group => (
<ButtonGroup
group={group}
handleClick={handleClose}
/>
)}
/>
)}
</HeaderPopover>
)
}
ButtonGroup.propTypes = {
group: PropTypes.shape({
ID: PropTypes.string,
NAME: PropTypes.string
}).isRequired,
handleClick: PropTypes.func
}
ButtonGroup.displayName = 'ButtonGroup'
export default Group

View File

@ -21,7 +21,7 @@ import { ProfileCircled as UserIcon } from 'iconoir-react'
import { useAuth, useAuthApi } from 'client/features/Auth'
import HeaderPopover from 'client/components/Header/Popover'
import { DevTypography } from 'client/components/Typography'
import { Tr } from 'client/components/HOC'
import { Translate } from 'client/components/HOC'
import { isDevelopment } from 'client/utils'
import { T, APPS, APP_URL } from 'client/constants'
@ -38,13 +38,13 @@ const User = memo(() => {
disablePadding
>
{() => (
<MenuList disablePadding>
<MenuItem onClick={logout} data-cy='header-logout-button'>
{Tr(T.SignOut)}
<MenuList>
<MenuItem onClick={logout} disableRipple data-cy='header-logout-button'>
<Translate word={T.SignOut} />
</MenuItem>
{isDevelopment() &&
APPS?.map(appName => (
<MenuItem key={appName}>
<MenuItem key={appName} disableRipple>
<Link
width='100%'
color='secondary'

View File

@ -14,7 +14,8 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
import { useMemo } from 'react'
import { useMemo, memo } from 'react'
import PropTypes from 'prop-types'
import { Button } from '@mui/material'
import { ViewGrid as ViewIcon, VerifiedBadge as SelectIcon } from 'iconoir-react'
@ -25,17 +26,20 @@ import HeaderPopover from 'client/components/Header/Popover'
import { Translate } from 'client/components/HOC'
import { T } from 'client/constants'
const View = () => {
const { view, views = {} } = useAuth()
const ButtonView = memo(({ view, handleClick }) => {
const { changeView } = useAuthApi()
const { view: currentView } = useAuth()
const isCurrentView = currentView === view
const renderResult = (newView, handleClose) => (
return (
<Button
key={`view-${newView}`}
key={`view-${view}`}
fullWidth
color='debug'
variant='outlined'
onClick={() => {
newView && newView !== view && changeView(newView)
handleClose()
view && !isCurrentView && changeView(view)
handleClick()
}}
sx={{
color: theme => theme.palette.text.primary,
@ -43,12 +47,22 @@ const View = () => {
'& svg:first-of-type': { my: 0, mx: 2 }
}}
>
{newView}
{newView === view && <SelectIcon size='1em' />}
{view}
{isCurrentView && <SelectIcon />}
</Button>
)
}, (prev, next) => prev.view === next.view)
const viewNames = useMemo(() => Object.keys(views), [view])
ButtonView.propTypes = {
view: PropTypes.string.isRequired,
handleClick: PropTypes.func
}
ButtonView.displayName = 'ButtonView'
const View = () => {
const { view: currentView, views = {} } = useAuth()
const viewNames = useMemo(() => Object.keys(views), [currentView])
return (
<HeaderPopover
@ -62,7 +76,12 @@ const View = () => {
<Search
list={viewNames}
maxResults={5}
renderResult={item => renderResult(item, handleClose)}
renderResult={view => (
<ButtonView
view={view}
handleClick={handleClose}
/>
)}
/>
)}
</HeaderPopover>

View File

@ -33,7 +33,7 @@ const Zone = memo(() => (
disablePadding
>
{({ handleClose }) => (
<MenuList disablePadding>
<MenuList>
<MenuItem onClick={handleClose}>
<Translate word={T.Zone} />
</MenuItem>

View File

@ -95,7 +95,7 @@ const GlobalSort = ({ useTableProps }) => {
}}
>
{() => (
<MenuList disablePadding>
<MenuList>
{headersNotSorted.length
? headersNotSorted?.map(({ id, Header: name }) => (
<MenuItem key={id} onClick={() => { handleClick(id, name) }}>

View File

@ -704,7 +704,10 @@ export const VM_ACTIONS_WITH_SCHEDULE = [
VM_ACTIONS.SNAPSHOT_DISK_DELETE,
VM_ACTIONS.SNAPSHOT_CREATE,
VM_ACTIONS.SNAPSHOT_REVERT,
VM_ACTIONS.SNAPSHOT_DELETE
VM_ACTIONS.SNAPSHOT_DELETE,
// Actions exists in scheduler only
'delete',
'delete-recreate'
]
/**

View File

@ -371,6 +371,12 @@ export default (appTheme, mode = SCHEMES.DARK) => {
}
}
}
},
MuiList: {
defaultProps: {
dense: true,
disablePadding: true
}
}
}
}