diff --git a/src/fireedge/etc/sunstone/admin/vm-tab.yaml b/src/fireedge/etc/sunstone/admin/vm-tab.yaml index d337d1fa9c..55e1fd4892 100644 --- a/src/fireedge/etc/sunstone/admin/vm-tab.yaml +++ b/src/fireedge/etc/sunstone/admin/vm-tab.yaml @@ -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 diff --git a/src/fireedge/src/client/components/Header/Popover.js b/src/fireedge/src/client/components/Header/Popover.js index 651f16855e..6e56a35b97 100644 --- a/src/fireedge/src/client/components/Header/Popover.js +++ b/src/fireedge/src/client/components/Header/Popover.js @@ -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 = ({ ) -} +}) HeaderPopover.propTypes = { id: PropTypes.string, @@ -115,4 +115,6 @@ HeaderPopover.defaultProps = { children: () => undefined } +HeaderPopover.displayName = 'HeaderPopover' + export default HeaderPopover diff --git a/src/fireedge/src/client/components/Search/index.js b/src/fireedge/src/client/components/Search/index.js index fb4c8beab6..3779d76570 100644 --- a/src/fireedge/src/client/components/Search/index.js +++ b/src/fireedge/src/client/components/Search/index.js @@ -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, diff --git a/src/fireedge/src/client/components/Tables/Enhanced/Utils/CategoryFilter.js b/src/fireedge/src/client/components/Tables/Enhanced/Utils/CategoryFilter.js index 6138e165c8..b9913b13e1 100644 --- a/src/fireedge/src/client/components/Tables/Enhanced/Utils/CategoryFilter.js +++ b/src/fireedge/src/client/components/Tables/Enhanced/Utils/CategoryFilter.js @@ -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) diff --git a/src/fireedge/src/client/components/Tables/Enhanced/Utils/index.js b/src/fireedge/src/client/components/Tables/Enhanced/Utils/index.js new file mode 100644 index 0000000000..66e21a022e --- /dev/null +++ b/src/fireedge/src/client/components/Tables/Enhanced/Utils/index.js @@ -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 +} diff --git a/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js b/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js new file mode 100644 index 0000000000..8f31815d0c --- /dev/null +++ b/src/fireedge/src/client/components/Tables/Enhanced/Utils/utils.js @@ -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' +}) diff --git a/src/fireedge/src/client/components/Tables/Enhanced/index.js b/src/fireedge/src/client/components/Tables/Enhanced/index.js index b0ab598b71..304334c1e7 100644 --- a/src/fireedge/src/client/components/Tables/Enhanced/index.js +++ b/src/fireedge/src/client/components/Tables/Enhanced/index.js @@ -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 && ( - {Tr(T.NoDataAvailable)} + )} diff --git a/src/fireedge/src/client/components/Tables/Vms/columns.js b/src/fireedge/src/client/components/Tables/Vms/columns.js index b24ee0d20d..ebfba87c04 100644 --- a/src/fireedge/src/client/components/Tables/Vms/columns.js +++ b/src/fireedge/src/client/components/Tables/Vms/columns.js @@ -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' }, diff --git a/src/fireedge/src/client/components/Tables/Vms/index.js b/src/fireedge/src/client/components/Tables/Vms/index.js index 297aaf9fd0..38425446f7 100644 --- a/src/fireedge/src/client/components/Tables/Vms/index.js +++ b/src/fireedge/src/client/components/Tables/Vms/index.js @@ -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 diff --git a/src/fireedge/src/client/features/Auth/actions.js b/src/fireedge/src/client/features/Auth/actions.js index 1f6fe8cc3e..265e7d5d44 100644 --- a/src/fireedge/src/client/features/Auth/actions.js +++ b/src/fireedge/src/client/features/Auth/actions.js @@ -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 } diff --git a/src/fireedge/src/client/features/Auth/hooks.js b/src/fireedge/src/client/features/Auth/hooks.js index cf27917d2e..22c7550fbb 100644 --- a/src/fireedge/src/client/features/Auth/hooks.js +++ b/src/fireedge/src/client/features/Auth/hooks.js @@ -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)) } }