1313 * See the License for the specific language governing permissions and *
1414 * limitations under the License. *
1515 * ------------------------------------------------------------------------- */
16- import { Box , CircularProgress , Grid } from '@mui/material'
17- import {
18- BoxIso as ImageIcon ,
19- NetworkAlt as NetworkIcon ,
20- EmptyPage as TemplatesIcon ,
21- ModernTv as VmsIcons ,
22- } from 'iconoir-react'
16+ import { Box , Grid } from '@mui/material'
2317import PropTypes from 'prop-types'
24- import { ReactElement , memo , useEffect , useMemo } from 'react'
25- import { useHistory } from 'react-router-dom'
18+ import { ReactElement , useEffect , useMemo } from 'react'
2619
27- import {
28- ImageAPI ,
29- VmAPI ,
30- VmTemplateAPI ,
31- VnAPI ,
32- useAuth ,
33- useGeneralApi ,
34- useViews ,
35- } from '@FeaturesModule'
20+ import { useAuth , useGeneralApi , useViews } from '@FeaturesModule'
21+ import { TranslateProvider } from '@ComponentsModule'
22+ import { RESOURCE_NAMES } from '@ConstantsModule'
23+ import { stringToBoolean } from '@ModelsModule'
3624
3725import {
38- NumberEasing ,
39- PATH ,
40- TranslateProvider ,
41- WavesCard ,
42- } from '@ComponentsModule'
43- import { RESOURCE_NAMES , T , VM_POOL_PAGINATION_SIZE } from '@ConstantsModule'
44- import { stringToBoolean } from '@ModelsModule '
26+ ResourceSummaryCards ,
27+ InfrastructureUtilization ,
28+ StorageCapacity ,
29+ HostMonitoringGraphs ,
30+ VmStateDistribution ,
31+ QuickActions ,
32+ } from './widgets '
4533
46- const { VM , VM_TEMPLATE , IMAGE , VNET } = RESOURCE_NAMES
34+ const { HOST , DATASTORE } = RESOURCE_NAMES
4735
4836/**
37+ * Sunstone admin dashboard with resource overview, utilization metrics,
38+ * monitoring graphs, state distribution, and quick actions.
39+ *
4940 * @param {object } props - Props
50- * @param {object } props.view - View
41+ * @param {string } props.view - Current view name
5142 * @returns {ReactElement } Sunstone dashboard container
5243 */
5344export default function SunstoneDashboard ( { view } ) {
5445 const { settings : { FIREEDGE : fireedge = { } } = { } } = useAuth ( )
5546 const { DISABLE_ANIMATIONS } = fireedge
5647 const { hasAccessToResource } = useViews ( )
5748
58- // Delete second title
5949 const { setSecondTitle } = useGeneralApi ( )
6050 useEffect ( ( ) => setSecondTitle ( { } ) , [ ] )
6151
62- const { push : goTo } = useHistory ( )
63-
64- const vmAccess = useMemo ( ( ) => hasAccessToResource ( VM ) , [ view ] )
65- const templateAccess = useMemo ( ( ) => hasAccessToResource ( VM_TEMPLATE ) , [ view ] )
66- const imageAccess = useMemo ( ( ) => hasAccessToResource ( IMAGE ) , [ view ] )
67- const vnetAccess = useMemo ( ( ) => hasAccessToResource ( VNET ) , [ view ] )
52+ const hostAccess = useMemo ( ( ) => hasAccessToResource ( HOST ) , [ view ] )
53+ const datastoreAccess = useMemo (
54+ ( ) => hasAccessToResource ( DATASTORE ) ,
55+ [ view ]
56+ )
6857
6958 const styles = useMemo ( ( ) => {
7059 if ( stringToBoolean ( DISABLE_ANIMATIONS ) )
@@ -76,43 +65,45 @@ export default function SunstoneDashboard({ view }) {
7665 return (
7766 < TranslateProvider >
7867 < Box py = { 3 } sx = { styles } >
79- < Grid
80- container
81- data-cy = "dashboard-widget-total-sunstone-resources"
82- spacing = { 3 }
83- >
84- < ResourceWidget
85- type = "vms"
86- bgColor = "#fa7892"
87- text = { T . VMs }
88- icon = { VmsIcons }
89- onClick = { vmAccess && ( ( ) => goTo ( PATH . INSTANCE . VMS . LIST ) ) }
90- disableAnimations = { DISABLE_ANIMATIONS }
91- />
92- < ResourceWidget
93- type = "vmtemples"
94- bgColor = "#b25aff"
95- text = { T . VMTemplates }
96- icon = { TemplatesIcon }
97- onClick = { templateAccess && ( ( ) => goTo ( PATH . TEMPLATE . VMS . LIST ) ) }
98- disableAnimations = { DISABLE_ANIMATIONS }
99- />
100- < ResourceWidget
101- type = "images"
102- bgColor = "#1fbbc6"
103- text = { T . Images }
104- icon = { ImageIcon }
105- onClick = { imageAccess && ( ( ) => goTo ( PATH . STORAGE . IMAGES . LIST ) ) }
106- disableAnimations = { DISABLE_ANIMATIONS }
107- />
108- < ResourceWidget
109- type = "vnets"
110- bgColor = "#f09d42"
111- text = { T . VirtualNetworks }
112- icon = { NetworkIcon }
113- onClick = { vnetAccess && ( ( ) => goTo ( PATH . NETWORK . VNETS . LIST ) ) }
114- disableAnimations = { DISABLE_ANIMATIONS }
115- />
68+ { /* Row 1: Enhanced Resource Summary Cards */ }
69+ < ResourceSummaryCards
70+ disableAnimations = { DISABLE_ANIMATIONS }
71+ view = { view }
72+ />
73+
74+ { /* Row 2: Infrastructure Utilization + Storage Capacity */ }
75+ { ( hostAccess || datastoreAccess ) && (
76+ < Grid container spacing = { 3 } sx = { { mt : 0 } } >
77+ { hostAccess && (
78+ < Grid item xs = { 12 } md = { 6 } >
79+ < InfrastructureUtilization view = { view } />
80+ </ Grid >
81+ ) }
82+ { datastoreAccess && (
83+ < Grid item xs = { 12 } md = { 6 } >
84+ < StorageCapacity view = { view } />
85+ </ Grid >
86+ ) }
87+ </ Grid >
88+ ) }
89+
90+ { /* Row 3: Host CPU + Memory Monitoring Graphs */ }
91+ { hostAccess && (
92+ < Box sx = { { mt : 3 } } >
93+ < HostMonitoringGraphs />
94+ </ Box >
95+ ) }
96+
97+ { /* Row 4: VM State Distribution + Quick Actions */ }
98+ < Grid container spacing = { 3 } sx = { { mt : 0 } } >
99+ < Grid item xs = { 12 } md = { 8 } >
100+ < VmStateDistribution
101+ disableAnimations = { stringToBoolean ( DISABLE_ANIMATIONS ) }
102+ />
103+ </ Grid >
104+ < Grid item xs = { 12 } md = { 4 } >
105+ < QuickActions view = { view } />
106+ </ Grid >
116107 </ Grid >
117108 </ Box >
118109 </ TranslateProvider >
@@ -124,52 +115,3 @@ SunstoneDashboard.displayName = 'SunstoneDashboard'
124115SunstoneDashboard . propTypes = {
125116 view : PropTypes . string ,
126117}
127-
128- const ResourceWidget = memo (
129- ( { type = 'vms' , onClick, text, bgColor, icon, disableAnimations } ) => {
130- const options = {
131- vmtemples : VmTemplateAPI . useGetTemplatesQuery ( undefined , {
132- skip : type !== 'vmtemples' ,
133- } ) ,
134- images : ImageAPI . useGetImagesQuery ( undefined , {
135- skip : type !== 'images' ,
136- } ) ,
137- vnets : VnAPI . useGetVNetworksQuery ( undefined , { skip : type !== 'vnets' } ) ,
138- vms : VmAPI . useGetVmsPaginatedQuery (
139- { extended : 0 , pageSize : VM_POOL_PAGINATION_SIZE } ,
140- { skip : type !== 'vms' }
141- ) ,
142- }
143-
144- const { data = [ ] , isFetching } = options [ type ] || { }
145-
146- const NumberElement = useMemo ( ( ) => {
147- if ( stringToBoolean ( disableAnimations ) ) return data ?. length
148-
149- return < NumberEasing value = { data ?. length } />
150- } , [ disableAnimations , data ?. length ] )
151-
152- return (
153- < Grid item xs = { 12 } sm = { 6 } md = { 3 } >
154- < WavesCard
155- bgColor = { bgColor }
156- icon = { icon }
157- text = { text }
158- value = { isFetching ? < CircularProgress size = { 20 } /> : NumberElement }
159- onClick = { onClick || undefined }
160- />
161- </ Grid >
162- )
163- }
164- )
165-
166- ResourceWidget . displayName = 'ResourceWidget'
167-
168- ResourceWidget . propTypes = {
169- type : PropTypes . string ,
170- onClick : PropTypes . oneOfType ( [ PropTypes . func , PropTypes . bool ] ) ,
171- text : PropTypes . string ,
172- bgColor : PropTypes . string ,
173- icon : PropTypes . any ,
174- disableAnimations : PropTypes . string ,
175- }
0 commit comments