Skip to content

Commit f3bb947

Browse files
F #7133: buttons added to individual resources (#3763)
1 parent 99c0e36 commit f3bb947

File tree

25 files changed

+299
-112
lines changed

25 files changed

+299
-112
lines changed

src/fireedge/src/modules/components/Tabs/Cluster/index.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,22 @@
1313
* See the License for the specific language governing permissions and *
1414
* limitations under the License. *
1515
* ------------------------------------------------------------------------- */
16+
import { OpenNebulaLogo } from '@modules/components/Icons'
1617
import { Alert, Stack } from '@mui/material'
1718
import PropTypes from 'prop-types'
1819
import { memo, useMemo } from 'react'
19-
import { OpenNebulaLogo } from '@modules/components/Icons'
2020

2121
import { RESOURCE_NAMES } from '@ConstantsModule'
22-
import { useViews, ClusterAPI } from '@FeaturesModule'
22+
import { ClusterAPI, useViews } from '@FeaturesModule'
2323
import { getAvailableInfoTabs } from '@ModelsModule'
2424

2525
import { BaseTab as Tabs } from '@modules/components/Tabs'
26-
import Info from '@modules/components/Tabs/Cluster/Info'
27-
import Hosts from '@modules/components/Tabs/Cluster/Hosts'
28-
import Vnets from '@modules/components/Tabs/Cluster/Vnets'
2926
import Datastores from '@modules/components/Tabs/Cluster/Datastores'
3027
import PlanOptimization from '@modules/components/Tabs/Cluster/Drs'
28+
import Hosts from '@modules/components/Tabs/Cluster/Hosts'
29+
import Info from '@modules/components/Tabs/Cluster/Info'
30+
import Vnets from '@modules/components/Tabs/Cluster/Vnets'
31+
import SingleDetailActions from '@modules/components/Tabs/SingleDetailActions'
3132

3233
const getTabComponent = (tabName) =>
3334
({
@@ -38,7 +39,7 @@ const getTabComponent = (tabName) =>
3839
drs: PlanOptimization,
3940
}[tabName])
4041

