Skip to content

Commit 9aa0b3d

Browse files
lfujeremylenz
authored andcommitted
Fixes #38836 - Add clickable indicator to status icon on All Hosts page
1 parent 5d6a82c commit 9aa0b3d

File tree

5 files changed

+307
-292
lines changed

5 files changed

+307
-292
lines changed

webpack/assets/javascripts/react_app/components/HostStatuses/Status/GlobalStatusIcon.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,33 @@ import {
1212
GLOBAL_STATUS_ERROR,
1313
} from '../HostStatusesConstants';
1414

15-
const GlobalStatusIcon = ({ status, ...props }) => {
15+
const GlobalStatusIcon = ({ status, style, ...props }) => {
1616
switch (status) {
1717
case GLOBAL_STATUS_OK:
1818
return (
1919
<CheckCircleIcon
20-
style={{ fill: 'var(--pf-v5-global--success-color--100)' }}
20+
style={{ fill: 'var(--pf-v5-global--success-color--100)', ...style }}
2121
{...props}
2222
/>
2323
);
2424
case GLOBAL_STATUS_WARN:
2525
return (
2626
<ExclamationTriangleIcon
27-
style={{ fill: 'var(--pf-v5-global--warning-color--100)' }}
27+
style={{ fill: 'var(--pf-v5-global--warning-color--100)', ...style }}
2828
{...props}
2929
/>
3030
);
3131
case GLOBAL_STATUS_ERROR:
3232
return (
3333
<ExclamationCircleIcon
34-
style={{ fill: 'var(--pf-v5-global--danger-color--100)' }}
34+
style={{ fill: 'var(--pf-v5-global--danger-color--100)', ...style }}
3535
{...props}
3636
/>
3737
);
3838
default:
3939
return (
4040
<QuestionCircleIcon
41-
style={{ fill: 'var(--pf-v5-global--info-color--200)' }}
41+
style={{ fill: 'var(--pf-v5-global--info-color--200)', ...style }}
4242
{...props}
4343
/>
4444
);
@@ -47,10 +47,12 @@ const GlobalStatusIcon = ({ status, ...props }) => {
4747

4848
GlobalStatusIcon.propTypes = {
4949
status: PropTypes.number,
50+
style: PropTypes.object,
5051
};
5152

5253
GlobalStatusIcon.defaultProps = {
5354
status: undefined,
55+
style: undefined,
5456
};
5557

5658
export default GlobalStatusIcon;

webpack/assets/javascripts/react_app/components/HostsIndex/Columns/core.js

Lines changed: 4 additions & 287 deletions
Original file line numberDiff line numberDiff line change
@@ -1,290 +1,7 @@
1-
/* eslint-disable camelcase */
2-
import React from 'react';
3-
import { Link } from 'react-router-dom';
4-
import { TableText } from '@patternfly/react-table';
5-
import {
6-
Popover,
7-
TextContent,
8-
TextList,
9-
TextListItem,
10-
} from '@patternfly/react-core';
11-
import { UserIcon, UsersIcon } from '@patternfly/react-icons';
12-
import { number_to_human_size as NumberToHumanSize } from 'number_helpers';
13-
import { translate as __ } from '../../../common/I18n';
141
import forceSingleton from '../../../common/forceSingleton';
15-
import { foremanUrl } from '../../../common/helpers';
16-
import RelativeDateTime from '../../common/dates/RelativeDateTime';
17-
import HostPowerStatus from './components/HostPowerStatus';
18-
import GlobalStatusIcon from '../../HostStatuses/Status/GlobalStatusIcon';
19-
20-
const coreHostsIndexColumns = [
21-
{
22-
columnName: 'power_status',
23-
title: __('Power'),
24-
wrapper: ({ name }) => <HostPowerStatus hostName={name} />,
25-
isSorted: false,
26-
weight: 0,
27-
},
28-
{
29-
columnName: 'name',
30-
title: __('Name'),
31-
wrapper: ({
32-
name,
33-
display_name: displayName,
34-
global_status: globalStatus,
35-
global_status_fulltext: statuses,
36-
}) => (
37-
<span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
38-
<Popover
39-
id="host-index-global-status-tooltip"
40-
bodyContent={
41-
<TextContent>
42-
<TextList isPlain>
43-
{statuses.map((status, index) => (
44-
<TextListItem key={`status-list-${index}`}>
45-
{status}
46-
</TextListItem>
47-
))}
48-
</TextList>
49-
</TextContent>
50-
}
51-
>
52-
<GlobalStatusIcon status={globalStatus} />
53-
</Popover>
54-
<Link to={`hosts/${name}`}>{displayName}</Link>
55-
</span>
56-
),
57-
isSorted: true,
58-
weight: 50,
59-
isRequired: true,
60-
},
61-
{
62-
columnName: 'organization',
63-
title: __('Organization'),
64-
wrapper: hostDetails => hostDetails?.organization_name,
65-
isSorted: false,
66-
weight: 75,
67-
},
68-
{
69-
columnName: 'location',
70-
title: __('Location'),
71-
wrapper: hostDetails => hostDetails?.location_name,
72-
isSorted: false,
73-
weight: 80,
74-
},
75-
{
76-
columnName: 'hostgroup',
77-
title: __('Host group'),
78-
wrapper: hostDetails => {
79-
const fullTitle = hostDetails?.hostgroup_title;
80-
const name = hostDetails?.hostgroup_name;
81-
return (
82-
<span>
83-
{fullTitle?.substring(0, fullTitle?.lastIndexOf(name))}
84-
<a href={`/hostgroups/${hostDetails?.hostgroup_id}/edit`}>{name}</a>
85-
</span>
86-
);
87-
},
88-
isSorted: true,
89-
weight: 100,
90-
},
91-
{
92-
columnName: 'os_title',
93-
title: __('OS'),
94-
wrapper: hostDetails => hostDetails?.operatingsystem_name,
95-
isSorted: true,
96-
weight: 200,
97-
},
98-
{
99-
columnName: 'owner',
100-
title: __('Owner'),
101-
wrapper: hostDetails => {
102-
if (!hostDetails?.owner_name) return null;
103-
const OwnerIcon =
104-
hostDetails?.owner_type !== 'User' ? UsersIcon : UserIcon;
105-
return (
106-
<TableText>
107-
<OwnerIcon color="#2B9AF3" style={{ marginRight: '5px' }} />
108-
{hostDetails?.owner_name}
109-
</TableText>
110-
);
111-
},
112-
isSorted: true,
113-
weight: 300,
114-
},
115-
{
116-
columnName: 'boot_time',
117-
title: __('Boot time'),
118-
wrapper: hostDetails => {
119-
const bootTime = hostDetails?.reported_data?.boot_time;
120-
return <RelativeDateTime defaultValue={__('Unknown')} date={bootTime} />;
121-
},
122-
isSorted: true,
123-
weight: 400,
124-
},
125-
{
126-
columnName: 'last_report',
127-
title: __('Last report'),
128-
wrapper: hostDetails => {
129-
const lastReport = hostDetails?.last_report;
130-
return lastReport ? (
131-
<Link to={foremanUrl(`/hosts/${hostDetails.name}/config_reports/last`)}>
132-
<RelativeDateTime date={lastReport} />
133-
</Link>
134-
) : (
135-
__('No report')
136-
);
137-
},
138-
isSorted: true,
139-
weight: 500,
140-
},
141-
{
142-
columnName: 'comment',
143-
title: __('Comment'),
144-
wrapper: hostDetails => (
145-
<TableText wrapModifier="truncate">
146-
{hostDetails?.comment ?? ''}
147-
</TableText>
148-
),
149-
isSorted: true,
150-
weight: 600,
151-
},
152-
];
153-
154-
coreHostsIndexColumns.forEach(column => {
155-
column.tableName = 'hosts';
156-
column.categoryName = 'General';
157-
column.categoryKey = 'general';
158-
});
159-
160-
const networkColumns = [
161-
{
162-
columnName: 'ip',
163-
title: 'IPv4',
164-
wrapper: hostDetails => hostDetails?.ip,
165-
isSorted: true,
166-
weight: 700,
167-
},
168-
{
169-
columnName: 'ip6',
170-
title: 'IPv6',
171-
wrapper: hostDetails => hostDetails?.ip6,
172-
isSorted: true,
173-
weight: 800,
174-
},
175-
{
176-
columnName: 'mac',
177-
title: 'MAC',
178-
wrapper: hostDetails => hostDetails?.mac,
179-
isSorted: true,
180-
weight: 900,
181-
},
182-
];
183-
184-
networkColumns.forEach(column => {
185-
column.tableName = 'hosts';
186-
column.categoryName = 'Network';
187-
column.categoryKey = 'network';
188-
});
189-
190-
const reportedDataColumns = [
191-
{
192-
columnName: 'model',
193-
title: __('Model'),
194-
wrapper: hostDetails =>
195-
hostDetails?.compute_resource_name || hostDetails?.model_name,
196-
isSorted: true,
197-
weight: 1000,
198-
},
199-
{
200-
columnName: 'sockets',
201-
title: __('Sockets'),
202-
wrapper: hostDetails => hostDetails?.reported_data?.sockets,
203-
isSorted: false,
204-
weight: 1100,
205-
},
206-
{
207-
columnName: 'cores',
208-
title: __('Cores'),
209-
wrapper: hostDetails => hostDetails?.reported_data?.cores,
210-
isSorted: false,
211-
weight: 1200,
212-
},
213-
{
214-
columnName: 'ram',
215-
title: __('RAM'),
216-
wrapper: hostDetails => {
217-
if (!hostDetails?.reported_data?.ram) return null;
218-
return NumberToHumanSize(hostDetails.reported_data.ram * 1024 * 1024, {
219-
strip_insignificant_zeros: true,
220-
});
221-
},
222-
isSorted: false,
223-
weight: 1300,
224-
},
225-
{
226-
columnName: 'virtual',
227-
title: __('Virtual'),
228-
wrapper: hostDetails => {
229-
const value = hostDetails?.reported_data?.virtual;
230-
if (value === undefined || value === null) {
231-
return '';
232-
}
233-
if (value) {
234-
return __('Virtual');
235-
}
236-
return __('Physical');
237-
},
238-
isSorted: false,
239-
weight: 1400,
240-
},
241-
{
242-
columnName: 'disks_total',
243-
title: __('Total disk space'),
244-
wrapper: hostDetails => {
245-
if (!hostDetails?.reported_data?.disks_total) return null;
246-
return NumberToHumanSize(hostDetails.reported_data.disks_total, {
247-
strip_insignificant_zeros: true,
248-
});
249-
},
250-
isSorted: false,
251-
weight: 1500,
252-
},
253-
{
254-
columnName: 'kernel_version',
255-
title: __('Kernel version'),
256-
wrapper: hostDetails => hostDetails?.reported_data?.kernel_version,
257-
isSorted: false,
258-
weight: 1600,
259-
},
260-
{
261-
columnName: 'bios_vendor',
262-
title: __('BIOS vendor'),
263-
wrapper: hostDetails => hostDetails?.reported_data?.bios_vendor,
264-
isSorted: false,
265-
weight: 1700,
266-
},
267-
{
268-
columnName: 'bios_release_date',
269-
title: __('BIOS release date'),
270-
wrapper: hostDetails => hostDetails?.reported_data?.bios_release_date,
271-
isSorted: false,
272-
weight: 1800,
273-
},
274-
{
275-
columnName: 'bios_version',
276-
title: __('BIOS version'),
277-
wrapper: hostDetails => hostDetails?.reported_data?.bios_version,
278-
isSorted: false,
279-
weight: 1900,
280-
},
281-
];
282-
283-
reportedDataColumns.forEach(column => {
284-
column.tableName = 'hosts';
285-
column.categoryName = 'Reported data';
286-
column.categoryKey = 'reported_data';
287-
});
2+
import generalColumns from './generalColumns';
3+
import networkColumns from './networkColumns';
4+
import reportedDataColumns from './reportedDataColumns';
2885

2896
const coreColumnRegistry = forceSingleton('coreColumnRegistry', () => ({}));
2907

@@ -294,7 +11,7 @@ export const registerColumns = columns => {
29411
});
29512
};
29613

297-
registerColumns(coreHostsIndexColumns);
14+
registerColumns(generalColumns);
29815
registerColumns(networkColumns);
29916
registerColumns(reportedDataColumns);
30017

0 commit comments

Comments
 (0)