Skip to content

Commit 268e795

Browse files
committed
Ambari-Web React Implementation: Authentication Components
1 parent 982c545 commit 268e795

File tree

19 files changed

+4266
-231
lines changed

19 files changed

+4266
-231
lines changed

ambari-admin/src/main/resources/ui/ambari-admin/package-lock.json

Lines changed: 2706 additions & 163 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ambari-admin/src/main/resources/ui/ambari-admin/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@fortawesome/react-fontawesome": "^0.2.2",
1717
"@tanstack/react-table": "^8.20.5",
1818
"@types/lodash": "^4.17.12",
19+
"@types/recharts": "^1.8.29",
1920
"axios": "^1.7.7",
2021
"bootstrap": "^5.3.3",
2122
"history": "^5.3.0",
@@ -27,6 +28,7 @@
2728
"react-hot-toast": "^2.4.1",
2829
"react-router-dom": "^5.3.4",
2930
"react-select": "^5.8.3",
31+
"recharts": "^2.15.1",
3032
"sass": "^1.77.6"
3133
},
3234
"devDependencies": {

ambari-admin/src/main/resources/ui/ambari-admin/src/App.tsx

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,65 +24,88 @@ import NavBar from "./layout/NavBar";
2424
import AppContent from "./context/AppContext";
2525
import { Toaster } from "react-hot-toast";
2626
import { HashRouter } from "react-router-dom";
27+
import { AuthProvider, useAuth } from "./context/AuthContext";
28+
import Login from "./screens/Login";
2729

28-
function App() {
30+
// Main application component that requires authentication
31+
const MainApp: React.FC = () => {
2932
const [selectedOption, setSelectedOption] = useState<string>(
3033
SideItemLabels.CLUSTERINFORMATION
3134
);
3235
const [rbacData, setRbacData] = useState({});
3336
const [ambariVersion, setAmbariVersion] = useState<string>("");
3437
const [permissionLabelList, setPermissionLabelList] = useState<string[]>([]);
3538
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
39+
const { logout } = useAuth();
3640

37-
console.log("In App");
41+
console.log("In MainApp");
3842

3943
return (
40-
<HashRouter>
41-
<AppContent.Provider
42-
value={{
43-
selectedOption,
44-
setSelectedOption,
45-
rbacData,
46-
setRbacData,
47-
permissionLabelList,
48-
setPermissionLabelList,
49-
ambariVersion,
50-
setAmbariVersion,
51-
}}
52-
>
53-
<Toaster />
54-
<div className="d-flex h-100" style={{ maxHeight: "100vh" }}>
55-
<SideBar
56-
clusterExists={false}
57-
isSidebarCollapsed={isSidebarCollapsed}
58-
setIsSidebarCollapsed={setIsSidebarCollapsed}
59-
isRoot
44+
<AppContent.Provider
45+
value={{
46+
selectedOption,
47+
setSelectedOption,
48+
rbacData,
49+
setRbacData,
50+
permissionLabelList,
51+
setPermissionLabelList,
52+
ambariVersion,
53+
setAmbariVersion,
54+
}}
55+
>
56+
<Toaster />
57+
<div className="d-flex h-100" style={{ maxHeight: "100vh" }}>
58+
<SideBar
59+
clusterExists={false}
60+
isSidebarCollapsed={isSidebarCollapsed}
61+
setIsSidebarCollapsed={setIsSidebarCollapsed}
62+
isRoot
63+
onLogout={logout}
64+
/>
65+
<div
66+
className={`d-flex flex-column ${isSidebarCollapsed?"main-content-collapsed":"main-content"}`}
67+
style={{
68+
background: "#e6e6e6",
69+
maxHeight: "100%",
70+
overflowY: "scroll",
71+
height: "100%",
72+
position: "absolute",
73+
left: isSidebarCollapsed?"60px":"230px",
74+
width: "calc(100% - " + (isSidebarCollapsed ? "60px" : "230px") + ")",
75+
}}
76+
>
77+
<NavBar
78+
subPath={selectedOption}
79+
clusterName={""}
6080
/>
61-
<div
62-
className={`d-flex flex-column ${isSidebarCollapsed?"main-content-collapsed":"main-content"}`}
63-
style={{
64-
background: "#e6e6e6",
65-
maxHeight: "100%",
66-
overflowY: "scroll",
67-
height: "100%",
68-
position: "absolute",
69-
left: isSidebarCollapsed?"60px":"230px",
70-
}}
71-
>
72-
<NavBar
73-
subPath={selectedOption}
74-
clusterName={""}
75-
/>
76-
<Container className="mt-4">
77-
<Card className="p-4 rounded-0">
78-
<Routes />
79-
</Card>
80-
</Container>
81-
</div>
81+
<Container className="mt-4">
82+
<Card className="p-4 rounded-0">
83+
<Routes />
84+
</Card>
85+
</Container>
8286
</div>
83-
</AppContent.Provider>
87+
</div>
88+
</AppContent.Provider>
89+
);
90+
};
91+
92+
// App wrapper that handles authentication state
93+
function App() {
94+
return (
95+
<HashRouter>
96+
<AuthProvider>
97+
<AppRouter />
98+
</AuthProvider>
8499
</HashRouter>
85100
);
86101
}
87102

103+
// Router component that conditionally renders Login or MainApp
104+
const AppRouter: React.FC = () => {
105+
const { isAuthenticated } = useAuth();
106+
107+
// Render Login page or MainApp based on authentication status
108+
return isAuthenticated ? <MainApp /> : <Login />;
109+
};
110+
88111
export default App;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
.loading-spinner-container {
20+
display: flex;
21+
justify-content: center;
22+
align-items: center;
23+
height: 100vh;
24+
width: 100%;
25+
26+
.loading-spinner-content {
27+
text-align: center;
28+
29+
.spinner-border {
30+
width: 3rem;
31+
height: 3rem;
32+
}
33+
34+
p {
35+
font-size: 1.2rem;
36+
color: #666;
37+
}
38+
}
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import React from 'react';
20+
import { Spinner, Container } from 'react-bootstrap';
21+
import './LoadingSpinner.scss';
22+
23+
interface LoadingSpinnerProps {
24+
message?: string;
25+
}
26+
27+
const LoadingSpinner: React.FC<LoadingSpinnerProps> = ({ message = 'Loading...' }) => {
28+
return (
29+
<Container className="loading-spinner-container">
30+
<div className="loading-spinner-content">
31+
<Spinner animation="border" role="status" variant="primary" />
32+
<p className="mt-3">{message}</p>
33+
</div>
34+
</Container>
35+
);
36+
};
37+
38+
export default LoadingSpinner;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
.login-form {
20+
width: 100%;
21+
22+
h2 {
23+
margin-bottom: 20px;
24+
font-size: 1.5rem;
25+
font-weight: normal;
26+
}
27+
28+
.form-label {
29+
font-weight: normal;
30+
margin-bottom: 5px;
31+
}
32+
33+
.form-control {
34+
margin-bottom: 5px;
35+
border-radius: 0;
36+
37+
&:focus {
38+
box-shadow: none;
39+
border-color: #ccc;
40+
}
41+
42+
&.is-invalid {
43+
border-color: #dc3545;
44+
background-image: none;
45+
padding-right: 0.75rem;
46+
}
47+
}
48+
49+
.invalid-feedback {
50+
margin-bottom: 10px;
51+
font-size: 0.8rem;
52+
}
53+
54+
.sign-in-button {
55+
background-color: #5cb85c;
56+
border-color: #5cb85c;
57+
border-radius: 0;
58+
width: 100px;
59+
text-transform: uppercase;
60+
font-size: 0.8rem;
61+
font-weight: bold;
62+
margin-top: 10px;
63+
64+
&:hover, &:focus {
65+
background-color: #4cae4c;
66+
border-color: #4cae4c;
67+
}
68+
69+
&:disabled {
70+
background-color: #8bc58b;
71+
border-color: #8bc58b;
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)