41-
const ClusterTabs = memo(({ id }) => {
42+
const ClusterTabs = memo(({ id, singleActions }) => {
4243
const { view, getResourceView } = useViews()
4344
const { isError, error, status, data } = ClusterAPI.useGetClusterQuery({ id })
4445

@@ -58,7 +59,15 @@ const ClusterTabs = memo(({ id }) => {
5859
}
5960

6061
if (status === 'fulfilled' || id === data?.ID) {
61-
return <Tabs addBorder tabs={tabsAvailable ?? []} />
62+
return (
63+
<>
64+
<SingleDetailActions
65+
selectedRows={data}
66+
singleActions={singleActions}
67+
/>
68+
<Tabs addBorder tabs={tabsAvailable ?? []} />
69+
</>
70+
)
6271
}
6372

6473
return (
@@ -71,7 +80,10 @@ const ClusterTabs = memo(({ id }) => {
7180
)
7281
})
7382

74-
ClusterTabs.propTypes = { id: PropTypes.string.isRequired }
83+
ClusterTabs.propTypes = {
84+
id: PropTypes.string.isRequired,
85+
singleActions: PropTypes.array.isRequired,
86+
}
7587
ClusterTabs.displayName = 'ClusterTabs'
7688

7789
export default ClusterTabs

src/fireedge/src/modules/components/Tabs/Datastore/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@
1313
* See the License for the specific language governing permissions and *
1414
* limitations under the License. *
1515
* ------------------------------------------------------------------------- */
16+
import { OpenNebulaLogo } from '@modules/components/Icons'
1617
import { Alert, Stack } from '@mui/material'
1718
import PropTypes from 'prop-types'
1819
import { memo, useMemo } from 'react'
19-
import { OpenNebulaLogo } from '@modules/components/Icons'
2020

2121
import { RESOURCE_NAMES } from '@ConstantsModule'
22-
import { useViews, DatastoreAPI } from '@FeaturesModule'
22+
import { DatastoreAPI, useViews } from '@FeaturesModule'
2323
import { getAvailableInfoTabs } from '@ModelsModule'
2424

2525
import { BaseTab as Tabs } from '@modules/components/Tabs'
2626
import Clusters from '@modules/components/Tabs/Datastore/Clusters'
2727
import Images from '@modules/components/Tabs/Datastore/Images'
2828
import Info from '@modules/components/Tabs/Datastore/Info'
29+
import SingleDetailActions from '@modules/components/Tabs/SingleDetailActions'
2930

3031
const getTabComponent = (tabName) =>
3132
({
@@ -34,7 +35,7 @@ const getTabComponent = (tabName) =>
3435
clusters: Clusters,
3536
}[tabName])
3637

37-
const DatastoreTabs = memo(({ id }) => {
38+
const DatastoreTabs = memo(({ id, singleActions }) => {
3839
const { view, getResourceView } = useViews()
3940
const { isError, error, status, data } = DatastoreAPI.useGetDatastoreQuery({
4041
id,
@@ -56,7 +57,15 @@ const DatastoreTabs = memo(({ id }) => {
5657
}
5758

5859
if (status === 'fulfilled' || id === data?.ID) {
59-
return <Tabs addBorder tabs={tabsAvailable ?? []} />
60+
return (
61+
<>
62+
<SingleDetailActions
63+
selectedRows={data}
64+
singleActions={singleActions}
65+
/>
66+
<Tabs addBorder tabs={tabsAvailable ?? []} />
67+
</>
68+
)
6069
}
6170

6271
return (
@@ -69,7 +78,10 @@ const DatastoreTabs = memo(({ id }) => {
6978
)
7079
})
7180

72-
DatastoreTabs.propTypes = { id: PropTypes.string.isRequired }
81+
DatastoreTabs.propTypes = {
82+
id: PropTypes.string.isRequired,
83+
singleActions: PropTypes.func,
84+
}
7385
DatastoreTabs.displayName = 'DatastoreTabs'
7486

7587
export default DatastoreTabs

src/fireedge/src/modules/components/Tabs/Group/index.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@
1313
* See the License for the specific language governing permissions and *
1414
* limitations under the License. *
1515
* ------------------------------------------------------------------------- */
16+
import { OpenNebulaLogo } from '@modules/components/Icons'
1617
import { Alert, Stack } from '@mui/material'
1718
import PropTypes from 'prop-types'
1819
import { memo, useMemo } from 'react'
19-
import { OpenNebulaLogo } from '@modules/components/Icons'
2020

2121
import { RESOURCE_NAMES } from '@ConstantsModule'
22-
import { useViews, GroupAPI } from '@FeaturesModule'
22+
import { GroupAPI, useViews } from '@FeaturesModule'
2323
import { getAvailableInfoTabs } from '@ModelsModule'
24-
2524
import { BaseTab as Tabs } from '@modules/components/Tabs'
25+
import generateAccountingInfoTab from '@modules/components/Tabs/Accounting'
2626
import Info from '@modules/components/Tabs/Group/Info'
2727
import GroupUsersTab from '@modules/components/Tabs/Group/Users'
2828
import generateQuotasInfoTab from '@modules/components/Tabs/Quota'
29-
import generateAccountingInfoTab from '@modules/components/Tabs/Accounting'
3029
import generateShowbackInfoTab from '@modules/components/Tabs/Showback'
30+
import SingleDetailActions from '@modules/components/Tabs/SingleDetailActions'
3131

3232
const getTabComponent = (tabName) =>
3333
({
@@ -38,7 +38,7 @@ const getTabComponent = (tabName) =>
3838
showback: generateShowbackInfoTab({ groups: true }),
3939
}[tabName])
4040

41-
const GroupTabs = memo(({ id }) => {
41+
const GroupTabs = memo(({ id, singleActions }) => {
4242
const { view, getResourceView } = useViews()
4343
const { isError, error, status, data } = GroupAPI.useGetGroupQuery({ id })
4444

@@ -58,7 +58,15 @@ const GroupTabs = memo(({ id }) => {
5858
}
5959

6060
if (status === 'fulfilled' || id === data?.ID) {
61-
return <Tabs addBorder tabs={tabsAvailable ?? []} />
61+
return (
62+
<>
63+
<SingleDetailActions
64+
selectedRows={data}
65+
singleActions={singleActions}
66+
/>
67+
<Tabs addBorder tabs={tabsAvailable ?? []} />
68+
</>
69+
)
6270
}
6371

6472
return (
@@ -71,7 +79,10 @@ const GroupTabs = memo(({ id }) => {
7179
)
7280
})
7381

74-
GroupTabs.propTypes = { id: PropTypes.string.isRequired }
82+
GroupTabs.propTypes = {
83+
id: PropTypes.string.isRequired,
84+
singleActions: PropTypes.func,
85+
}
7586
GroupTabs.displayName = 'GroupTabs'
7687

7788
export default GroupTabs

src/fireedge/src/modules/components/Tabs/Host/index.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ import PropTypes from 'prop-types'
1818
import { memo, useMemo } from 'react'
1919

2020
import { RESOURCE_NAMES } from '@ConstantsModule'
21-
import { useViews, HostAPI } from '@FeaturesModule'
21+
import { HostAPI, useViews } from '@FeaturesModule'
2222
import { getAvailableInfoTabs } from '@ModelsModule'
2323

24+
import { OpenNebulaLogo } from '@modules/components/Icons'
2425
import { BaseTab as Tabs } from '@modules/components/Tabs'
25-
import Info from '@modules/components/Tabs/Host/Info'
2626
import Graph from '@modules/components/Tabs/Host/Graphs'
27-
import PCI from '@modules/components/Tabs/Host/PCI'
27+
import Info from '@modules/components/Tabs/Host/Info'
2828
import Numa from '@modules/components/Tabs/Host/Numa'
29+
import PCI from '@modules/components/Tabs/Host/PCI'
2930
import Vms from '@modules/components/Tabs/Host/Vms'
3031
import Wilds from '@modules/components/Tabs/Host/Wilds'
3132
import Zombies from '@modules/components/Tabs/Host/Zombies'
32-
import { OpenNebulaLogo } from '@modules/components/Icons'
33+
import SingleDetailActions from '@modules/components/Tabs/SingleDetailActions'
3334

3435
const getTabComponent = (tabName) =>
3536
({
@@ -42,7 +43,7 @@ const getTabComponent = (tabName) =>
4243
zombies: Zombies,
4344
}[tabName])
4445

45-
const HostTabs = memo(({ id }) => {
46+
const HostTabs = memo(({ id, singleActions }) => {
4647
const { view, getResourceView } = useViews()
4748
const {
4849
isError,
@@ -69,7 +70,15 @@ const HostTabs = memo(({ id }) => {
6970
}
7071

7172
if (status === 'fulfilled' || id === data?.ID) {
72-
return <Tabs addBorder tabs={tabsAvailable} />
73+
return (
74+
<>
75+
<SingleDetailActions
76+
selectedRows={data}
77+
singleActions={singleActions}
78+
/>
79+
<Tabs addBorder tabs={tabsAvailable} />
80+
</>
81+
)
7382
}
7483

7584
return (
@@ -82,7 +91,10 @@ const HostTabs = memo(({ id }) => {
8291
)
8392
})
8493

85-
HostTabs.propTypes = { id: PropTypes.string.isRequired }
94+
HostTabs.propTypes = {
95+
id: PropTypes.string.isRequired,
96+
singleActions: PropTypes.func,
97+
}
8698
HostTabs.displayName = 'HostTabs'
8799

88100
export default HostTabs

src/fireedge/src/modules/components/Tabs/ServiceTemplate/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@
1313
* See the License for the specific language governing permissions and *
1414
* limitations under the License. *
1515
* ------------------------------------------------------------------------- */
16+
import { OpenNebulaLogo } from '@modules/components/Icons'
1617
import { Alert, Stack } from '@mui/material'
1718
import PropTypes from 'prop-types'
1819
import { memo, useMemo } from 'react'
19-
import { OpenNebulaLogo } from '@modules/components/Icons'
2020

2121
import { RESOURCE_NAMES } from '@ConstantsModule'
22-
import { useViews, ServiceTemplateAPI } from '@FeaturesModule'
22+
import { ServiceTemplateAPI, useViews } from '@FeaturesModule'
2323
import { getAvailableInfoTabs } from '@ModelsModule'
2424

2525
import { BaseTab as Tabs } from '@modules/components/Tabs'
2626
import Info from '@modules/components/Tabs/ServiceTemplate/Info'
2727
import Roles from '@modules/components/Tabs/ServiceTemplate/Roles'
2828
import Template from '@modules/components/Tabs/ServiceTemplate/Template'
29+
import SingleDetailActions from '@modules/components/Tabs/SingleDetailActions'
2930

3031
const getTabComponent = (tabName) =>
3132
({
@@ -34,7 +35,7 @@ const getTabComponent = (tabName) =>
3435
template: Template,
3536
}[tabName])
3637

37-
const ServiceTemplateTabs = memo(({ id }) => {
38+
const ServiceTemplateTabs = memo(({ id, singleActions }) => {
3839
const { view, getResourceView } = useViews()
3940
const { isError, error, status, data } =
4041
ServiceTemplateAPI.useGetServiceTemplateQuery({
@@ -57,7 +58,15 @@ const ServiceTemplateTabs = memo(({ id }) => {
5758
}
5859

5960
if (status === 'fulfilled' || id === data?.ID) {
60-
return <Tabs addBorder tabs={tabsAvailable ?? []} />
61+
return (
62+
<>
63+
<SingleDetailActions
64+
selectedRows={data}
65+
singleActions={singleActions}
66+
/>
67+
<Tabs addBorder tabs={tabsAvailable ?? []} />
68+
</>
69+
)
6170
}
6271

6372
return (
@@ -70,7 +79,10 @@ const ServiceTemplateTabs = memo(({ id }) => {
7079
)
7180
})
7281

73-
ServiceTemplateTabs.propTypes = { id: PropTypes.string.isRequired }
82+
ServiceTemplateTabs.propTypes = {
83+
id: PropTypes.string.isRequired,
84+
singleActions: PropTypes.func,
85+
}
7486
ServiceTemplateTabs.displayName = 'ServiceTemplateTabs'
7587

7688
export default ServiceTemplateTabs
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* ------------------------------------------------------------------------- *
2+
* Copyright 2002-2025, OpenNebula Project, OpenNebula Systems *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
5+
* not use this file except in compliance with the License. You may obtain *
6+
* a copy of the License at *
7+
* *
8+
* http://www.apache.org/licenses/LICENSE-2.0 *
9+
* *
10+
* Unless required by applicable law or agreed to in writing, software *
11+
* distributed under the License is distributed on an "AS IS" BASIS, *
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
* See the License for the specific language governing permissions and *
14+
* limitations under the License. *
15+
* ------------------------------------------------------------------------- */
16+
import EnhancedTableStyles from '@modules/components/Tables/Enhanced/styles'
17+
import { GlobalActions } from '@modules/components/Tables/Enhanced/Utils'
18+
import { Box, useTheme } from '@mui/material'
19+
import PropTypes from 'prop-types'
20+
import { memo, useMemo } from 'react'
21+
22+
const SingleDetailActions = memo(({ selectedRows = [], singleActions }) => {
23+
const theme = useTheme()
24+
const styles = useMemo(
25+
() =>
26+
EnhancedTableStyles({
27+
...theme,
28+
readOnly: false,
29+
}),
30+
[theme]
31+
)
32+
33+
if (!selectedRows || typeof singleActions !== 'function') {
34+
return null
35+
}
36+
37+
const parsedSelectedRows = [{ original: selectedRows }]
38+
const actions = singleActions({ selectedRows: parsedSelectedRows })
39+
40+
return (
41+
<Box marginBottom={2}>
42+
<GlobalActions
43+
className={styles.actions}
44+
globalActions={actions}
45+
selectedRows={parsedSelectedRows}
46+
/>
47+
</Box>
48+
)
49+
})
50+
51+
SingleDetailActions.propTypes = {
52+
selectedRows: PropTypes.array,
53+
actions: PropTypes.array,
54+
}
55+
SingleDetailActions.displayName = 'SingleDetailActions'
56+
export default SingleDetailActions

0 commit comments

Comments
 (0)