-
Notifications
You must be signed in to change notification settings - Fork 991
/
index.js
166 lines (153 loc) · 4.81 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
Grid,
Tab,
Tabs,
GridItem,
Badge,
Title,
Breadcrumb,
BreadcrumbItem,
Text,
TextVariants,
PageSection,
} from '@patternfly/react-core';
import Skeleton from 'react-loading-skeleton';
import RelativeDateTime from '../../components/common/dates/RelativeDateTime';
import { foremanUrl } from '../../../foreman_tools';
import { get } from '../../redux/API';
import { selectAPIResponse } from '../../redux/API/APISelectors';
import { selectFillsIDs } from '../common/Slot/SlotSelectors';
import { selectIsCollapsed } from '../Layout/LayoutSelectors';
import ActionsBar from './ActionsBar';
import Slot from '../common/Slot';
import { registerCoreTabs } from './Tabs';
import './HostDetails.scss';
const HostDetails = ({ match, location: { hash } }) => {
const dispatch = useDispatch();
const [activeTab, setActiveTab] = useState('Details');
const response = useSelector(state =>
selectAPIResponse(state, 'HOST_DETAILS')
);
const isNavCollapsed = useSelector(selectIsCollapsed);
const tabs = useSelector(state =>
selectFillsIDs(state, 'host-details-page-tabs')
);
// This is a workaround due to the tabs overflow mechanism in PF4
useEffect(() => {
if (tabs?.length) dispatchEvent(new Event('resize'));
}, [tabs]);
useEffect(() => {
registerCoreTabs();
}, []);
useEffect(() => {
if (hash) setActiveTab(hash.slice(1));
}, [hash]);
useEffect(() => {
dispatch(
get({
key: 'HOST_DETAILS',
url: foremanUrl(`/api/hosts/${match.params.id}`),
})
);
}, [match.params.id, dispatch]);
useEffect(() => {
// This is a workaround for adding gray background inspiring pf4 desgin
// TODO: delete it when pf4 layout (Page copmponent) is implemented in foreman
document.body.classList.add('pf-gray-background');
return () => document.body.classList.remove('pf-gray-background');
}, []);
const handleTabClick = (event, tabIndex) => {
setActiveTab(tabIndex);
};
return (
<>
<PageSection
className="host-details-header-section"
isFilled
variant="light"
>
<div style={{ marginLeft: '18px', marginRight: '18px' }}>
<Breadcrumb style={{ marginTop: '15px' }}>
<BreadcrumbItem to="/hosts">Hosts</BreadcrumbItem>
<BreadcrumbItem isActive>
{response.name || <Skeleton />}
</BreadcrumbItem>
</Breadcrumb>
{/* TODO: Replace all br with css */}
<br />
<br />
<Grid>
<GridItem span={2}>
<Title headingLevel="h5" size="2xl">
{/* TODO: Make a generic Skeleton HOC (withSkeleton) */}
{response.name || <Skeleton />}
</Title>
</GridItem>
<GridItem style={{ marginTop: '5px', marginLeft: '10px' }} span={8}>
<Badge key={1}>{response.operatingsystem_name}</Badge>{' '}
<Badge key={21}>{response.architecture_name}</Badge>
</GridItem>
<GridItem span={2}>
<ActionsBar hostName={response.name || <Skeleton />} />
</GridItem>
</Grid>
<Text style={{ fontStyle: 'italic' }} component={TextVariants.p}>
{/* TODO: extracting text and remove timeago usage in favor i18n */}
{response.name ? (
<div>
created{' '}
<RelativeDateTime
date={response.created_at}
defaultValue="N/A"
/>{' '}
by {response.owner_name} (updated{' '}
<RelativeDateTime
date={response.updated_at}
defaultValue="N/A"
/>
)
</div>
) : (
<Skeleton width={400} />
)}
</Text>
<br />
</div>
<Tabs
style={{
width: window.innerWidth - (isNavCollapsed ? 95 : 220),
}}
activeKey={activeTab}
onSelect={handleTabClick}
>
{tabs &&
tabs.map(tab => (
<Tab eventKey={tab} title={tab}>
<div className="host-details-tab-item">
<Slot
response={response}
id="host-details-page-tabs"
fillID={tab}
/>
</div>
</Tab>
))}
</Tabs>
</PageSection>
</>
);
};
HostDetails.propTypes = {
match: PropTypes.shape({
params: PropTypes.shape({
id: PropTypes.string,
}),
}).isRequired,
location: PropTypes.shape({
hash: PropTypes.string,
}).isRequired,
};
export default HostDetails;