mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
F OpenNebula/one#5422: Add context to vm tabs
This commit is contained in:
parent
54744e9875
commit
1d5a8f59b3
@ -63,10 +63,10 @@ const Attribute = React.memo(({
|
||||
}
|
||||
|
||||
const handleActiveEditForm = async () => {
|
||||
const response = await handleGetOptionList?.()
|
||||
const response = await handleGetOptionList?.() ?? []
|
||||
const isFormatValid = response?.every?.(({ text, value } = {}) => !!text && !!value)
|
||||
|
||||
if (isFormatValid) {
|
||||
if (!handleGetOptionList || isFormatValid) {
|
||||
setOptions(response)
|
||||
setIsEditing(true)
|
||||
}
|
||||
@ -79,25 +79,31 @@ const Attribute = React.memo(({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography noWrap variant='body2'>
|
||||
<Typography noWrap variant='body2' title={Tr(name)}>
|
||||
{Tr(name)}
|
||||
</Typography>
|
||||
<div className={classes.wrapper}>
|
||||
{isEditing ? (
|
||||
<>
|
||||
{handleGetOptionList && (
|
||||
{handleGetOptionList ? (
|
||||
<Inputs.Select
|
||||
name={name}
|
||||
value={valueInOptionList}
|
||||
ref={inputRef}
|
||||
options={options} />
|
||||
) : (
|
||||
<Inputs.Text name={name} value={value} ref={inputRef} />
|
||||
)}
|
||||
<Actions.Accept name={name} handleClick={handleEditAttribute} />
|
||||
<Actions.Cancel name={name} handleClick={handleCancel} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Typography noWrap variant='body2'>
|
||||
<Typography
|
||||
noWrap
|
||||
variant='body2'
|
||||
title={typeof value === 'string' ? value : undefined}
|
||||
>
|
||||
{value}
|
||||
</Typography>
|
||||
{canEdit && (
|
||||
|
@ -82,4 +82,41 @@ Select.propTypes = {
|
||||
)
|
||||
}
|
||||
|
||||
export { Select }
|
||||
const Text = React.forwardRef(
|
||||
/**
|
||||
* @param {object} props - Props
|
||||
* @param {string} props.name - Attribute name
|
||||
* @param {string} props.value - Attribute value
|
||||
* @param {React.ForwardedRef} ref - Forward reference
|
||||
* @returns {React.JSXElementConstructor} Text field
|
||||
*/
|
||||
({ name = '', value = '' }, ref) => {
|
||||
console.log({ name, value })
|
||||
const [newValue, setNewValue] = React.useState(() => value)
|
||||
|
||||
const handleChange = event => setNewValue(event.target.value)
|
||||
|
||||
return (
|
||||
<TextField
|
||||
color='secondary'
|
||||
inputProps={{
|
||||
'data-cy': Actions.getAttributeCy('text', name)
|
||||
}}
|
||||
inputRef={ref}
|
||||
margin='dense'
|
||||
onChange={handleChange}
|
||||
value={newValue}
|
||||
variant='outlined'
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
Text.displayName = 'Text'
|
||||
|
||||
Text.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
export { Select, Text }
|
||||
|
@ -19,6 +19,7 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import { makeStyles, List as MList, ListItem, Typography, Paper } from '@material-ui/core'
|
||||
|
||||
import Attribute from 'client/components/Tabs/Common/Attribute'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
@ -27,7 +28,7 @@ const useStyles = makeStyles(theme => ({
|
||||
borderBottom: `1px solid ${theme.palette.divider}`
|
||||
},
|
||||
item: {
|
||||
'& > $typo': {
|
||||
'& > *': {
|
||||
width: '50%'
|
||||
}
|
||||
},
|
||||
@ -49,18 +50,12 @@ const List = ({ title, list = [], ...props }) => {
|
||||
</ListItem>
|
||||
)}
|
||||
{/* LIST */}
|
||||
{list.map(({ key, value }, idx) => (
|
||||
<ListItem key={`${key}-${idx}`} className={classes.item}>
|
||||
<Typography className={classes.typo} noWrap title={key}>
|
||||
{Tr(key)}
|
||||
</Typography>
|
||||
<Typography
|
||||
noWrap
|
||||
className={classes.typo}
|
||||
title={typeof value === 'string' ? value : undefined}
|
||||
>
|
||||
{value}
|
||||
</Typography>
|
||||
{list.map((attribute, idx) => (
|
||||
<ListItem
|
||||
key={`${attribute.name}-${idx}`}
|
||||
className={classes.item}
|
||||
>
|
||||
<Attribute {...attribute}/>
|
||||
</ListItem>
|
||||
))}
|
||||
</MList>
|
||||
@ -71,8 +66,14 @@ const List = ({ title, list = [], ...props }) => {
|
||||
List.propTypes = {
|
||||
title: PropTypes.string,
|
||||
list: PropTypes.arrayOf(PropTypes.shape({
|
||||
key: PropTypes.string,
|
||||
value: PropTypes.any
|
||||
canDelete: PropTypes.bool,
|
||||
canEdit: PropTypes.bool,
|
||||
handleEdit: PropTypes.func,
|
||||
handleDelete: PropTypes.func,
|
||||
handleGetOptionList: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.any.isRequired,
|
||||
valueInOptionList: PropTypes.string.isRequired
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -64,35 +64,25 @@ const Ownership = React.memo(({
|
||||
)
|
||||
}
|
||||
|
||||
const ownership = [
|
||||
{
|
||||
key: T.Owner,
|
||||
value: userName,
|
||||
valueInOptionList: userId,
|
||||
handleGetOptionList: getUserOptions,
|
||||
handleEdit: user => handleEdit?.({ user })
|
||||
},
|
||||
{
|
||||
key: T.Group,
|
||||
value: groupName,
|
||||
valueInOptionList: groupId,
|
||||
handleGetOptionList: getGroupOptions,
|
||||
handleEdit: group => handleEdit?.({ group })
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<Paper variant='outlined'>
|
||||
<List>
|
||||
<ListItem className={classes.title}>
|
||||
<Typography noWrap>{Tr(T.Ownership)}</Typography>
|
||||
</ListItem>
|
||||
<Divider />
|
||||
<ListItem className={classes.item}>
|
||||
<Attribute
|
||||
canEdit
|
||||
name={T.Owner}
|
||||
value={userName}
|
||||
valueInOptionList={userId}
|
||||
handleGetOptionList={getUserOptions}
|
||||
handleEdit={user => handleEdit?.({ user })}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem className={classes.item}>
|
||||
<Attribute
|
||||
canEdit
|
||||
name={T.Group}
|
||||
value={groupName}
|
||||
valueInOptionList={groupId}
|
||||
handleGetOptionList={getGroupOptions}
|
||||
handleEdit={group => handleEdit?.({ group })}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Paper>
|
||||
<List title={T.Ownership} list={ownership} />
|
||||
)
|
||||
})
|
||||
|
||||
|
45
src/fireedge/src/client/components/Tabs/TabProvider.js
Normal file
45
src/fireedge/src/client/components/Tabs/TabProvider.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Copyright 2002-2021, 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. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import React, { createContext, useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export const TabContext = createContext(null)
|
||||
|
||||
const TabProvider = ({ initialState = {}, children }) => {
|
||||
const [information, setTabInformation] = useState(() => initialState)
|
||||
const { data } = initialState
|
||||
|
||||
React.useEffect(() => {
|
||||
data && setTabInformation(prev => ({ ...prev, data }))
|
||||
}, [data])
|
||||
|
||||
return (
|
||||
<TabContext.Provider value={{ ...information, setTabInformation }}>
|
||||
{children}
|
||||
</TabContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
TabProvider.propTypes = {
|
||||
initialState: PropTypes.object,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.node,
|
||||
PropTypes.arrayOf(PropTypes.node)
|
||||
])
|
||||
}
|
||||
|
||||
export default TabProvider
|
@ -17,6 +17,7 @@
|
||||
import * as React from 'react'
|
||||
import { makeStyles, Paper, Typography } from '@material-ui/core'
|
||||
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
import { Action } from 'client/components/Cards/SelectCard'
|
||||
import * as VirtualMachine from 'client/models/VirtualMachine'
|
||||
import { prettyBytes } from 'client/utils'
|
||||
@ -56,12 +57,13 @@ const useStyles = makeStyles(theme => ({
|
||||
}
|
||||
}))
|
||||
|
||||
const VmCapacityTab = data => {
|
||||
const VmCapacityTab = () => {
|
||||
const classes = useStyles()
|
||||
|
||||
const { TEMPLATE } = data
|
||||
const { data: vm = {} } = React.useContext(TabContext)
|
||||
const { TEMPLATE } = vm
|
||||
|
||||
const isVCenter = VirtualMachine.isVCenter(data)
|
||||
const isVCenter = VirtualMachine.isVCenter(vm)
|
||||
|
||||
const capacity = [
|
||||
{ key: 'Physical CPU', value: TEMPLATE?.CPU },
|
||||
|
@ -17,10 +17,12 @@
|
||||
import * as React from 'react'
|
||||
import { Accordion, AccordionSummary, AccordionDetails } from '@material-ui/core'
|
||||
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
|
||||
const NavArrowDown = <span style={{ writingMode: 'vertical-rl' }}>{'>'}</span>
|
||||
|
||||
const VmConfigurationTab = data => {
|
||||
const { TEMPLATE, USER_TEMPLATE } = data
|
||||
const { data: { TEMPLATE, USER_TEMPLATE } = {} } = React.useContext(TabContext)
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -19,11 +19,13 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import { useVmApi } from 'client/features/One'
|
||||
import { Permissions, Ownership } from 'client/components/Tabs/Common'
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
import Information from 'client/components/Tabs/Vm/Info/information'
|
||||
|
||||
const VmInfoTab = ({ tabProps, handleRefetch, ...data }) => {
|
||||
const { ID, UNAME, UID, GNAME, GID, PERMISSIONS } = data
|
||||
const VmInfoTab = ({ tabProps }) => {
|
||||
const { changeOwnership } = useVmApi()
|
||||
const { handleRefetch, data } = React.useContext(TabContext)
|
||||
const { ID, UNAME, UID, GNAME, GID, PERMISSIONS } = data
|
||||
|
||||
const handleChangeOwnership = async newOwnership => {
|
||||
const response = await changeOwnership(ID, newOwnership)
|
||||
@ -58,8 +60,7 @@ const VmInfoTab = ({ tabProps, handleRefetch, ...data }) => {
|
||||
}
|
||||
|
||||
VmInfoTab.propTypes = {
|
||||
tabProps: PropTypes.object,
|
||||
handleRefetch: PropTypes.func
|
||||
tabProps: PropTypes.object
|
||||
}
|
||||
|
||||
VmInfoTab.displayName = 'VmInfoTab'
|
||||
|
@ -35,42 +35,49 @@ const InformationPanel = data => {
|
||||
const ips = VirtualMachine.getIps(data)
|
||||
|
||||
const info = [
|
||||
{ key: T.ID, value: ID },
|
||||
{ key: T.Name, value: NAME },
|
||||
{ name: T.ID, value: ID },
|
||||
{
|
||||
key: T.State,
|
||||
name: T.Name,
|
||||
value: NAME,
|
||||
canEdit: true,
|
||||
handleEdit: newName => {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
name: T.State,
|
||||
value: <StatusChip text={stateName} stateColor={stateColor} />
|
||||
},
|
||||
{
|
||||
key: T.Reschedule,
|
||||
name: T.Reschedule,
|
||||
value: Helper.booleanToString(+RESCHED)
|
||||
},
|
||||
{
|
||||
key: T.Locked,
|
||||
name: T.Locked,
|
||||
value: Helper.levelLockToString(LOCK?.LOCKED)
|
||||
},
|
||||
{
|
||||
key: T.IP,
|
||||
name: T.IP,
|
||||
value: ips?.length ? <Multiple tags={ips} /> : '--'
|
||||
},
|
||||
{
|
||||
key: T.StartTime,
|
||||
name: T.StartTime,
|
||||
value: Helper.timeToString(STIME)
|
||||
},
|
||||
{
|
||||
key: T.EndTime,
|
||||
name: T.EndTime,
|
||||
value: Helper.timeToString(ETIME)
|
||||
},
|
||||
{
|
||||
key: T.Host,
|
||||
name: T.Host,
|
||||
value: hostId ? `#${hostId} ${hostname}` : ''
|
||||
},
|
||||
{
|
||||
key: T.Cluster,
|
||||
name: T.Cluster,
|
||||
value: clusterId ? `#${clusterId} ${clusterName}` : ''
|
||||
},
|
||||
{
|
||||
key: T.DeployID,
|
||||
name: T.DeployID,
|
||||
value: DEPLOY_ID
|
||||
}
|
||||
]
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
import { useVmApi } from 'client/features/One'
|
||||
import { Action } from 'client/components/Cards/SelectCard'
|
||||
import Multiple from 'client/components/Tables/Vms/multiple'
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
|
||||
import { T, VM_ACTIONS } from 'client/constants'
|
||||
import { Tr } from 'client/components/HOC'
|
||||
@ -84,9 +85,11 @@ const useStyles = makeStyles(({
|
||||
}
|
||||
}))
|
||||
|
||||
const NetworkItem = ({ vmId, handleRefetch, nic = {}, actions }) => {
|
||||
const NetworkItem = ({ nic = {}, actions }) => {
|
||||
const classes = useStyles()
|
||||
const isMobile = useMediaQuery(theme => theme.breakpoints.down('sm'))
|
||||
|
||||
const { handleRefetch, data: vm } = React.useContext(TabContext)
|
||||
const { detachNic } = useVmApi()
|
||||
|
||||
const { NIC_ID, NETWORK = '-', BRIDGE, IP, MAC, PCI_ID, ALIAS, SECURITY_GROUPS } = nic
|
||||
@ -96,15 +99,15 @@ const NetworkItem = ({ vmId, handleRefetch, nic = {}, actions }) => {
|
||||
[ALIAS.length, SECURITY_GROUPS?.length]
|
||||
)
|
||||
|
||||
const detachAction = () => actions.includes(VM_ACTIONS.DETACH_NIC) && (
|
||||
const detachAction = () => actions?.includes?.(VM_ACTIONS.DETACH_NIC) && (
|
||||
<Action
|
||||
cy={`${VM_ACTIONS.DETACH_NIC}-${NIC_ID}`}
|
||||
icon={<Trash size={18} />}
|
||||
stopPropagation
|
||||
handleClick={async () => {
|
||||
const response = await detachNic(vmId, NIC_ID)
|
||||
const response = await detachNic(vm.ID, NIC_ID)
|
||||
|
||||
String(response) === String(vmId) && handleRefetch?.(vmId)
|
||||
String(response) === String(vm.ID) && handleRefetch?.(vm.ID)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
@ -169,8 +172,6 @@ const NetworkItem = ({ vmId, handleRefetch, nic = {}, actions }) => {
|
||||
|
||||
NetworkItem.propTypes = {
|
||||
actions: PropTypes.arrayOf(PropTypes.string),
|
||||
handleRefetch: PropTypes.func,
|
||||
vmId: PropTypes.string,
|
||||
nic: PropTypes.object
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import NetworkItem from 'client/components/Tabs/Vm/Network/Item'
|
||||
|
||||
const NetworkList = ({ vmId, handleRefetch, nics, actions }) => (
|
||||
const NetworkList = ({ nics, actions }) => (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
@ -27,21 +27,13 @@ const NetworkList = ({ vmId, handleRefetch, nics, actions }) => (
|
||||
paddingBlock: '0.8em'
|
||||
}}>
|
||||
{nics.map((nic, idx) => (
|
||||
<NetworkItem
|
||||
key={idx}
|
||||
actions={actions}
|
||||
handleRefetch={handleRefetch}
|
||||
nic={nic}
|
||||
vmId={vmId}
|
||||
/>
|
||||
<NetworkItem key={idx} actions={actions} nic={nic} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
NetworkList.propTypes = {
|
||||
actions: PropTypes.arrayOf(PropTypes.string),
|
||||
handleRefetch: PropTypes.func,
|
||||
vmId: PropTypes.string,
|
||||
nics: PropTypes.array
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,12 @@ import * as React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import NetworkList from 'client/components/Tabs/Vm/Network/List'
|
||||
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
import * as VirtualMachine from 'client/models/VirtualMachine'
|
||||
import * as Helper from 'client/models/Helper'
|
||||
|
||||
const VmNetworkTab = ({ tabProps, handleRefetch, ...vm }) => {
|
||||
const VmNetworkTab = ({ tabProps }) => {
|
||||
const { data: vm } = React.useContext(TabContext)
|
||||
const { actions = [] } = tabProps
|
||||
|
||||
const nics = VirtualMachine.getNics(vm, {
|
||||
@ -34,18 +35,12 @@ const VmNetworkTab = ({ tabProps, handleRefetch, ...vm }) => {
|
||||
const actionsAvailable = Helper.getActionsAvailable(actions, hypervisor)
|
||||
|
||||
return (
|
||||
<NetworkList
|
||||
vmId={vm.ID}
|
||||
actions={actionsAvailable}
|
||||
nics={nics}
|
||||
handleRefetch={handleRefetch}
|
||||
/>
|
||||
<NetworkList actions={actionsAvailable} nics={nics} />
|
||||
)
|
||||
}
|
||||
|
||||
VmNetworkTab.propTypes = {
|
||||
tabProps: PropTypes.object,
|
||||
handleRefetch: PropTypes.func
|
||||
tabProps: PropTypes.object
|
||||
}
|
||||
|
||||
VmNetworkTab.displayName = 'VmNetworkTab'
|
||||
|
@ -22,11 +22,7 @@ import StorageItem from 'client/components/Tabs/Vm/Storage/Item'
|
||||
const StorageList = ({ disks, actions }) => (
|
||||
<div style={{ display: 'grid', gap: '1em', paddingBlock: '0.8em' }}>
|
||||
{disks.map((disk, idx) => (
|
||||
<StorageItem
|
||||
key={idx}
|
||||
disk={disk}
|
||||
actions={actions}
|
||||
/>
|
||||
<StorageItem key={idx} disk={disk} actions={actions} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
@ -18,15 +18,17 @@ import * as React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import StorageList from 'client/components/Tabs/Vm/Storage/List'
|
||||
|
||||
import { TabContext } from 'client/components/Tabs/TabProvider'
|
||||
import * as VirtualMachine from 'client/models/VirtualMachine'
|
||||
import * as Helper from 'client/models/Helper'
|
||||
|
||||
const VmStorageTab = ({ tabProps, ...data }) => {
|
||||
const VmStorageTab = ({ tabProps = {} }) => {
|
||||
const { data: vm } = React.useContext(TabContext)
|
||||
const { actions = [] } = tabProps
|
||||
|
||||
const disks = VirtualMachine.getDisks(data)
|
||||
const hypervisor = VirtualMachine.getHypervisor(data)
|
||||
const disks = VirtualMachine.getDisks(vm)
|
||||
|
||||
const hypervisor = VirtualMachine.getHypervisor(vm)
|
||||
const actionsAvailable = Helper.getActionsAvailable(actions, hypervisor)
|
||||
|
||||
return (
|
||||
@ -35,10 +37,7 @@ const VmStorageTab = ({ tabProps, ...data }) => {
|
||||
}
|
||||
|
||||
VmStorageTab.propTypes = {
|
||||
tabProps: PropTypes.shape({
|
||||
actions: PropTypes.object
|
||||
}),
|
||||
actions: PropTypes.array
|
||||
tabProps: PropTypes.object
|
||||
}
|
||||
|
||||
VmStorageTab.displayName = 'VmStorageTab'
|
||||
|
@ -22,6 +22,7 @@ import { useAuth } from 'client/features/Auth'
|
||||
import Tabs from 'client/components/Tabs'
|
||||
import { stringToCamelCase, stringToCamelSpace } from 'client/utils'
|
||||
|
||||
import TabProvider from 'client/components/Tabs/TabProvider'
|
||||
import Capacity from 'client/components/Tabs/Vm/Capacity'
|
||||
import Configuration from 'client/components/Tabs/Vm/Configuration'
|
||||
import Info from 'client/components/Tabs/Vm/Info'
|
||||
@ -59,14 +60,17 @@ const VmTabs = ({ data, handleRefetch }) => {
|
||||
|
||||
return TabContent && {
|
||||
name: stringToCamelSpace(nameSanitize),
|
||||
renderContent:
|
||||
props => TabContent({ ...props, tabProps, handleRefetch })
|
||||
renderContent: props => TabContent({ ...props, tabProps })
|
||||
}
|
||||
})
|
||||
?.filter(Boolean))
|
||||
}, [view])
|
||||
|
||||
return <Tabs tabs={tabsAvailable} data={data} />
|
||||
return (
|
||||
<TabProvider initialState={{ data, handleRefetch }}>
|
||||
<Tabs tabs={tabsAvailable} />
|
||||
</TabProvider>
|
||||
)
|
||||
}
|
||||
|
||||
VmTabs.propTypes = {
|
||||
|
@ -19,7 +19,7 @@ import PropTypes from 'prop-types'
|
||||
|
||||
import { Tabs as MTabs, Tab as MTab } from '@material-ui/core'
|
||||
|
||||
const Content = ({ name, renderContent: Content, hidden, data }) => (
|
||||
const Content = ({ name, renderContent: Content, hidden }) => (
|
||||
<div key={`tab-${name}`}
|
||||
style={{
|
||||
padding: 2,
|
||||
@ -28,11 +28,11 @@ const Content = ({ name, renderContent: Content, hidden, data }) => (
|
||||
display: hidden ? 'none' : 'block'
|
||||
}}
|
||||
>
|
||||
{typeof Content === 'function' ? <Content {...data} /> : Content}
|
||||
{typeof Content === 'function' ? <Content /> : Content}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Tabs = ({ tabs = [], renderHiddenTabs = false, data }) => {
|
||||
const Tabs = ({ tabs = [], renderHiddenTabs = false }) => {
|
||||
const [tabSelected, setTab] = useState(0)
|
||||
|
||||
const renderTabs = useMemo(() => (
|
||||
@ -68,7 +68,7 @@ const Tabs = ({ tabs = [], renderHiddenTabs = false, data }) => {
|
||||
{renderHiddenTabs ? (
|
||||
renderAllHiddenTabContents
|
||||
) : (
|
||||
<Content data={data} {...tabs.find(({ value }, idx) => (value ?? idx) === tabSelected)} />
|
||||
<Content {...tabs.find(({ value }, idx) => (value ?? idx) === tabSelected)} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
@ -79,8 +79,7 @@ Content.displayName = 'Content'
|
||||
|
||||
Tabs.propTypes = {
|
||||
tabs: PropTypes.array,
|
||||
renderHiddenTabs: PropTypes.bool,
|
||||
data: PropTypes.object
|
||||
renderHiddenTabs: PropTypes.bool
|
||||
}
|
||||
|
||||
Content.propTypes = {
|
||||
@ -89,8 +88,7 @@ Content.propTypes = {
|
||||
PropTypes.object,
|
||||
PropTypes.func
|
||||
]),
|
||||
hidden: PropTypes.bool,
|
||||
data: PropTypes.object
|
||||
hidden: PropTypes.bool
|
||||
}
|
||||
|
||||
export default Tabs
|
||||
|
Loading…
x
Reference in New Issue
Block a user