mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
F OpenNebula/One#6718: Add DataTable rows as lists functionality
This commit is contained in:
parent
cd4bcba0b9
commit
4afac0039c
@ -13,14 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, Component, useState } from 'react'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetAclsExtendedQuery } from 'client/features/OneApi/acl'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import ACLColumns from 'client/components/Tables/ACLs/columns'
|
||||
import ACLRow from 'client/components/Tables/ACLs/row'
|
||||
import { RESOURCE_NAMES, ACL_TABLE_VIEWS } from 'client/constants'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import { ACL_TABLE_VIEWS, RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetAclsExtendedQuery } from 'client/features/OneApi/acl'
|
||||
import { sentenceCase } from 'client/utils'
|
||||
import { Component, useMemo, useState } from 'react'
|
||||
|
||||
const DEFAULT_DATA_CY = 'acls'
|
||||
|
||||
@ -72,23 +73,55 @@ const ACLsTable = (props) => {
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
data && (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
data={data}
|
||||
rootProps={rootProps}
|
||||
searchProps={searchProps}
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={useMemo(() => ACLRow(viewType), [viewType])}
|
||||
singleSelect={singleSelect}
|
||||
tableViews={tableViews}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
)
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{
|
||||
header: T.AppliesTo,
|
||||
id: 'applies',
|
||||
accessor: ({ USER }) =>
|
||||
USER?.type ? sentenceCase(`${USER?.type} ${USER?.name ?? ''}`) : '',
|
||||
},
|
||||
{
|
||||
header: T.AffectedResources,
|
||||
id: 'affected-resources',
|
||||
accessor: ({ RESOURCE }) =>
|
||||
Array.isArray(RESOURCE?.resources)
|
||||
? sentenceCase(RESOURCE.resources.join(', '))
|
||||
: '',
|
||||
},
|
||||
{
|
||||
header: T.AllowedOperations,
|
||||
id: 'allowed-operations',
|
||||
accessor: ({ RIGHTS }) => sentenceCase(RIGHTS?.string || ''),
|
||||
},
|
||||
{
|
||||
header: T.Zone,
|
||||
id: 'zone',
|
||||
accessor: ({ ZONE }) => ZONE?.name || T.All,
|
||||
},
|
||||
]
|
||||
const CardStyle = useMemo(() => ACLRow(viewType), [viewType])
|
||||
const { component, header } = WrapperRow(CardStyle)
|
||||
|
||||
const EnhancedTableProps = {
|
||||
columns,
|
||||
data,
|
||||
rootProps,
|
||||
searchProps,
|
||||
refetch,
|
||||
isLoading: isFetching,
|
||||
getRowId: (row) => String(row.ID),
|
||||
singleSelect,
|
||||
RowComponent: component,
|
||||
headerList: header && listHeader,
|
||||
...rest,
|
||||
}
|
||||
!header && (EnhancedTableProps.tableViews = tableViews)
|
||||
|
||||
return data && <EnhancedTable {...EnhancedTableProps} />
|
||||
}
|
||||
|
||||
ACLsTable.propTypes = { ...EnhancedTable.propTypes }
|
||||
ACLsTable.displayName = 'ACLsTable'
|
||||
|
||||
export default ACLsTable
|
||||
|
@ -13,20 +13,20 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
import {
|
||||
ACLCardCLI,
|
||||
ACLCardIcons,
|
||||
ACLCardNames,
|
||||
ACLCardCLI,
|
||||
ACLCardReadableRule,
|
||||
ACLCardResources,
|
||||
ACLCardRule,
|
||||
ACLCardReadableRule,
|
||||
} from 'client/components/Cards'
|
||||
import { ACL_TABLE_VIEWS } from 'client/constants'
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
const Row = (viewType) => {
|
||||
const aclRow = ({ original, value, ...props }) => {
|
||||
const aclRow = ({ original, value, headerList, ...props }) => {
|
||||
// Check what view show in the table cards
|
||||
if (viewType === ACL_TABLE_VIEWS.NAMES.type) {
|
||||
return <ACLCardNames rootProps={props} acl={value} />
|
||||
|
@ -16,26 +16,26 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { Typography } from '@mui/material'
|
||||
import {
|
||||
Lock,
|
||||
User,
|
||||
Group,
|
||||
Db as DatastoreIcon,
|
||||
Archive as DiskTypeIcon,
|
||||
Group,
|
||||
Lock,
|
||||
ModernTv,
|
||||
Pin as PersistentIcon,
|
||||
Archive as DiskTypeIcon,
|
||||
User,
|
||||
} from 'iconoir-react'
|
||||
import { Typography } from '@mui/material'
|
||||
|
||||
import Timer from 'client/components/Timer'
|
||||
import { StatusCircle, StatusChip } from 'client/components/Status'
|
||||
import { StatusChip, StatusCircle } from 'client/components/Status'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import Timer from 'client/components/Timer'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
import * as ImageModel from 'client/models/Image'
|
||||
import * as Helper from 'client/models/Helper'
|
||||
import * as ImageModel from 'client/models/Image'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const {
|
||||
ID,
|
||||
@ -126,6 +126,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -13,18 +13,25 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetBackupJobsQuery } from 'client/features/OneApi/backupjobs'
|
||||
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import BackupJobsColumns from 'client/components/Tables/BackupJobs/columns'
|
||||
import BackupJobsRow from 'client/components/Tables/BackupJobs/row'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import Timer from 'client/components/Timer'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import COLOR from 'client/constants/color'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetBackupJobsQuery } from 'client/features/OneApi/backupjobs'
|
||||
import { timeFromMilliseconds } from 'client/models/Helper'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
const DEFAULT_DATA_CY = 'backupjobs'
|
||||
|
||||
const haveValues = function (object) {
|
||||
return Object.values(object).length > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @returns {ReactElement} Backup Jobs table
|
||||
@ -46,6 +53,83 @@ const BackupJobsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: ({
|
||||
OUTDATED_VMS,
|
||||
BACKING_UP_VMS,
|
||||
ERROR_VMS,
|
||||
LAST_BACKUP_TIME,
|
||||
}) => {
|
||||
const status = useMemo(() => {
|
||||
const completed = {
|
||||
color: COLOR.success.main,
|
||||
tooltip: T.Completed,
|
||||
}
|
||||
const noStarted = {
|
||||
color: COLOR.warning.main,
|
||||
tooltip: T.NotStartedYet,
|
||||
}
|
||||
|
||||
const error = {
|
||||
color: COLOR.error.main,
|
||||
tooltip: T.Error,
|
||||
}
|
||||
|
||||
const onGoing = {
|
||||
color: COLOR.info.main,
|
||||
tooltip: T.OnGoing,
|
||||
}
|
||||
|
||||
if (haveValues(ERROR_VMS)) {
|
||||
return error
|
||||
}
|
||||
|
||||
if (!haveValues(OUTDATED_VMS) && !haveValues(BACKING_UP_VMS)) {
|
||||
return LAST_BACKUP_TIME === '0' ? noStarted : completed
|
||||
}
|
||||
|
||||
if (haveValues(OUTDATED_VMS)) {
|
||||
return completed
|
||||
}
|
||||
|
||||
if (haveValues(BACKING_UP_VMS)) {
|
||||
return onGoing
|
||||
}
|
||||
}, [OUTDATED_VMS, BACKING_UP_VMS, ERROR_VMS, LAST_BACKUP_TIME])
|
||||
|
||||
return <StatusCircle color={status.color} tooltip={status.tooltip} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{ header: T.Priority, id: 'priority', accessor: 'PRIORITY' },
|
||||
{
|
||||
header: T.LastBackupTimeInfo,
|
||||
id: 'last-time',
|
||||
accessor: ({ LAST_BACKUP_TIME }) => {
|
||||
const LastBackupTime = +LAST_BACKUP_TIME
|
||||
if (LastBackupTime > 0) {
|
||||
const timer = timeFromMilliseconds(LastBackupTime)
|
||||
|
||||
return (
|
||||
<span title={timer.toFormat('ff')}>
|
||||
<Timer translateWord={T.LastBackupTime} initial={timer} />
|
||||
</span>
|
||||
)
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(BackupJobsRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -55,7 +139,8 @@ const BackupJobsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={BackupJobsRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -23,7 +23,7 @@ import backupjobApi, {
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateBackupJobMutation()
|
||||
|
||||
const state = backupjobApi.endpoints.getBackupJobs.useQueryState(
|
||||
@ -67,6 +67,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VirtualDataCenterRow'
|
||||
|
@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetBackupsQuery } from 'client/features/OneApi/image'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import backupColumns from 'client/components/Tables/Backups/columns'
|
||||
import BackupRow from 'client/components/Tables/Backups/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { getState, getType } from 'client/models/Image'
|
||||
|
||||
const DEFAULT_DATA_CY = 'backups'
|
||||
|
||||
@ -87,6 +89,26 @@ const BackupsTable = (props) => {
|
||||
const isFetchingAll = () =>
|
||||
isFetchingVm ? !!(isFetchingVm && isFetching) : isFetching
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (template) => {
|
||||
const { color: stateColor, name: stateName } = getState(template)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{ header: T.Datastore, id: 'datastore', accessor: 'DATASTORE' },
|
||||
{ header: T.Type, id: 'type', accessor: (template) => getType(template) },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(BackupRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -96,7 +118,8 @@ const BackupsTable = (props) => {
|
||||
refetch={refetchAll}
|
||||
isLoading={isFetchingAll()}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={BackupRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,39 +13,39 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useAuth } from 'client/features/Auth'
|
||||
import imageApi, { useUpdateImageMutation } from 'client/features/OneApi/image'
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
import { useAuth } from 'client/features/Auth'
|
||||
import { useMemo, useCallback } from 'react'
|
||||
import imageApi, { useUpdateImageMutation } from 'client/features/OneApi/image'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
|
||||
import {
|
||||
Lock,
|
||||
User,
|
||||
Group,
|
||||
Db as DatastoreIcon,
|
||||
ModernTv,
|
||||
Pin as PersistentIcon,
|
||||
Archive as DiskTypeIcon,
|
||||
} from 'iconoir-react'
|
||||
import { Typography } from '@mui/material'
|
||||
import MultipleTags from 'client/components/MultipleTags'
|
||||
import {
|
||||
jsonToXml,
|
||||
getUniqueLabels,
|
||||
getColorFromString,
|
||||
getUniqueLabels,
|
||||
jsonToXml,
|
||||
} from 'client/models/Helper'
|
||||
import {
|
||||
Db as DatastoreIcon,
|
||||
Archive as DiskTypeIcon,
|
||||
Group,
|
||||
Lock,
|
||||
ModernTv,
|
||||
Pin as PersistentIcon,
|
||||
User,
|
||||
} from 'iconoir-react'
|
||||
|
||||
import Timer from 'client/components/Timer'
|
||||
import { StatusCircle, StatusChip } from 'client/components/Status'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import { T } from 'client/constants'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { StatusChip, StatusCircle } from 'client/components/Status'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import Timer from 'client/components/Timer'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
import * as ImageModel from 'client/models/Image'
|
||||
import * as Helper from 'client/models/Helper'
|
||||
import * as ImageModel from 'client/models/Image'
|
||||
|
||||
const Row = ({ original, value, onClickLabel, ...props }) => {
|
||||
const Row = ({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateImageMutation()
|
||||
const { labels: userLabels } = useAuth()
|
||||
|
||||
@ -187,6 +187,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetClustersQuery } from 'client/features/OneApi/cluster'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import ClusterColumns from 'client/components/Tables/Clusters/columns'
|
||||
import ClusterRow from 'client/components/Tables/Clusters/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetClustersQuery } from 'client/features/OneApi/cluster'
|
||||
|
||||
const DEFAULT_DATA_CY = 'clusters'
|
||||
|
||||
@ -74,6 +74,29 @@ const ClustersTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{
|
||||
header: T.Hosts,
|
||||
id: 'hosts',
|
||||
accessor: ({ HOSTS }) => (Array.isArray(HOSTS.ID) ? HOSTS.ID.length : 1),
|
||||
},
|
||||
{
|
||||
header: T.Vnets,
|
||||
id: 'vnets',
|
||||
accessor: ({ VNETS }) => (Array.isArray(VNETS.ID) ? VNETS.ID.length : 1),
|
||||
},
|
||||
{
|
||||
header: T.Datastore,
|
||||
id: 'datastores',
|
||||
accessor: ({ DATASTORES }) =>
|
||||
Array.isArray(DATASTORES.ID) ? DATASTORES.ID.length : 1,
|
||||
},
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(ClusterRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -83,7 +106,8 @@ const ClustersTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={ClusterRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -16,15 +16,15 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { HardDrive, NetworkAlt, Folder, Cloud } from 'iconoir-react'
|
||||
import { Typography } from '@mui/material'
|
||||
import { Cloud, Folder, HardDrive, NetworkAlt } from 'iconoir-react'
|
||||
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { ID, NAME, HOSTS, DATASTORES, VNETS, PROVIDER_NAME } = value
|
||||
|
||||
@ -76,6 +76,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -18,6 +18,7 @@ import { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetDatastoresQuery } from 'client/features/OneApi/datastore'
|
||||
|
||||
import { LinearProgressWithLabel, StatusCircle } from 'client/components/Status'
|
||||
import DatastoreColumns from 'client/components/Tables/Datastores/columns'
|
||||
import DatastoreRow from 'client/components/Tables/Datastores/row'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
@ -25,7 +26,9 @@ import {
|
||||
areArraysEqual,
|
||||
sortStateTables,
|
||||
} from 'client/components/Tables/Enhanced/Utils/DataTableUtils'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import { DS_THRESHOLD, RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { getCapacityInfo, getState, getType } from 'client/models/Datastore'
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
|
||||
const DEFAULT_DATA_CY = 'datastores'
|
||||
@ -135,6 +138,58 @@ const DatastoresTable = (props) => {
|
||||
}
|
||||
})
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: T.Status,
|
||||
id: 'status',
|
||||
accessor: (template) => {
|
||||
const { color: stateColor, name: stateName } = getState(template)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.Capacity,
|
||||
id: 'capacity',
|
||||
accessor: (template) => {
|
||||
const capacity = useMemo(() => getCapacityInfo(template), [template])
|
||||
const { percentOfUsed, percentLabel } = capacity
|
||||
|
||||
return (
|
||||
<LinearProgressWithLabel
|
||||
value={percentOfUsed}
|
||||
label={percentLabel}
|
||||
high={DS_THRESHOLD.CAPACITY.high}
|
||||
low={DS_THRESHOLD.CAPACITY.low}
|
||||
title={T.UsedOfTotal}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Cluster,
|
||||
id: 'cluster',
|
||||
accessor: ({ CLUSTERS }) => {
|
||||
const clusters = useMemo(
|
||||
() => [CLUSTERS?.ID ?? []].flat(),
|
||||
[CLUSTERS?.ID]
|
||||
)
|
||||
|
||||
return clusters.length && clusters[0]
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Type,
|
||||
id: 'type',
|
||||
accessor: (template) => getType(template),
|
||||
},
|
||||
]
|
||||
const { component, header } = WrapperRow(DatastoreRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -144,8 +199,9 @@ const DatastoresTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={DatastoreRow}
|
||||
dataDepend={values}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,27 +13,34 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import {
|
||||
useGetDatastoresQuery,
|
||||
import { DatastoreCard } from 'client/components/Cards'
|
||||
import api, {
|
||||
useUpdateDatastoreMutation,
|
||||
} from 'client/features/OneApi/datastore'
|
||||
import { DatastoreCard } from 'client/components/Cards'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, onClickLabel, ...props }) => {
|
||||
const { data: datastores } = useGetDatastoresQuery(undefined)
|
||||
const selectedDatastore = datastores?.find(
|
||||
(datastore) => +datastore.ID === +original.ID
|
||||
)
|
||||
({ original, value, onClickLabel, zone, headerList, ...props }) => {
|
||||
const [update] = useUpdateDatastoreMutation()
|
||||
const {
|
||||
data: datastores,
|
||||
error,
|
||||
isLoading,
|
||||
} = api.endpoints.getDatastores.useQueryState({ zone })
|
||||
|
||||
const selectedDatastore = useMemo(
|
||||
() =>
|
||||
datastores?.find((datastore) => +datastore.ID === +original.ID) ??
|
||||
original,
|
||||
[datastores, original]
|
||||
)
|
||||
|
||||
const memoDs = useMemo(
|
||||
() => selectedDatastore ?? original,
|
||||
[datastores, original]
|
||||
[selectedDatastore, original, update, isLoading, error, datastores]
|
||||
)
|
||||
|
||||
const handleDeleteLabel = useCallback(
|
||||
@ -62,7 +69,10 @@ const Row = memo(
|
||||
|
||||
Row.propTypes = {
|
||||
original: PropTypes.object,
|
||||
value: PropTypes.object,
|
||||
onClickLabel: PropTypes.func,
|
||||
zone: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'DatastoreRow'
|
||||
|
@ -0,0 +1,95 @@
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Copyright 2002-2024, 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 { TableCell, TableRow } from '@mui/material'
|
||||
import makeStyles from '@mui/styles/makeStyles'
|
||||
import { SERVER_CONFIG } from 'client/constants'
|
||||
import { useAuth } from 'client/features/Auth'
|
||||
import get from 'lodash.get'
|
||||
import PropTypes from 'prop-types'
|
||||
import { ReactElement, memo } from 'react'
|
||||
|
||||
const listStyles = makeStyles(({ palette }) => ({
|
||||
row: {
|
||||
'&.selected': {
|
||||
boxShadow: `inset 0px -0.5px 0px 2px ${palette.secondary.main}`,
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @returns {ReactElement} Generic Row
|
||||
*/
|
||||
const RowStyle = memo(
|
||||
({
|
||||
original,
|
||||
value,
|
||||
onClickLabel,
|
||||
globalErrors,
|
||||
headerList = [],
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const styles = listStyles()
|
||||
|
||||
return (
|
||||
<TableRow {...props} className={`${styles.row} ${className}`}>
|
||||
{headerList.map(({ id, accessor }) => {
|
||||
switch (typeof accessor) {
|
||||
case 'string':
|
||||
return <TableCell key={id}>{get(original, accessor)}</TableCell>
|
||||
case 'function':
|
||||
return <TableCell key={id}>{accessor(original)}</TableCell>
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})}
|
||||
</TableRow>
|
||||
)
|
||||
},
|
||||
(prev, next) => prev.className === next.className
|
||||
)
|
||||
|
||||
RowStyle.propTypes = {
|
||||
original: PropTypes.object,
|
||||
value: PropTypes.object,
|
||||
onClickLabel: PropTypes.func,
|
||||
globalErrors: PropTypes.array,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
RowStyle.displayName = 'RowStyle'
|
||||
|
||||
/**
|
||||
* @param {ReactElement} RowCardComponent - Standard row component (Card).
|
||||
* @returns {ReactElement} Generic Row
|
||||
*/
|
||||
const WrapperRow = (RowCardComponent) => {
|
||||
const { settings: { FIREEDGE: fireedge = {} } = {} } = useAuth()
|
||||
const { ROW_STYLE } = fireedge
|
||||
const { rowStyle } = SERVER_CONFIG
|
||||
|
||||
const data = ROW_STYLE || rowStyle
|
||||
const header = data === 'list'
|
||||
|
||||
return {
|
||||
component: header ? RowStyle : RowCardComponent,
|
||||
header,
|
||||
}
|
||||
}
|
||||
|
||||
export default WrapperRow
|
@ -17,7 +17,17 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { Alert, Box, Chip, Grid } from '@mui/material'
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Chip,
|
||||
Grid,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableRow,
|
||||
} from '@mui/material'
|
||||
import clsx from 'clsx'
|
||||
import InfoEmpty from 'iconoir-react/dist/InfoEmpty'
|
||||
import RemoveIcon from 'iconoir-react/dist/RemoveSquare'
|
||||
@ -83,6 +93,7 @@ const EnhancedTable = ({
|
||||
readOnly = false,
|
||||
tableViews,
|
||||
zoneId,
|
||||
headerList,
|
||||
}) => {
|
||||
const styles = EnhancedTableStyles({
|
||||
readOnly: readOnly,
|
||||
@ -301,6 +312,84 @@ const EnhancedTable = ({
|
||||
)
|
||||
}
|
||||
|
||||
const DataListPerPage = ({ page: internalPage = [] }) => {
|
||||
if (!internalPage.length) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const valuesPerPages = internalPage.map((row) => {
|
||||
prepareRow(row)
|
||||
|
||||
/** @type {UseRowSelectRowProps} */
|
||||
const { getRowProps, original, values, toggleRowSelected, isSelected } =
|
||||
row
|
||||
const { key, ...rowProps } = getRowProps()
|
||||
|
||||
return (
|
||||
<RowComponent
|
||||
{...rowProps}
|
||||
headerList={headerList}
|
||||
zone={zoneId}
|
||||
key={key}
|
||||
original={original}
|
||||
value={values}
|
||||
{...(messageValues.length && {
|
||||
globalErrors: messageValues,
|
||||
})}
|
||||
className={isSelected ? 'selected' : ''}
|
||||
{...(!cannotFilterByLabel && {
|
||||
onClickLabel: (label) => {
|
||||
const currentFilter =
|
||||
state.filters
|
||||
?.filter(({ id }) => id === LABEL_COLUMN_ID)
|
||||
?.map(({ value }) => value)
|
||||
?.flat() || []
|
||||
|
||||
const nextFilter = [...new Set([...currentFilter, label])]
|
||||
setFilter(LABEL_COLUMN_ID, nextFilter)
|
||||
},
|
||||
})}
|
||||
onClick={(e) => {
|
||||
typeof onRowClick === 'function' && onRowClick(original)
|
||||
|
||||
if (!disableRowSelect && !readOnly) {
|
||||
if (
|
||||
singleSelect ||
|
||||
(!singleSelect && !(e.ctrlKey || e.metaKey))
|
||||
) {
|
||||
toggleAllRowsSelected?.(false)
|
||||
}
|
||||
toggleRowSelected?.(!isSelected)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
return headerList ? (
|
||||
<Table stickyHeader>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{headerList.map(({ header = '', id = '' }) => (
|
||||
<TableCell key={id} className={styles.cellHeaders}>
|
||||
{header}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>{valuesPerPages}</TableBody>
|
||||
</Table>
|
||||
) : (
|
||||
<>{valuesPerPages}</>
|
||||
)
|
||||
}
|
||||
|
||||
DataListPerPage.propTypes = {
|
||||
page: PropTypes.any,
|
||||
}
|
||||
|
||||
DataListPerPage.displayName = 'DataListPerPage'
|
||||
|
||||
return (
|
||||
<Box
|
||||
{...getTableProps()}
|
||||
@ -376,7 +465,7 @@ const EnhancedTable = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className={clsx(styles.body, classes.body)}>
|
||||
<div className={clsx(styles.body, !headerList ? classes.body : '')}>
|
||||
{!!messages.length && <MessagesRowsAlerts />}
|
||||
{/* NO DATA MESSAGE */}
|
||||
{!isLoading &&
|
||||
@ -390,58 +479,7 @@ const EnhancedTable = ({
|
||||
))}
|
||||
|
||||
{/* DATALIST PER PAGE */}
|
||||
{page.map((row) => {
|
||||
prepareRow(row)
|
||||
|
||||
/** @type {UseRowSelectRowProps} */
|
||||
const {
|
||||
getRowProps,
|
||||
original,
|
||||
values,
|
||||
toggleRowSelected,
|
||||
isSelected,
|
||||
} = row
|
||||
const { key, ...rowProps } = getRowProps()
|
||||
|
||||
return (
|
||||
<RowComponent
|
||||
{...rowProps}
|
||||
zone={zoneId}
|
||||
key={key}
|
||||
original={original}
|
||||
value={values}
|
||||
{...(messageValues.length && {
|
||||
globalErrors: messageValues,
|
||||
})}
|
||||
className={isSelected ? 'selected' : ''}
|
||||
{...(!cannotFilterByLabel && {
|
||||
onClickLabel: (label) => {
|
||||
const currentFilter =
|
||||
state.filters
|
||||
?.filter(({ id }) => id === LABEL_COLUMN_ID)
|
||||
?.map(({ value }) => value)
|
||||
?.flat() || []
|
||||
|
||||
const nextFilter = [...new Set([...currentFilter, label])]
|
||||
setFilter(LABEL_COLUMN_ID, nextFilter)
|
||||
},
|
||||
})}
|
||||
onClick={(e) => {
|
||||
typeof onRowClick === 'function' && onRowClick(original)
|
||||
|
||||
if (!disableRowSelect && !readOnly) {
|
||||
if (
|
||||
singleSelect ||
|
||||
(!singleSelect && !(e.ctrlKey || e.metaKey))
|
||||
) {
|
||||
toggleAllRowsSelected?.(false)
|
||||
}
|
||||
toggleRowSelected?.(!isSelected)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
<DataListPerPage page={page} />
|
||||
</div>
|
||||
</Box>
|
||||
)
|
||||
@ -490,6 +528,7 @@ EnhancedTable.propTypes = {
|
||||
readOnly: PropTypes.bool,
|
||||
tableViews: PropTypes.object,
|
||||
zoneId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export * from 'client/components/Tables/Enhanced/Utils'
|
||||
|
@ -132,4 +132,7 @@ export default makeStyles(({ palette, typography, breakpoints }) => ({
|
||||
gap: '0.8em',
|
||||
padding: '1em',
|
||||
},
|
||||
cellHeaders: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
}))
|
||||
|
@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetFilesQuery } from 'client/features/OneApi/image'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import ImageColumns from 'client/components/Tables/Images/columns'
|
||||
import ImageRow from 'client/components/Tables/Images/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetFilesQuery } from 'client/features/OneApi/image'
|
||||
import { getState, getType } from 'client/models/Image'
|
||||
|
||||
const DEFAULT_DATA_CY = 'images'
|
||||
|
||||
@ -61,6 +63,26 @@ const FilesTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (vm) => {
|
||||
const { color: stateColor, name: stateName } = getState(vm)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{ header: T.Datastore, id: 'datastore', accessor: 'DATASTORE' },
|
||||
{ header: T.Type, id: 'type', accessor: (template) => getType(template) },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(ImageRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -70,7 +92,8 @@ const FilesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={ImageRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,13 +13,16 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, Component } from 'react'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetGroupsQuery } from 'client/features/OneApi/group'
|
||||
import { LinearProgressWithTooltip } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import GroupColumns from 'client/components/Tables/Groups/columns'
|
||||
import GroupRow from 'client/components/Tables/Groups/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetGroupsQuery } from 'client/features/OneApi/group'
|
||||
import { getQuotaUsage } from 'client/models/Group'
|
||||
import { Component, useMemo } from 'react'
|
||||
|
||||
const DEFAULT_DATA_CY = 'groups'
|
||||
|
||||
@ -58,6 +61,74 @@ const GroupsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{
|
||||
header: T.Users,
|
||||
id: 'users',
|
||||
accessor: ({ USERS }) => (Array.isArray(USERS?.ID) ? USERS.ID.length : 0),
|
||||
},
|
||||
{
|
||||
header: T.VMs,
|
||||
id: 'vms',
|
||||
accessor: ({ VM_QUOTA }) => {
|
||||
const vmQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('VM', VM_QUOTA),
|
||||
[VM_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={vmQuotaUsage.vms.percentOfUsed}
|
||||
label={vmQuotaUsage.vms.percentLabel}
|
||||
tooltipTitle={T.VMCount}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Datastores,
|
||||
id: 'datastores',
|
||||
accessor: ({ DATASTORE_QUOTA }) => {
|
||||
const datastoreQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('DATASTORE', DATASTORE_QUOTA),
|
||||
[DATASTORE_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={datastoreQuotaUsage.size.percentOfUsed}
|
||||
label={datastoreQuotaUsage.size.percentLabel}
|
||||
tooltipTitle={T.DatastoreSize}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Networks,
|
||||
id: 'networks',
|
||||
accessor: ({ NETWORK_QUOTA }) => {
|
||||
const networkQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('NETWORK', NETWORK_QUOTA),
|
||||
[NETWORK_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={networkQuotaUsage.leases.percentOfUsed}
|
||||
label={networkQuotaUsage.leases.percentLabel}
|
||||
tooltipTitle={T.NetworkLeases}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
const { component, header } = WrapperRow(GroupRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -67,11 +138,15 @@ const GroupsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={GroupRow}
|
||||
singleSelect={singleSelect}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
GroupsTable.propTypes = { ...EnhancedTable.propTypes }
|
||||
GroupsTable.displayName = 'GroupsTable'
|
||||
|
||||
export default GroupsTable
|
||||
|
@ -15,17 +15,20 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetHostsQuery } from 'client/features/OneApi/host'
|
||||
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { LinearProgressWithLabel, StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import {
|
||||
areArraysEqual,
|
||||
sortStateTables,
|
||||
} from 'client/components/Tables/Enhanced/Utils/DataTableUtils'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import HostColumns from 'client/components/Tables/Hosts/columns'
|
||||
import HostRow from 'client/components/Tables/Hosts/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { HOST_THRESHOLD, RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetHostsQuery } from 'client/features/OneApi/host'
|
||||
import { getAllocatedInfo, getState } from 'client/models/Host'
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
|
||||
const DEFAULT_DATA_CY = 'hosts'
|
||||
@ -136,6 +139,65 @@ const HostsTable = (props) => {
|
||||
})
|
||||
useEffect(() => refetch(), [])
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (host) => {
|
||||
const { color: stateColor, name: stateName } = getState(host)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Cluster, id: 'cluster', accessor: 'CLUSTER' },
|
||||
{
|
||||
header: T.Rvms,
|
||||
id: 'rvms',
|
||||
accessor: ({ HOST_SHARE }) => HOST_SHARE?.RUNNING_VMS || 0,
|
||||
},
|
||||
{
|
||||
header: T.AllocatedCpu,
|
||||
id: 'cpu',
|
||||
accessor: (host) => {
|
||||
const { percentCpuUsed, percentCpuLabel, colorCpu } =
|
||||
getAllocatedInfo(host)
|
||||
|
||||
return (
|
||||
<LinearProgressWithLabel
|
||||
value={percentCpuUsed}
|
||||
high={HOST_THRESHOLD.CPU.high}
|
||||
low={HOST_THRESHOLD.CPU.low}
|
||||
label={percentCpuLabel}
|
||||
title={`${Tr(T.AllocatedCpu)}`}
|
||||
color={colorCpu}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.AllocatedMemory,
|
||||
id: 'memory',
|
||||
accessor: (host) => {
|
||||
const { percentMemUsed, percentMemLabel, colorMem } =
|
||||
getAllocatedInfo(host)
|
||||
|
||||
return (
|
||||
<LinearProgressWithLabel
|
||||
value={percentMemUsed}
|
||||
high={HOST_THRESHOLD.MEMORY.high}
|
||||
low={HOST_THRESHOLD.MEMORY.low}
|
||||
label={percentMemLabel}
|
||||
title={`${Tr(T.AllocatedMemory)}`}
|
||||
color={colorMem}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
const { component, header } = WrapperRow(HostRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -145,9 +207,10 @@ const HostsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={HostRow}
|
||||
dataDepend={values}
|
||||
zoneId={zoneId}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -20,14 +20,14 @@ import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, zone, ...props }) => {
|
||||
({ original, value, onClickLabel, zone, headerList, ...props }) => {
|
||||
const [update] = useUpdateHostMutation()
|
||||
|
||||
const {
|
||||
data: hosts,
|
||||
error,
|
||||
isLoading,
|
||||
} = hostApi.endpoints.getHosts.useQuery({ zone })
|
||||
} = hostApi.endpoints.getHosts.useQueryState({ zone })
|
||||
|
||||
const host = useMemo(
|
||||
() => hosts?.find((h) => +h.ID === +original.ID) ?? original,
|
||||
@ -71,6 +71,7 @@ Row.propTypes = {
|
||||
handleClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
zone: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'HostRow'
|
||||
|
@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetImagesQuery } from 'client/features/OneApi/image'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import ImageColumns from 'client/components/Tables/Images/columns'
|
||||
import ImageRow from 'client/components/Tables/Images/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetImagesQuery } from 'client/features/OneApi/image'
|
||||
import { getState, getType } from 'client/models/Image'
|
||||
|
||||
const DEFAULT_DATA_CY = 'images'
|
||||
|
||||
@ -46,6 +48,27 @@ const ImagesTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (vm) => {
|
||||
const { color: stateColor, name: stateName } = getState(vm)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{ header: T.Datastore, id: 'datastore', accessor: 'DATASTORE' },
|
||||
{ header: T.Type, id: 'type', accessor: (template) => getType(template) },
|
||||
{ header: T.VMs, id: 'vms', accessor: 'RUNNING_VMS' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(ImageRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -55,7 +78,8 @@ const ImagesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={ImageRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -45,7 +45,7 @@ import { prettyBytes } from 'client/utils'
|
||||
import * as Helper from 'client/models/Helper'
|
||||
import * as ImageModel from 'client/models/Image'
|
||||
|
||||
const Row = ({ original, value, onClickLabel, ...props }) => {
|
||||
const Row = ({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateImageMutation()
|
||||
const { labels: userLabels } = useAuth()
|
||||
|
||||
@ -167,6 +167,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -16,22 +16,22 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { Typography } from '@mui/material'
|
||||
import {
|
||||
HardDrive as SizeIcon,
|
||||
RefreshCircular as FullIcon,
|
||||
Refresh as IncrementIcon,
|
||||
HardDrive as SizeIcon,
|
||||
} from 'iconoir-react'
|
||||
import { Typography } from '@mui/material'
|
||||
|
||||
import Timer from 'client/components/Timer'
|
||||
import { StatusChip } from 'client/components/Status'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import Timer from 'client/components/Timer'
|
||||
import { T } from 'client/constants'
|
||||
import { prettyBytes } from 'client/utils'
|
||||
|
||||
import * as Helper from 'client/models/Helper'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { ID, TYPE, DATE, SIZE, SOURCE } = value
|
||||
|
||||
@ -78,6 +78,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetMarketplaceAppsQuery } from 'client/features/OneApi/marketplaceApp'
|
||||
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import MarketplaceAppColumns from 'client/components/Tables/MarketplaceApps/columns'
|
||||
import MarketplaceAppRow from 'client/components/Tables/MarketplaceApps/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetMarketplaceAppsQuery } from 'client/features/OneApi/marketplaceApp'
|
||||
import { getState, getType } from 'client/models/MarketplaceApp'
|
||||
import { prettyBytes } from 'client/utils'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
const DEFAULT_DATA_CY = 'apps'
|
||||
|
||||
@ -56,6 +58,41 @@ const MarketplaceAppsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (vm) => {
|
||||
const { color: stateColor, name: stateName } = getState(vm)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.Size,
|
||||
id: 'Size',
|
||||
accessor: ({ SIZE }) => prettyBytes(+SIZE, 'MB'),
|
||||
},
|
||||
{
|
||||
header: T.Type,
|
||||
id: 'type',
|
||||
accessor: (template) =>
|
||||
useMemo(() => getType(template), [template?.TYPE]),
|
||||
},
|
||||
{
|
||||
header: T.Marketplace,
|
||||
id: 'marketplace',
|
||||
accessor: 'MARKETPLACE',
|
||||
},
|
||||
{ header: T.Zone, id: 'zone', accessor: 'ZONE_ID' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(MarketplaceAppRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -65,7 +102,8 @@ const MarketplaceAppsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={MarketplaceAppRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,17 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import { MarketplaceAppCard } from 'client/components/Cards'
|
||||
import api, {
|
||||
useUpdateAppMutation,
|
||||
} from 'client/features/OneApi/marketplaceApp'
|
||||
import { MarketplaceAppCard } from 'client/components/Cards'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateAppMutation()
|
||||
|
||||
const state = api.endpoints.getMarketplaceApps.useQueryState(undefined, {
|
||||
@ -64,6 +64,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'MarketplaceAppRow'
|
||||
|
@ -13,16 +13,19 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetMarketplacesQuery } from 'client/features/OneApi/marketplace'
|
||||
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { LinearProgressWithLabel, StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import MarketplaceColumns from 'client/components/Tables/Marketplaces/columns'
|
||||
import MarketplaceRow from 'client/components/Tables/Marketplaces/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { MARKET_THRESHOLD, RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetMarketplacesQuery } from 'client/features/OneApi/marketplace'
|
||||
import { getCapacityInfo, getState } from 'client/models/Datastore'
|
||||
|
||||
const DEFAULT_DATA_CY = 'marketplaces'
|
||||
|
||||
@ -53,6 +56,52 @@ const MarketplacesTable = ({ filter, ...props }) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (vm) => {
|
||||
const { color: stateColor, name: stateName } = getState(vm)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.Capacity,
|
||||
id: 'capacity',
|
||||
accessor: (template) => {
|
||||
const capacity = useMemo(() => getCapacityInfo(template), [template])
|
||||
const { percentOfUsed, percentLabel } = capacity
|
||||
|
||||
return (
|
||||
<LinearProgressWithLabel
|
||||
value={percentOfUsed}
|
||||
label={percentLabel}
|
||||
high={MARKET_THRESHOLD.CAPACITY.high}
|
||||
low={MARKET_THRESHOLD.CAPACITY.low}
|
||||
title={Tr(T.UsedOfTotal)}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Apps,
|
||||
id: 'apps',
|
||||
accessor: ({ MARKETPLACEAPPS }) =>
|
||||
useMemo(
|
||||
() => [MARKETPLACEAPPS?.ID ?? []].flat().length || 0,
|
||||
[MARKETPLACEAPPS?.ID]
|
||||
),
|
||||
},
|
||||
{ header: T.Zone, id: 'zone', accessor: 'ZONE_ID' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(MarketplaceRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -62,7 +111,8 @@ const MarketplacesTable = ({ filter, ...props }) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={MarketplaceRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import marketplaceApi from 'client/features/OneApi/marketplace'
|
||||
import { MarketplaceCard } from 'client/components/Cards'
|
||||
import marketplaceApi from 'client/features/OneApi/marketplace'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, ...props }) => {
|
||||
({ original, value, headerList, ...props }) => {
|
||||
const state = marketplaceApi.endpoints.getMarketplaces.useQueryState(
|
||||
undefined,
|
||||
{
|
||||
@ -42,6 +42,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'MarketplaceRow'
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetSecGroupsQuery } from 'client/features/OneApi/securityGroup'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import SecurityGroupColumns from 'client/components/Tables/SecurityGroups/columns'
|
||||
import SecurityGroupsRow from 'client/components/Tables/SecurityGroups/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetSecGroupsQuery } from 'client/features/OneApi/securityGroup'
|
||||
|
||||
const DEFAULT_DATA_CY = 'secgroup'
|
||||
|
||||
@ -51,6 +51,15 @@ const SecurityGroupsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(SecurityGroupsRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -60,7 +69,8 @@ const SecurityGroupsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={SecurityGroupsRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,16 +13,16 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { SecurityGroupCard } from 'client/components/Cards'
|
||||
import secGroupApi, {
|
||||
useUpdateSecGroupMutation,
|
||||
} from 'client/features/OneApi/securityGroup'
|
||||
import { SecurityGroupCard } from 'client/components/Cards'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateSecGroupMutation()
|
||||
|
||||
const {
|
||||
@ -74,6 +74,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'SecurityGroupRow'
|
||||
|
@ -13,16 +13,16 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import { ServiceTemplateCard } from 'client/components/Cards'
|
||||
import serviceTemplateApi, {
|
||||
useUpdateServiceTemplateMutation,
|
||||
} from 'client/features/OneApi/serviceTemplate'
|
||||
import { ServiceTemplateCard } from 'client/components/Cards'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, ...props }) => {
|
||||
({ original, value, headerList, ...props }) => {
|
||||
const [update] = useUpdateServiceTemplateMutation()
|
||||
|
||||
const state =
|
||||
@ -63,6 +63,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'ServiceTemplateRow'
|
||||
|
@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import serviceApi from 'client/features/OneApi/service'
|
||||
import { ServiceCard } from 'client/components/Cards'
|
||||
import serviceApi from 'client/features/OneApi/service'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, ...props }) => {
|
||||
({ original, value, headerList, ...props }) => {
|
||||
const state = serviceApi.endpoints.getServices.useQueryState(undefined, {
|
||||
selectFromResult: ({ data = [] }) =>
|
||||
data.find((service) => +service.ID === +original.ID),
|
||||
@ -39,6 +39,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'ServiceRow'
|
||||
|
@ -13,15 +13,14 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetTicketsQuery } from 'client/features/OneApi/support'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import SupportColumns from 'client/components/Tables/Support/columns'
|
||||
import SupportRow from 'client/components/Tables/Support/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetTicketsQuery } from 'client/features/OneApi/support'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
const DEFAULT_DATA_CY = 'support'
|
||||
|
||||
@ -62,6 +61,13 @@ const SupportTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'id' },
|
||||
{ header: T.Subject, id: 'subject', accessor: 'subject' },
|
||||
{ header: T.Status, id: 'status', accessor: 'status' },
|
||||
]
|
||||
const { component, header } = WrapperRow(SupportRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -71,8 +77,9 @@ const SupportTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.id)}
|
||||
RowComponent={SupportRow}
|
||||
initialState={initialState}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo } from 'react'
|
||||
|
||||
import { SupportCard } from 'client/components/Cards'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, ...props }) => (
|
||||
({ original, value, headerList, ...props }) => (
|
||||
<SupportCard ticket={original} rootProps={props} />
|
||||
),
|
||||
(prev, next) => prev.className === next.className
|
||||
@ -31,6 +31,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'SupportRow'
|
||||
|
@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetUsersQuery } from 'client/features/OneApi/user'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { LinearProgressWithTooltip } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import UserColumns from 'client/components/Tables/Users/columns'
|
||||
import UserRow from 'client/components/Tables/Users/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetUsersQuery } from 'client/features/OneApi/user'
|
||||
import { getQuotaUsage } from 'client/models/User'
|
||||
|
||||
const DEFAULT_DATA_CY = 'users'
|
||||
|
||||
@ -52,6 +54,76 @@ const UsersTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.Enabled,
|
||||
id: 'enabled',
|
||||
accessor: ({ ENABLED }) => (+ENABLED ? T.Yes : T.No),
|
||||
},
|
||||
{ header: T.AuthDriver, id: 'auth-driver', accessor: 'AUTH_DRIVER' },
|
||||
{
|
||||
header: T.VMs,
|
||||
id: 'vms',
|
||||
accessor: ({ VM_QUOTA }) => {
|
||||
const vmQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('VM', VM_QUOTA),
|
||||
[VM_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={vmQuotaUsage.vms.percentOfUsed}
|
||||
label={vmQuotaUsage.vms.percentLabel}
|
||||
tooltipTitle={T.VMCount}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Datastores,
|
||||
id: 'datastores',
|
||||
accessor: ({ DATASTORE_QUOTA }) => {
|
||||
const datastoreQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('DATASTORE', DATASTORE_QUOTA),
|
||||
[DATASTORE_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={datastoreQuotaUsage.size.percentOfUsed}
|
||||
label={datastoreQuotaUsage.size.percentLabel}
|
||||
tooltipTitle={T.DatastoreSize}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Networks,
|
||||
id: 'networks',
|
||||
accessor: ({ NETWORK_QUOTA }) => {
|
||||
const networkQuotaUsage = useMemo(
|
||||
() => getQuotaUsage('NETWORK', NETWORK_QUOTA),
|
||||
[NETWORK_QUOTA]
|
||||
)
|
||||
|
||||
return (
|
||||
<LinearProgressWithTooltip
|
||||
value={networkQuotaUsage.leases.percentOfUsed}
|
||||
label={networkQuotaUsage.leases.percentLabel}
|
||||
tooltipTitle={T.NetworkLeases}
|
||||
icon=""
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
const { component, header } = WrapperRow(UserRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -61,7 +133,8 @@ const UsersTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={UserRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import { UserCard } from 'client/components/Cards'
|
||||
|
||||
const Row = ({ original, value, ...props }) => (
|
||||
const Row = ({ original, value, headerList, ...props }) => (
|
||||
<UserCard rootProps={props} user={value} />
|
||||
)
|
||||
|
||||
@ -27,6 +27,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -14,15 +14,15 @@
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVNTemplatesQuery } from 'client/features/OneApi/networkTemplate'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VNetworkTemplateColumns from 'client/components/Tables/VNetworkTemplates/columns'
|
||||
import VNetworkTemplateRow from 'client/components/Tables/VNetworkTemplates/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVNTemplatesQuery } from 'client/features/OneApi/networkTemplate'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vnet-templates'
|
||||
|
||||
@ -47,6 +47,15 @@ const VNetworkTemplatesTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VNetworkTemplateRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -56,7 +65,8 @@ const VNetworkTemplatesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VNetworkTemplateRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -19,13 +19,13 @@ import PropTypes from 'prop-types'
|
||||
import { Typography } from '@mui/material'
|
||||
import { Cloud, Group, Lock, User } from 'iconoir-react'
|
||||
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
import * as Helper from 'client/models/Helper'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { ID, NAME, UNAME, GNAME, LOCK, REGTIME, PROVISION_ID } = value
|
||||
|
||||
@ -68,6 +68,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -13,19 +13,21 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVNetworksQuery } from 'client/features/OneApi/network'
|
||||
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { LinearProgressWithLabel, StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import {
|
||||
areArraysEqual,
|
||||
sortStateTables,
|
||||
} from 'client/components/Tables/Enhanced/Utils/DataTableUtils'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VNetworkColumns from 'client/components/Tables/VNetworks/columns'
|
||||
import VNetworkRow from 'client/components/Tables/VNetworks/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T, VNET_THRESHOLD } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVNetworksQuery } from 'client/features/OneApi/network'
|
||||
import { getLeasesInfo, getState } from 'client/models/VirtualNetwork'
|
||||
import { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vnets'
|
||||
@ -137,6 +139,54 @@ const VNetworksTable = (props) => {
|
||||
})
|
||||
useEffect(() => refetch(), [])
|
||||
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (template) => {
|
||||
const { color: stateColor, name: stateName } = getState(template)
|
||||
|
||||
return <StatusCircle color={stateColor} tooltip={stateName} />
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.Clusters,
|
||||
id: 'clusters',
|
||||
accessor: ({ CLUSTERS }) => {
|
||||
const clusters = useMemo(
|
||||
() => [CLUSTERS?.ID ?? []].flat(),
|
||||
[CLUSTERS?.ID]
|
||||
)
|
||||
|
||||
return clusters.length && clusters[0]
|
||||
},
|
||||
},
|
||||
{
|
||||
header: T.Leases,
|
||||
id: 'leases',
|
||||
accessor: (template) => {
|
||||
const leasesInfo = useMemo(() => getLeasesInfo(template), [template])
|
||||
const { percentOfUsed, percentLabel } = leasesInfo
|
||||
|
||||
return (
|
||||
<LinearProgressWithLabel
|
||||
value={percentOfUsed}
|
||||
high={VNET_THRESHOLD.LEASES.high}
|
||||
low={VNET_THRESHOLD.LEASES.low}
|
||||
label={percentLabel}
|
||||
title={`${Tr(T.Used)} / ${Tr(T.TotalLeases)}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VNetworkRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -146,8 +196,9 @@ const VNetworksTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VNetworkRow}
|
||||
dataDepend={values}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,21 +13,21 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import api, { useUpdateVNetMutation } from 'client/features/OneApi/network'
|
||||
import { NetworkCard } from 'client/components/Cards'
|
||||
import api, { useUpdateVNetMutation } from 'client/features/OneApi/network'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateVNetMutation()
|
||||
const {
|
||||
data: vnetworks,
|
||||
error,
|
||||
isLoading,
|
||||
} = api.endpoints.getVNetworks.useQuery(undefined)
|
||||
} = api.endpoints.getVNetworks.useQueryState(undefined)
|
||||
|
||||
const vnetwork = useMemo(
|
||||
() => vnetworks?.find((vnet) => +vnet.ID === +original.ID) ?? original,
|
||||
@ -69,6 +69,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VirtualNetworkRow'
|
||||
|
@ -29,6 +29,7 @@ import { BoxIso as DownloadIcon } from 'iconoir-react'
|
||||
|
||||
import { Tr, Translate } from 'client/components/HOC'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VRouterTemplateColumns from 'client/components/Tables/VRouterTemplates/columns'
|
||||
import VRouterTemplateRow from 'client/components/Tables/VRouterTemplates/row'
|
||||
import { useStyles } from 'client/components/Tabs/EmptyTab/styles'
|
||||
@ -37,6 +38,7 @@ import {
|
||||
useExportAppMutation,
|
||||
useLazyGetMarketplaceAppsQuery,
|
||||
} from 'client/features/OneApi/marketplaceApp'
|
||||
import { timeToString } from 'client/models/Helper'
|
||||
import InfoEmpty from 'iconoir-react/dist/InfoEmpty'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
@ -262,6 +264,20 @@ const VRouterTemplatesTable = (props) => {
|
||||
</>
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.RegistrationTime,
|
||||
id: 'registration-time',
|
||||
accessor: (template) => timeToString(template.REGTIME),
|
||||
},
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VRouterTemplateRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -271,8 +287,9 @@ const VRouterTemplatesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={loading}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VRouterTemplateRow}
|
||||
noDataCustomRenderer={<NoDataAvailable />}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,17 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import { VmTemplateCard as VRouterTemplateCard } from 'client/components/Cards'
|
||||
import vrouterTemplatesApi, {
|
||||
useUpdateTemplateMutation,
|
||||
} from 'client/features/OneApi/vmTemplate'
|
||||
import { VmTemplateCard as VRouterTemplateCard } from 'client/components/Cards'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateTemplateMutation()
|
||||
|
||||
const state =
|
||||
@ -68,6 +68,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VRouterTemplateRow'
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVRoutersQuery } from 'client/features/OneApi/vrouter'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VRouterColumns from 'client/components/Tables/VRouters/columns'
|
||||
import VRouterRow from 'client/components/Tables/VRouters/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVRoutersQuery } from 'client/features/OneApi/vrouter'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vrouters'
|
||||
|
||||
@ -51,6 +51,15 @@ const VRoutersTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VRouterRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -60,7 +69,8 @@ const VRoutersTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VRouterRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -16,15 +16,15 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { User, Group, EmptyPage, ModernTv } from 'iconoir-react'
|
||||
import { Typography } from '@mui/material'
|
||||
import { EmptyPage, Group, ModernTv, User } from 'iconoir-react'
|
||||
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { ID, NAME, UNAME, GNAME, VMS, TEMPLATE_ID } = value
|
||||
|
||||
@ -65,6 +65,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -13,18 +13,21 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VDCColumns from 'client/components/Tables/VirtualDataCenters/columns'
|
||||
import VDCRow from 'client/components/Tables/VirtualDataCenters/row'
|
||||
import { ALL_SELECTED, RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVDCsQuery } from 'client/features/OneApi/vdc'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import VDCColumns from 'client/components/Tables/VirtualDataCenters/columns'
|
||||
import VDCRow from 'client/components/Tables/VirtualDataCenters/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vdcs'
|
||||
|
||||
const isAllSelected = (resourceArray) =>
|
||||
resourceArray.length === 1 && resourceArray[0] === ALL_SELECTED
|
||||
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @returns {ReactElement} VM Templates table
|
||||
@ -46,6 +49,75 @@ const VDCsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{
|
||||
header: T.Groups,
|
||||
id: 'group',
|
||||
accessor: ({ GROUPS }) =>
|
||||
useMemo(() => {
|
||||
const { ID: groupsIds = [] } = GROUPS
|
||||
const groupsArray = Array.isArray(groupsIds) ? groupsIds : [groupsIds]
|
||||
|
||||
return groupsArray.length
|
||||
}, [GROUPS.ID]),
|
||||
},
|
||||
{
|
||||
header: T.Clusters,
|
||||
id: 'clusters',
|
||||
accessor: ({ CLUSTERS }) =>
|
||||
useMemo(() => {
|
||||
const { CLUSTER: clustersInfo = [] } = CLUSTERS
|
||||
const clustersArray = (
|
||||
Array.isArray(clustersInfo) ? clustersInfo : [clustersInfo]
|
||||
).map((cluster) => cluster.CLUSTER_ID)
|
||||
|
||||
return isAllSelected(clustersArray) ? T.All : clustersArray.length
|
||||
}, [CLUSTERS.CLUSTER]),
|
||||
},
|
||||
{
|
||||
header: T.Hosts,
|
||||
id: 'hosts',
|
||||
accessor: ({ HOSTS }) =>
|
||||
useMemo(() => {
|
||||
const { HOST: hostsInfo = [] } = HOSTS
|
||||
const hostsArray = (
|
||||
Array.isArray(hostsInfo) ? hostsInfo : [hostsInfo]
|
||||
).map((host) => host.HOST_ID)
|
||||
|
||||
return isAllSelected(hostsArray) ? T.All : hostsArray.length
|
||||
}, [HOSTS.HOST]),
|
||||
},
|
||||
{
|
||||
header: T.Vnets,
|
||||
id: 'vnets',
|
||||
accessor: ({ VNETS }) =>
|
||||
useMemo(() => {
|
||||
const { VNET: vnetsInfo = [] } = VNETS
|
||||
const vnetsArray = (
|
||||
Array.isArray(vnetsInfo) ? vnetsInfo : [vnetsInfo]
|
||||
).map((vnet) => vnet.VNET_ID)
|
||||
|
||||
return isAllSelected(vnetsArray) ? T.All : vnetsArray.length
|
||||
}, [VNETS.VNET]),
|
||||
},
|
||||
{
|
||||
header: T.Datastores,
|
||||
id: 'datastores',
|
||||
accessor: ({ DATASTORES }) =>
|
||||
useMemo(() => {
|
||||
const { DATASTORE: datastoresInfo = [] } = DATASTORES
|
||||
const datastoresArray = (
|
||||
Array.isArray(datastoresInfo) ? datastoresInfo : [datastoresInfo]
|
||||
).map((ds) => ds.DATASTORE_ID)
|
||||
|
||||
return isAllSelected(datastoresArray) ? T.All : datastoresArray.length
|
||||
}, [DATASTORES.DATASTORE]),
|
||||
},
|
||||
]
|
||||
const { component, header } = WrapperRow(VDCRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -55,7 +127,8 @@ const VDCsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VDCRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import vdcApi, { useUpdateVDCMutation } from 'client/features/OneApi/vdc'
|
||||
import { VirtualDataCenterCard } from 'client/components/Cards'
|
||||
import vdcApi, { useUpdateVDCMutation } from 'client/features/OneApi/vdc'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateVDCMutation()
|
||||
|
||||
const state = vdcApi.endpoints.getVDCs.useQueryState(undefined, {
|
||||
@ -62,6 +62,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VirtualDataCenterRow'
|
||||
|
@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useMemo } from 'react'
|
||||
|
||||
import { DiskCard } from 'client/components/Cards'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, ...props }) => {
|
||||
({ original, value, headerList, ...props }) => {
|
||||
const memoDisk = useMemo(() => original, [original])
|
||||
|
||||
return <DiskCard disk={memoDisk} rootProps={props} />
|
||||
@ -33,6 +33,7 @@ Row.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VmDiskRow'
|
||||
|
@ -15,13 +15,13 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useEffect, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVMGroupsQuery } from 'client/features/OneApi/vmGroup'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VmGroupColumns from 'client/components/Tables/VmGroups/columns'
|
||||
import VmGroupRow from 'client/components/Tables/VmGroups/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVMGroupsQuery } from 'client/features/OneApi/vmGroup'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vmgroups'
|
||||
|
||||
@ -48,6 +48,15 @@ const VmGroupsTable = (props) => {
|
||||
|
||||
useEffect(() => refetch(), [])
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VmGroupRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -57,7 +66,8 @@ const VmGroupsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VmGroupRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import { VmGroupCard } from 'client/components/Cards'
|
||||
|
||||
const Row = ({ original, value, ...props }) => (
|
||||
const Row = ({ original, value, headerList, ...props }) => (
|
||||
<VmGroupCard rootProps={props} vmgroup={value} />
|
||||
)
|
||||
|
||||
@ -27,6 +27,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -15,13 +15,14 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useEffect, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetTemplatesQuery } from 'client/features/OneApi/vmTemplate'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VmTemplateColumns from 'client/components/Tables/VmTemplates/columns'
|
||||
import VmTemplateRow from 'client/components/Tables/VmTemplates/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetTemplatesQuery } from 'client/features/OneApi/vmTemplate'
|
||||
import { timeToString } from 'client/models/Helper'
|
||||
|
||||
const DEFAULT_DATA_CY = 'vm-templates'
|
||||
|
||||
@ -47,6 +48,20 @@ const VmTemplatesTable = (props) => {
|
||||
)
|
||||
useEffect(() => refetch(), [])
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.RegistrationTime,
|
||||
id: 'registration-time',
|
||||
accessor: (vm) => timeToString(vm.REGTIME),
|
||||
},
|
||||
]
|
||||
|
||||
const { component, header } = WrapperRow(VmTemplateRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -56,7 +71,8 @@ const VmTemplatesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VmTemplateRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -13,17 +13,17 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useMemo, useCallback } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, useCallback, useMemo } from 'react'
|
||||
|
||||
import { VmTemplateCard } from 'client/components/Cards'
|
||||
import vmTemplateApi, {
|
||||
useUpdateTemplateMutation,
|
||||
} from 'client/features/OneApi/vmTemplate'
|
||||
import { VmTemplateCard } from 'client/components/Cards'
|
||||
import { jsonToXml } from 'client/models/Helper'
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, ...props }) => {
|
||||
({ original, value, onClickLabel, headerList, ...props }) => {
|
||||
const [update] = useUpdateTemplateMutation()
|
||||
|
||||
const state = vmTemplateApi.endpoints.getTemplates.useQueryState(
|
||||
@ -67,6 +67,7 @@ Row.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VmTemplateRow'
|
||||
|
@ -15,21 +15,29 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetVmsQuery } from 'client/features/OneApi/vm'
|
||||
|
||||
import { ConsoleButton } from 'client/components/Buttons'
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import VmColumns from 'client/components/Tables/Vms/columns'
|
||||
import VmRow from 'client/components/Tables/Vms/row'
|
||||
import {
|
||||
RESOURCE_NAMES,
|
||||
STATES,
|
||||
T,
|
||||
VM_ACTIONS,
|
||||
VM_EXTENDED_POOL,
|
||||
VM_STATES,
|
||||
} from 'client/constants'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGeneral } from 'client/features/General'
|
||||
import { useGetVmsQuery } from 'client/features/OneApi/vm'
|
||||
import { getIps, getLastHistory, getState } from 'client/models/VirtualMachine'
|
||||
const DEFAULT_DATA_CY = 'vms'
|
||||
|
||||
const { VNC, RDP, SSH, VMRC } = VM_ACTIONS
|
||||
const CONNECTION_TYPES = [VNC, RDP, SSH, VMRC]
|
||||
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @returns {ReactElement} Virtual Machines table
|
||||
@ -121,6 +129,66 @@ const VmsTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const { zone, defaultZone } = useGeneral()
|
||||
const listHeader = [
|
||||
{
|
||||
header: '',
|
||||
id: 'status-icon',
|
||||
accessor: (vm) => {
|
||||
const {
|
||||
color: stateColor,
|
||||
name: stateName,
|
||||
displayName: stateDisplayName,
|
||||
} = getState(vm)
|
||||
|
||||
return (
|
||||
<StatusCircle
|
||||
color={stateColor}
|
||||
tooltip={stateDisplayName ?? stateName}
|
||||
/>
|
||||
)
|
||||
},
|
||||
},
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Owner, id: 'owner', accessor: 'UNAME' },
|
||||
{ header: T.Group, id: 'group', accessor: 'GNAME' },
|
||||
{
|
||||
header: T.State,
|
||||
id: 'state',
|
||||
accessor: (vm) => getState(vm)?.name,
|
||||
},
|
||||
{
|
||||
header: T.Hostname,
|
||||
id: 'hostname',
|
||||
accessor: (vm) => getLastHistory(vm)?.HOSTNAME,
|
||||
},
|
||||
{
|
||||
header: T.IP,
|
||||
id: 'ips',
|
||||
accessor: (vm) => getIps(vm).join(),
|
||||
},
|
||||
]
|
||||
|
||||
zone === defaultZone &&
|
||||
listHeader.push({
|
||||
header: '',
|
||||
id: 'consoles',
|
||||
accessor: (vm) => (
|
||||
<>
|
||||
{CONNECTION_TYPES.map((connectionType) => (
|
||||
<ConsoleButton
|
||||
key={`${vm}-${connectionType}`}
|
||||
connectionType={connectionType}
|
||||
vm={vm}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
})
|
||||
|
||||
const { component, header } = WrapperRow(VmRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -130,8 +198,9 @@ const VmsTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={VmRow}
|
||||
initialState={initialState}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ const { VNC, RDP, SSH, VMRC } = VM_ACTIONS
|
||||
const CONNECTION_TYPES = [VNC, RDP, SSH, VMRC]
|
||||
|
||||
const Row = memo(
|
||||
({ original, value, onClickLabel, globalErrors, ...props }) => {
|
||||
({ original, value, onClickLabel, globalErrors, headerList, ...props }) => {
|
||||
// This is for not showing VNC coneections when the user use other zone.
|
||||
const { zone, defaultZone } = useGeneral()
|
||||
|
||||
@ -88,6 +88,7 @@ Row.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
onClickLabel: PropTypes.func,
|
||||
globalErrors: PropTypes.array,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'VirtualMachineRow'
|
||||
|
@ -13,8 +13,8 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, ReactElement } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, ReactElement } from 'react'
|
||||
|
||||
import { Typography } from '@mui/material'
|
||||
|
||||
@ -28,7 +28,7 @@ import { Row as RowType } from 'react-table'
|
||||
* @param {Function} props.handleClick - Action by click
|
||||
* @returns {ReactElement} - Table row
|
||||
*/
|
||||
const Row = memo(({ original, ...props }) => {
|
||||
const Row = memo(({ original, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { DEPLOY_ID, VM_NAME } = original
|
||||
|
||||
@ -52,6 +52,7 @@ Row.propTypes = {
|
||||
original: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'WildsRow'
|
||||
|
@ -13,8 +13,8 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, ReactElement } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { memo, ReactElement } from 'react'
|
||||
|
||||
import { Typography } from '@mui/material'
|
||||
|
||||
@ -28,7 +28,7 @@ import { Row as RowType } from 'react-table'
|
||||
* @param {Function} props.handleClick - Action by click
|
||||
* @returns {ReactElement} - Table row
|
||||
*/
|
||||
const Row = memo(({ original, ...props }) => {
|
||||
const Row = memo(({ original, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { DEPLOY_ID, VM_NAME } = original
|
||||
|
||||
@ -49,6 +49,7 @@ Row.propTypes = {
|
||||
original: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
Row.displayName = 'ZombiesRow'
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { useMemo, ReactElement } from 'react'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetZonesQuery } from 'client/features/OneApi/zone'
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
|
||||
import EnhancedTable, { createColumns } from 'client/components/Tables/Enhanced'
|
||||
import WrapperRow from 'client/components/Tables/Enhanced/WrapperRow'
|
||||
import ZoneColumns from 'client/components/Tables/Zones/columns'
|
||||
import ZoneRow from 'client/components/Tables/Zones/row'
|
||||
import { RESOURCE_NAMES } from 'client/constants'
|
||||
import { RESOURCE_NAMES, T } from 'client/constants'
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGetZonesQuery } from 'client/features/OneApi/zone'
|
||||
|
||||
const DEFAULT_DATA_CY = 'zones'
|
||||
|
||||
@ -46,6 +46,13 @@ const ZonesTable = (props) => {
|
||||
[view]
|
||||
)
|
||||
|
||||
const listHeader = [
|
||||
{ header: T.ID, id: 'id', accessor: 'ID' },
|
||||
{ header: T.Name, id: 'name', accessor: 'NAME' },
|
||||
{ header: T.Endpoint, id: 'endpoint', accessor: 'TEMPLATE.ENDPOINT' },
|
||||
]
|
||||
const { component, header } = WrapperRow(ZoneRow)
|
||||
|
||||
return (
|
||||
<EnhancedTable
|
||||
columns={columns}
|
||||
@ -55,7 +62,8 @@ const ZonesTable = (props) => {
|
||||
refetch={refetch}
|
||||
isLoading={isFetching}
|
||||
getRowId={(row) => String(row.ID)}
|
||||
RowComponent={ZoneRow}
|
||||
RowComponent={component}
|
||||
headerList={header && listHeader}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
|
@ -17,15 +17,15 @@
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { Typography } from '@mui/material'
|
||||
import { HomeShield } from 'iconoir-react'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
import { T } from 'client/constants'
|
||||
import { StatusCircle } from 'client/components/Status'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
import { T } from 'client/constants'
|
||||
import { HomeShield } from 'iconoir-react'
|
||||
|
||||
import * as ZoneModel from 'client/models/Zone'
|
||||
|
||||
const Row = ({ original, value, ...props }) => {
|
||||
const Row = ({ original, value, headerList, ...props }) => {
|
||||
const classes = rowStyles()
|
||||
const { ID, NAME, ENDPOINT } = value
|
||||
|
||||
@ -57,6 +57,7 @@ Row.propTypes = {
|
||||
value: PropTypes.object,
|
||||
isSelected: PropTypes.bool,
|
||||
handleClick: PropTypes.func,
|
||||
headerList: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||
}
|
||||
|
||||
export default Row
|
||||
|
@ -427,6 +427,9 @@ module.exports = {
|
||||
|
||||
/* sections - settings */
|
||||
Settings: 'Settings',
|
||||
AppliesTo: 'Applies To',
|
||||
AllowedOperations: 'Allowed operations',
|
||||
AffectedResources: 'Affected resources',
|
||||
Schema: 'Schema',
|
||||
Dark: 'Dark',
|
||||
Light: 'Light',
|
||||
@ -591,6 +594,7 @@ module.exports = {
|
||||
Zone: 'Zone',
|
||||
Zones: 'Zones',
|
||||
Vnet: 'Vnet',
|
||||
Vnets: 'Vnets',
|
||||
'cluster.form.create.general.help.title': 'Cluster',
|
||||
'cluster.form.create.general.help.paragraph.1.1':
|
||||
'Clusters group together hosts, datastores and virtual networks that are configured to work together. A cluster is used to:',
|
||||
@ -929,6 +933,7 @@ module.exports = {
|
||||
Reconnect: 'Reconnect',
|
||||
FullScreen: 'Full screen',
|
||||
FullScreenInfo: 'Full screen information in datatables',
|
||||
RowStyle: 'DataTables Row Style',
|
||||
Screenshot: 'Screenshot',
|
||||
LastConnection: 'Last connection',
|
||||
PartOf: 'Part of',
|
||||
@ -1485,6 +1490,7 @@ module.exports = {
|
||||
AutomaticDeletion: 'Automatic deletion',
|
||||
Role: 'Role',
|
||||
Roles: 'Roles',
|
||||
Card: 'Card',
|
||||
Cardinality: 'Cardinality',
|
||||
Parents: 'Parents',
|
||||
ParentRoles: 'Parent roles',
|
||||
|
@ -119,6 +119,22 @@ const FULL_SCREEN_INFO_FIELD = {
|
||||
grid: { md: 12 },
|
||||
}
|
||||
|
||||
const ROW_STYLE_FIELD = {
|
||||
name: 'ROW_STYLE',
|
||||
label: T.RowStyle,
|
||||
type: INPUT_TYPES.AUTOCOMPLETE,
|
||||
optionsOnly: true,
|
||||
values: [
|
||||
{ text: T.Card, value: 'card' },
|
||||
{ text: T.List, value: 'list' },
|
||||
],
|
||||
validation: string()
|
||||
.trim()
|
||||
.required()
|
||||
.default(() => 'card'),
|
||||
grid: { md: 12 },
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @param {object} props.views - views.
|
||||
@ -131,6 +147,7 @@ export const FIELDS = (props) => [
|
||||
LANG_FIELD,
|
||||
VIEW_FIELD(props),
|
||||
ZONE_ENDPOINT_FIELD(props),
|
||||
ROW_STYLE_FIELD,
|
||||
DISABLE_ANIMATIONS_FIELD,
|
||||
FULL_SCREEN_INFO_FIELD,
|
||||
]
|
||||
|
@ -43,7 +43,7 @@ const Settings = () => {
|
||||
<Box
|
||||
display="grid"
|
||||
gridTemplateColumns={{ sm: '1fr', md: 'repeat(2, minmax(49%, 1fr))' }}
|
||||
gridTemplateRows="minmax(0, 33em)"
|
||||
gridTemplateRows="minmax(0, 36em)"
|
||||
gap="1em"
|
||||
>
|
||||
<ConfigurationUISection />
|
||||
|
Loading…
x
Reference in New Issue
Block a user