mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
F OpenNebula/one#5422: Add view condition to vms dt
This commit is contained in:
parent
b578aa0b2e
commit
7fe4b8cbd7
@ -80,8 +80,8 @@ actions:
|
||||
# Filters - List of criteria to filter the resources
|
||||
|
||||
filters:
|
||||
labels: true
|
||||
states: true
|
||||
label: true
|
||||
state: true
|
||||
|
||||
|
||||
# Info Tabs - Which info tabs are used to show extended information
|
||||
|
@ -15,7 +15,7 @@ import clsx from 'clsx'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import headerStyles from 'client/components/Header/styles'
|
||||
|
||||
const HeaderPopover = ({
|
||||
const HeaderPopover = React.memo(({
|
||||
id,
|
||||
icon,
|
||||
buttonLabel,
|
||||
@ -91,7 +91,7 @@ const HeaderPopover = ({
|
||||
</Popover>
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
HeaderPopover.propTypes = {
|
||||
id: PropTypes.string,
|
||||
@ -115,4 +115,6 @@ HeaderPopover.defaultProps = {
|
||||
children: () => undefined
|
||||
}
|
||||
|
||||
HeaderPopover.displayName = 'HeaderPopover'
|
||||
|
||||
export default HeaderPopover
|
||||
|
@ -36,7 +36,12 @@ const Search = ({
|
||||
}
|
||||
|
||||
Search.propTypes = {
|
||||
list: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
list: PropTypes.arrayOf(
|
||||
PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.string
|
||||
])
|
||||
).isRequired,
|
||||
listOptions: PropTypes.shape({
|
||||
isCaseSensitive: PropTypes.bool,
|
||||
shouldSort: PropTypes.bool,
|
||||
|
@ -15,7 +15,7 @@ const CategoryFilter = ({ title, column, accessorOption, multiple }) => {
|
||||
filterValue = multiple ? [] : undefined
|
||||
} = column
|
||||
|
||||
React.useEffect(() => () => setFilter(multiple ? [] : undefined), [])
|
||||
React.useEffect(() => () => setFilter(undefined), [])
|
||||
|
||||
// Calculate the options for filtering using the preFilteredRows
|
||||
const options = React.useMemo(() => {
|
||||
@ -33,13 +33,13 @@ const CategoryFilter = ({ title, column, accessorOption, multiple }) => {
|
||||
return options
|
||||
}, [id, preFilteredRows])
|
||||
|
||||
const handleSelect = value => setFilter(
|
||||
multiple ? [...filterValue, value] : value
|
||||
)
|
||||
const handleSelect = value => {
|
||||
setFilter(multiple ? [...filterValue, value] : value)
|
||||
}
|
||||
|
||||
const handleUnselect = value => setFilter(
|
||||
multiple ? filterValue.filter(v => v !== value) : undefined
|
||||
)
|
||||
const handleUnselect = value => {
|
||||
setFilter(multiple ? filterValue.filter(v => v !== value) : undefined)
|
||||
}
|
||||
|
||||
const handleClear = () => setFilter(multiple ? [] : undefined)
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
import CategoryFilter from 'client/components/Tables/Enhanced/Utils/CategoryFilter'
|
||||
import GlobalFilter from 'client/components/Tables/Enhanced/Utils/GlobalFilter'
|
||||
import GlobalSort from 'client/components/Tables/Enhanced/Utils/GlobalSort'
|
||||
import LabelFilter from 'client/components/Tables/Enhanced/Utils/LabelFilter'
|
||||
|
||||
export * from 'client/components/Tables/Enhanced/Utils/utils'
|
||||
|
||||
export {
|
||||
CategoryFilter,
|
||||
GlobalFilter,
|
||||
GlobalSort,
|
||||
LabelFilter
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import { CategoryFilter } from 'client/components/Tables/Enhanced/Utils'
|
||||
|
||||
export const createColumns = ({ view, resource, columns }) => {
|
||||
const filters = view
|
||||
?.find(({ resource_name: name }) => name === resource)
|
||||
?.filters ?? {}
|
||||
|
||||
if (Object.keys(filters).length === 0) return columns
|
||||
|
||||
return columns.map(column => {
|
||||
const { Header, id = '', accessor } = column
|
||||
|
||||
const filterById = !!filters[String(id.toLowerCase())]
|
||||
|
||||
const filterByAccessor =
|
||||
typeof accessor === 'string' &&
|
||||
!!filters[String(accessor.toLowerCase())]
|
||||
|
||||
return {
|
||||
...column,
|
||||
...((filterById || filterByAccessor) &&
|
||||
createCategoryFilter(Header)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const createCategoryFilter = title => ({
|
||||
disableFilters: false,
|
||||
Filter: ({ column }) => CategoryFilter({
|
||||
column,
|
||||
multiple: true,
|
||||
title
|
||||
}),
|
||||
filter: 'includesValue'
|
||||
})
|
@ -19,7 +19,7 @@ import Filters from 'client/components/Tables/Enhanced/filters'
|
||||
import DefaultFilter from 'client/components/Table/Filters/DefaultFilter'
|
||||
import EnhancedTableStyles from 'client/components/Tables/Enhanced/styles'
|
||||
|
||||
import { Tr, ConditionalWrap } from 'client/components/HOC'
|
||||
import { Translate, ConditionalWrap } from 'client/components/HOC'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
const EnhancedTable = ({
|
||||
@ -58,6 +58,7 @@ const EnhancedTable = ({
|
||||
sortTypes,
|
||||
getRowId,
|
||||
// When table has update, disable all of the auto resetting
|
||||
autoResetHiddenColumns: false,
|
||||
autoResetExpanded: false,
|
||||
autoResetFilters: false,
|
||||
autoResetGroupBy: false,
|
||||
@ -134,7 +135,7 @@ const EnhancedTable = ({
|
||||
{!isFetching && page?.length === 0 && (
|
||||
<span className={classes.noDataMessage}>
|
||||
<InfoEmpty />
|
||||
{Tr(T.NoDataAvailable)}
|
||||
<Translate word={T.NoDataAvailable} />
|
||||
</span>
|
||||
)}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
import CategoryFilter from 'client/components/Tables/Enhanced/Utils/CategoryFilter'
|
||||
import * as VirtualMachineModel from 'client/models/VirtualMachine'
|
||||
|
||||
export default [
|
||||
@ -7,14 +6,7 @@ export default [
|
||||
{
|
||||
Header: 'State',
|
||||
id: 'STATE',
|
||||
accessor: row => VirtualMachineModel.getState(row)?.name,
|
||||
disableFilters: false,
|
||||
Filter: ({ column }) => CategoryFilter({
|
||||
column,
|
||||
multiple: true,
|
||||
title: 'State'
|
||||
}),
|
||||
filter: 'includesValue'
|
||||
accessor: row => VirtualMachineModel.getState(row)?.name
|
||||
},
|
||||
{ Header: 'Owner', accessor: 'UNAME' },
|
||||
{ Header: 'Group', accessor: 'GNAME' },
|
||||
|
@ -5,6 +5,7 @@ import { useFetch } from 'client/hooks'
|
||||
import { useVm, useVmApi } from 'client/features/One'
|
||||
|
||||
import { SkeletonTable, EnhancedTable } from 'client/components/Tables'
|
||||
import { createColumns } from 'client/components/Tables/Enhanced/Utils'
|
||||
import VmColumns from 'client/components/Tables/Vms/columns'
|
||||
import VmRow from 'client/components/Tables/Vms/row'
|
||||
import VmDetail from 'client/components/Tables/Vms/detail'
|
||||
@ -13,11 +14,15 @@ const INITIAL_ELEMENT = 0
|
||||
const INTERVAL_ON_FIRST_RENDER = 2_000
|
||||
|
||||
const VmsTable = () => {
|
||||
const columns = React.useMemo(() => VmColumns, [])
|
||||
|
||||
const vms = useVm()
|
||||
const { getVms } = useVmApi()
|
||||
const { filterPool } = useAuth()
|
||||
const { view, views, filterPool } = useAuth()
|
||||
|
||||
const columns = React.useMemo(() => createColumns({
|
||||
view: views[view],
|
||||
resource: 'VM',
|
||||
columns: VmColumns
|
||||
}), [view])
|
||||
|
||||
const { status, data, fetchRequest, loading, reloading, error, STATUS } = useFetch(getVms)
|
||||
const { INIT, PENDING } = STATUS
|
||||
|
@ -9,7 +9,7 @@ import { httpCodes } from 'server/utils/constants'
|
||||
import { T, JWT_NAME, ONEADMIN_ID, FILTER_POOL } from 'client/constants'
|
||||
import { storage, removeStoreData } from 'client/utils'
|
||||
|
||||
const login = createAsyncThunk(
|
||||
export const login = createAsyncThunk(
|
||||
'auth/login',
|
||||
async ({ remember, ...user }, { rejectWithValue, dispatch }) => {
|
||||
try {
|
||||
@ -38,7 +38,7 @@ const login = createAsyncThunk(
|
||||
}
|
||||
)
|
||||
|
||||
const getUser = createAsyncThunk(
|
||||
export const getUser = createAsyncThunk(
|
||||
'auth/user',
|
||||
async (_, { dispatch, getState }) => {
|
||||
try {
|
||||
@ -68,18 +68,18 @@ const getUser = createAsyncThunk(
|
||||
}
|
||||
)
|
||||
|
||||
const logout = createAction('logout', errorMessage => {
|
||||
export const logout = createAction('logout', errorMessage => {
|
||||
removeStoreData([JWT_NAME])
|
||||
|
||||
return { error: errorMessage }
|
||||
})
|
||||
|
||||
const changeFilter = createAction(
|
||||
export const changeFilter = createAction(
|
||||
'auth/change-filter',
|
||||
filterPool => ({ payload: { filterPool, isLoginInProgress: false } })
|
||||
)
|
||||
|
||||
const changeGroup = createAsyncThunk(
|
||||
export const changeGroup = createAsyncThunk(
|
||||
'auth/change-group',
|
||||
async ({ group }, { getState, dispatch, rejectWithValue }) => {
|
||||
try {
|
||||
@ -108,5 +108,3 @@ const changeGroup = createAsyncThunk(
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export { login, getUser, logout, changeFilter, changeGroup }
|
||||
|
@ -36,6 +36,6 @@ export const useAuthApi = () => {
|
||||
logout: () => dispatch(actions.logout()),
|
||||
|
||||
getSunstoneViews: () => unwrapDispatch(actionsView.getSunstoneViews()),
|
||||
changeView: data => unwrapDispatch(actionsView.changeView(data))
|
||||
changeView: data => dispatch(actionsView.changeView(data))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user