-
-
Sign Up
-
-
+ const navigate = useNavigate();
+ const [values, setValues] = useState({
+ email: '',
+ username: '',
+ password: '',
+ passwordConfirmation: '',
+ phone: '',
+ showPassword: false,
+ });
+
+ const handleClickShowPassword = () => {
+ setValues({
+ ...values,
+ showPassword: !values.showPassword,
+ });
+ };
+
+ return (
+
+
+
Sign Up
+
+
handleNewUser(e, '1')}
- sx={{color:'blue'}}
+ component='form'
+ autoComplete='off'
+ onSubmit={(e: any) => {
+ checkDbInit();
+ handleNewUser(e, '1');
+ }}
+ sx={{ color: 'blue' }}
>
-
+
{
/>
-
+
Password
{
+ onChange={(e) => {
checkPasswordLength();
- setValues({...values, password:e.target.value})
+ setValues({ ...values, password: e.target.value });
}}
endAdornment={
@@ -100,8 +104,8 @@ const SignUp = () => {
label="Password"
/>
- {values.password && }
-
+ {values.password && }
+
{
type='password'
required
onChange={(e) => {
- setValues({...values, passwordConfirmation:e.target.value})
- confirmPassword()
+ setValues({ ...values, passwordConfirmation: e.target.value });
+ confirmPassword();
}}
sx={{
m: 1
}}
/>
{/* This is sacrilege but I hardcoded this bar and made it hidden to keep the same formatting as above */}
- {}
-
+ {}
+
{
- const inputElement =(document.getElementById('signupPhone') as HTMLInputElement).value;
- checkPhone(inputElement)
+ const inputElement = (document.getElementById('signupPhone') as HTMLInputElement).value;
+ checkPhone(inputElement);
}}
sx={{
m: 1
@@ -140,31 +144,34 @@ const SignUp = () => {
-
-
- )
-}
+
+ );
+};
export default SignUp;
\ No newline at end of file
diff --git a/src/components/css/metric.css b/src/components/css/metric.css
index 917a4c50..b1bf7927 100644
--- a/src/components/css/metric.css
+++ b/src/components/css/metric.css
@@ -1,19 +1,20 @@
.legend-container {
display: flex;
flex-direction: column;
- align-items: flex-start;
width: 170px;
+ align-items: center;
+ margin-top: 5px;
}
+.legend-container p {
+ margin-left: 8px;
+}
.aggregate-conatiner {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto;
margin-bottom: 50px;
justify-items: center;
-
- /* margin: 20px; */
- /* padding: 15px; */
}
.avaliable-box {
@@ -46,12 +47,8 @@
justify-content: center;
align-items: center;
flex-direction: column;
-
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
+ border-radius: 0.3rem;
+ box-shadow: rgba(0, 0, 0, 0.09) 0px 3px 12px;
}
.lineChart {
@@ -77,12 +74,8 @@
.metrics-options-form {
background-color: white;
padding: 20px 10px 15px 15px;
-
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
+ box-shadow: rgba(0, 0, 0, 0.09) 0px 3px 12px;
+ border-radius: 0.3rem;
}
.metrics-options-form input {
diff --git a/src/components/css/static.css b/src/components/css/static.css
index 09417f1c..94cd491a 100644
--- a/src/components/css/static.css
+++ b/src/components/css/static.css
@@ -48,3 +48,13 @@
content: url(../../../assets/docketeer-logs.svg);
width: 22px;
}
+
+.fa-expand {
+ content: url(../../../assets/expand-icon.svg);
+ width: 22px;
+}
+
+.fa-compress {
+ content: url(../../../assets/compress-icon.svg);
+ width: 22px;
+}
\ No newline at end of file
diff --git a/src/components/css/styles.css b/src/components/css/styles.css
index 39d7c958..16078c40 100644
--- a/src/components/css/styles.css
+++ b/src/components/css/styles.css
@@ -1,23 +1,27 @@
-@font-face {
- font-family: "Maven Pro";
- src: url(./font/MavenPro-Regular.ttf);
-}
+@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@100;200;300;400;500;600;700;800;900&display=swap');
+
* {
- font-family: "Maven Pro", sans-serif;
+ font-family: 'Lexend', sans-serif;
margin: 0;
padding: 0;
- box-sizing:border-box;
+ box-sizing: border-box;
+}
+
+header {
+ display: flex;
+ justify-content: center;
+ color: #042331;
}
body {
margin: 0;
- /* background: #276873; */
background: #042331;
}
i {
color: rgb(105, 105, 72);
- transition: 0.3s;
+ transition: 0.7s;
+ margin-right: 8px;
}
ul {
@@ -27,18 +31,20 @@ ul {
padding: 0;
}
+h4 {
+ margin-top: 12px;
+ font-size: large;
+}
+
.container {
display: flex;
background: #042331;
- /* border-radius: 30px; */
min-height: 750px;
- margin: 0.2vh;
height: 99.7vh;
width: 99.7vw;
}
.tab {
- /* border-radius: 30px; */
min-height: 750px;
min-width: 255px;
height: 99.6vh;
@@ -51,29 +57,54 @@ ul {
}
.renderContainers {
- /* display: flex; */
color: #042331;
- /* margin: 15px 10px 0px 10px; */
margin: 0px 10px;
padding: 0px 25px 0px 25px;
min-width: 78vw;
height: 100%;
- /* flex-wrap: wrap; */
+ flex-wrap: wrap;
overflow: scroll;
- /* border-radius: 30px; */
+ border-radius: 0.3rem;
background: #e1e4e6;
}
+.renderContainers.login-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-width: 40%;
+ width: 50%;
+ margin: 0 auto;
+ border-radius: 0.7rem;
+ padding-top: 30px;
+ padding-bottom: 120px;
+}
+
+.renderContainers.signup-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-width: 40%;
+ width: 50%;
+ margin: 5vh auto;
+ border-radius: 0.7rem;
+ padding-top: 30px;
+ padding-bottom: 120px;
+}
+
+.container-heading {
+ margin: 10px;
+}
+
+.settings-container.inner-box {
+ border-radius: 0.7rem;
+}
+
.header {
- /* border-top-left-radius: 30px;
- border-top-right-radius: 30px; */
- /* z-index: 2; */
- /* position: fixed; */
line-height: 90px;
font-size: 12px;
font-weight: 800;
background: #e1e4e6;
- /* min-width: 78vw; */
}
.header span {
@@ -85,7 +116,7 @@ ul {
}
.tabTitle {
- /* margin-left: 50px; */
+ margin: 20px 15px;
font-weight: bolder;
font-size: 30px;
}
@@ -96,18 +127,32 @@ ul {
}
.containers {
- background-color: #e1e4e6;
- /* margin-top: 75px; */
- max-height: 800px;
display: flex;
flex-wrap: wrap;
+ background-color: #e1e4e6;
+ max-height: 800px;
overflow-y: auto;
}
.viewsAndButton {
display: flex;
flex-direction: column;
- height: 80%;
+ height: 75%;
+ align-items: center;
+}
+
+.login-buttons {
+ width: 100%;
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 0px 1px 0px;
+}
+
+.register.login-buttons:hover {
+ background-color: #e3f6f5;
+}
+
+.signup-btn {
+ display: flex;
+ justify-content: space-between;
align-items: center;
}
@@ -116,60 +161,62 @@ ul {
}
.box {
- border: 1px solid #bab2b5;
- /* border-radius: 11.5px; */
margin-top: 20px;
- margin-left: 20px;
- width: 250px;
+ margin-right: 20px;
+ min-width: 250px;
background: white;
padding-bottom: 10px;
position: relative;
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
+ border-radius: 10px;
}
-.box:hover {
- -webkit-box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1);
- -moz-box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1);
- box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1);
+.stopped-containers {
+ display: flex;
+ flex-wrap: wrap;
+ min-width: auto;
}
+
.box-running {
- max-height: 240px;
- margin-bottom: 100px;
- padding-bottom: 0;
+ border-radius: 0.7rem;
}
.toggle-box {
- background-color: white;
- width: 250px;
transform: translate(-5px, 5px);
- box-shadow: 0px 9px 7px rgba(146, 139, 148, 1);
-}
-.toggle-box:hover {
- box-shadow: 0px 17px 14px 1px rgba(148, 139, 148, 1);
}
.box-button-running {
- /* border-radius: 0px 0px 10.5px 10.5px; */
transform: translate(0px, 0px);
box-shadow: 0px 9px 7px rgba(146, 139, 148, 1);
padding: 10px;
}
-.box-button-running:hover {
- /* border-radius: 0px 0px 10.5px 10.5px; */
+
+.volume-box-label {
+ color: white;
+ display: flex;
+ font-weight: bolder;
+ flex-direction: column;
+ background: #052e41c0;
+ padding: 10px;
+ border-radius: 10px 10px 0 0;
+ justify-content: flex-start;
+ max-width: 300px;
+}
+
+.volume-box-label h3 {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.box-label {
color: white;
display: flex;
- /* font-size: 16px; */
- font-weight: bold;
+ font-weight: bolder;
flex-direction: column;
background: #052e41c0;
padding: 10px;
- /* border-radius: 10px 10px 0 0; */
+ border-radius: 10px 10px 0 0;
justify-content: flex-start;
}
@@ -185,9 +232,10 @@ ul {
}
.box-info {
- font-size: 10px;
- margin-left: 5px;
- margin-right: 5px;
+ background: none;
+ font-size: 11px;
+ margin-left: 10px;
+ margin-right: 10px;
}
.box li {
@@ -195,12 +243,15 @@ ul {
margin: 5px;
width: 100%;
}
+
.tab ul li:hover {
- border-left: #e1e4e6 12px solid;
+ /* border-left: #e1e4e6 5px solid; */
+
}
.tab ul li a:hover {
font-weight: 900;
+ color: #ecfffe;
}
.tab ul li a:hover i {
@@ -236,12 +287,6 @@ ul {
padding-left: 25px;
}
-.box-button {
- position: relative;
- text-align: center;
- background: white;
-}
-
.stopped-header {
color: white;
display: flex;
@@ -272,7 +317,8 @@ ul {
.stopped-button {
text-align: center;
background: white;
- margin-top: 20px;
+ margin-top: 10px;
+ margin-bottom: 7px;
}
.images-header {
@@ -287,35 +333,62 @@ ul {
}
.chart-container {
- width: 300px;
- /* border: 1px solid #052e41c0; */
- margin: 40px 0px;
- /* border-radius: 10px 10px 0 0; */
+ width: 350px;
+ margin-bottom: 30px;
+ border-radius: 10px 10px 0 0;
+ box-shadow: rgba(0, 0, 0, 0.09) 0px 3px 12px;
}
+
.dougnutChart {
height: 170px;
width: 280px;
}
+.metricCharts {
+ width: 100%;
+ display: flex;
+ justify-content: space-around;
+ flex-wrap: wrap;
+}
+
.allCharts {
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ flex-direction: column;
+ background-color: white;
+ margin: 20px 0px;
+ height: 320px;
+ width: calc(50% - 30px);
+ padding: 20px;
+ box-shadow: rgba(0, 0, 0, 0.09) 0px 3px 12px;
+ border-radius: 0.3rem;
+ transition: width 0.5s ease-in;
+}
+
+.allCharts.expanded-chart {
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
background-color: white;
margin: 20px 0px 20px 0px;
- height: 500px;
- /* border-radius: 30px; */
- /* width: 94%; */
- /* margin-top: 25px;
- margin-left: 20px;
- margin-right: 20px; */
- padding: 15px;
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
+ height: 400px;
+ width: 100%;
+ transition: width 0.7s ease-out;
+}
+
+.buttonDisplay {
+ display: flex;
+ flex-direction: row;
+ justify-content: end;
+ align-content: center;
+}
+
+.chart-btn {
+ border: none;
+ margin-bottom: 10px;
+ background: none;
}
.gitHub-container {
@@ -331,6 +404,13 @@ ul {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
+.users-container {
+ border-radius: 0.5rem;
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+ -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+}
+
.settings-container {
display: flex;
justify-content: center;
@@ -338,17 +418,12 @@ ul {
flex-direction: column;
background-color: white;
margin: 20px 0px 20px 0px;
- /* border-radius: 30px; */
- /* width: 94%; */
- /* margin-top: 25px;
- margin-left: 20px;
- margin-right: 20px; */
- padding: 15px;
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
+ padding: 30px;
+ border-radius: 0.5rem;
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+ -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+ line-height: 1.5rem;
}
.container-name {
@@ -366,7 +441,6 @@ ul {
align-content: center;
flex-direction: column;
background-color: white;
- /* border-radius: 30px; */
width: 94%;
margin-top: 25px;
margin-left: 20px;
@@ -380,14 +454,12 @@ ul {
}
.chart-number {
+ padding-top: 5px;
+ padding-bottom: 5px;
background-color: white;
- font-size: 24px;
+ font-size: 22px;
text-align: center;
- -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
- 0 0 40px rgba(0, 0, 0, 0.1) inset;
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
+ border-radius: 0 0 10px 10px;
}
.section {
@@ -396,25 +468,36 @@ ul {
justify-content: space-evenly;
margin-bottom: 100px;
}
+
.block {
margin-top: 50px;
}
+.threshold {
+ background: #57a3c6c0;
+ font-weight: 300;
+ font-size: 17px;
+ color: white;
+ text-align: center;
+ line-height: 35px;
+ margin: 0;
+}
+
.chart-title {
background: #052e41c0;
- font-weight: 700;
- font-size: 22px;
+ font-weight: 500;
+ font-size: 20px;
color: white;
text-align: center;
- line-height: 50px;
- /* border-radius: 10px 10px 0 0; */
- margin: 0;
+ line-height: 45px;
+ border-radius: 10px 10px 0 0;
}
+/*
#drag-file {
- /* width: 300px; */
background-color: white;
-}
+} */
+
.modal-container {
position: fixed;
@@ -424,6 +507,7 @@ ul {
height: 100%;
background: rgba(0, 0, 0, 0.6);
}
+
.modal-header {
position: absolute;
left: 50%;
@@ -431,6 +515,7 @@ ul {
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
+
.display-block {
display: block;
}
@@ -442,21 +527,16 @@ ul {
.btn-compose-up {
display: flex;
justify-content: space-between;
- align-items: flex-end;
+ align-items: center;
}
.yml-boxes {
border: 1px solid #bab2b5;
- /* border-radius: 11.5px; */
margin: 10px 70px 10px 70px;
background: white;
min-width: 65vw;
}
-/* .yml-boxes:hover {
- -webkit-box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1);
- -moz-box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1);
- box-shadow: 0px 5px 8px 2px rgba(148, 139, 148, 1); */
-/* } */
+
.yml-labels {
display: flex;
@@ -464,11 +544,10 @@ ul {
align-items: center;
color: white;
background: #052e41c0;
- /* border-radius: 10px 10px 0 0; */
- /* font-family: 'Playfair Display', serif; */
padding: 0px 20px 0px 20px;
height: 50px;
}
+
.yml-info {
display: flex;
justify-content: center;
@@ -482,13 +561,6 @@ ul {
}
.yml-info-box {
- /* border: 1px solid #bab2b5; */
- /* border-radius: 5px; */
- /* margin-top: 10px;
- margin-left: 20px;
- margin-bottom: 5px; */
- /* padding: 5px;
- height: 100%; */
width: 200px;
height: 100px;
color: white;
@@ -511,6 +583,7 @@ ul {
0 0 40px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
+
.btn-process {
border: 0px solid #e1e4e6;
cursor: pointer;
@@ -518,10 +591,8 @@ ul {
}
.btn {
- /* background: linear-gradient(to bottom, #599bb3 5%, #408c99 100%); */
+ border-radius: 0.2rem;
background-color: #599bb3;
- /* border-radius: 11px; */
- /* border: 2px solid #29668f; */
border: 2px solid #599bb3;
display: inline-block;
cursor: pointer;
@@ -531,29 +602,62 @@ ul {
padding: 6px 12px;
text-decoration: none;
}
+
.btn:hover {
- /* background: linear-gradient(to bottom, #408c99 5%, #599bb3 100%); */
background-color: #408c99;
}
+
.btn:active {
position: relative;
top: 1px;
}
+.stop-btn-box {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+}
+
.stop-btn {
- margin-right: 10px;
+ margin-top: 20px;
+ margin-bottom: 20px;
box-shadow: 0px 10px 14px -7px grey;
background-color: white;
- /* border-radius: 4px; */
+ border-radius: 0.2rem;
border: 1px solid red;
display: inline-block;
cursor: pointer;
color: red;
font-size: 12px;
- padding: 4px 8px;
+ padding: 5px 10px;
text-decoration: none;
outline: none;
}
+
+.remove-btn {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ box-shadow: 0px 10px 14px -7px grey;
+ background-color: white;
+ border-radius: 0.2rem;
+ border: 1px solid red;
+ display: inline-block;
+ cursor: pointer;
+ color: red;
+ font-size: 12px;
+ padding: 5px 10px;
+ text-decoration: none;
+ outline: none;
+}
+
+.remove-btn:hover {
+ background-color: rgba(255, 0, 0, 0.75);
+ color: white;
+}
+
.stop-btn:hover {
background-color: rgba(255, 0, 0, 0.75);
color: white;
@@ -563,44 +667,64 @@ ul {
margin-right: 10px;
background-color: white;
box-shadow: 0px 10px 14px -7px grey;
- /* border-radius: 6px; */
+ border-radius: 0.2rem;
border: 1px solid green;
display: inline-block;
cursor: pointer;
color: green;
font-size: 12px;
- padding: 4px 8px;
+ padding: 5px 10px;
text-decoration: none;
outline: none;
}
+
.run-btn:hover {
background-color: rgba(0, 128, 0, 0.75);
color: white;
}
+
.run-btn:active {
position: relative;
top: 1px;
}
-.upload-btn {
- background: linear-gradient(to bottom, #599bb3 5%, #408c99 100%);
- background-color: #599bb3;
- /* border-radius: 11px; */
- /* border: 2px solid #29668f; */
- border: 2px solid #599bb3;
+.etc-btn {
+ background-color: white;
+ box-shadow: 0px 10px 14px -7px grey;
+ border-radius: 0.2rem;
+ border: 1px solid rgb(0, 100, 255);
display: inline-block;
cursor: pointer;
- color: #ffffff;
- font-size: 16px;
- font-weight: bold;
- padding: 3.5px 10px;
+ color: rgb(0, 100, 255);
+ font-size: 12px;
+ padding: 5px 10px;
text-decoration: none;
- margin: 5px;
+ outline: none;
+}
+
+.etc-btn:hover {
+ background-color: rgba(0, 100, 255, 0.75);
+ color: white;
+}
+
+.etc-btn:active {
+ position: relative;
+ top: 1px;
+}
+
+#upload-btn {
+ margin-right: 1vw;
+}
+
+#getlogs-btn {
+ margin-right: 1vw;
+ margin-bottom: 1vh;
}
.toggle-button {
text-align: center;
}
+
.toggle-button-detail {
font-size: 12px;
padding: 0px 75px;
@@ -616,9 +740,7 @@ ul {
align-content: center;
flex-direction: column;
background-color: white;
- /* border-radius: 30px; */
width: 94%;
- /* margin-top: 100px; */
margin-left: 20px;
margin-right: 20px;
padding: 30px 0px;
@@ -648,9 +770,10 @@ ul {
}
.volume-container-details {
- padding: 5px;
+ padding: 10px;
border-top: lightgray solid 2px;
overflow: hidden;
+ max-width: 300px;
}
.volume-container-details ul {
@@ -682,3 +805,18 @@ ul {
margin-left: 5;
margin-bottom: 30;
}
+
+#logo {
+ padding: 5vh 0;
+}
+
+.input-box {
+ padding: 1vh 1vw;
+ width: 50vw;
+ margin: 1vh 1vw 0 0;
+ border-radius: 0.2rem;
+}
+
+.user-table {
+ height: calc(100% - 70px) !important;
+}
\ No newline at end of file
diff --git a/src/components/display/LineChartDisplay.js b/src/components/display/LineChartDisplay.js
index 81eaaf8c..77039668 100644
--- a/src/components/display/LineChartDisplay.js
+++ b/src/components/display/LineChartDisplay.js
@@ -8,6 +8,7 @@ import * as actions from '../../redux/actions/actions';
import * as helper from '../helper/commands';
import { DataGrid } from '@mui/x-data-grid';
import { FormControlLabel, Checkbox } from '@mui/material';
+import { ReadableStreamBYOBRequest } from 'stream/web';
/**
* Displays linegraph and github metrics
@@ -16,11 +17,14 @@ import { FormControlLabel, Checkbox } from '@mui/material';
const LineChartDisplay = () => {
const [activeContainers, setActiveContainers] = useState({});
const [gitUrls, setGitUrls] = useState([]);
- const [timePeriod, setTimePeriod] = useState('');
+ const [timePeriod, setTimePeriod] = useState('4');
+ const [expanded, setExpanded] = useState({});
const memory = useSelector((state) => state.graphs.graphMemory);
const cpu = useSelector((state) => state.graphs.graphCpu);
const writtenIO = useSelector((state) => state.graphs.graphWrittenIO);
const readIO = useSelector((state) => state.graphs.graphReadIO);
+ const receivedIO = useSelector((state) => state.graphs.graphReceivedIO);
+ const transmittedIO = useSelector((state) => state.graphs.graphTransmittedIO);
const axis = useSelector((state) => state.graphs.graphAxis);
const runningList = useSelector((state) => state.containersList.runningList);
const stoppedList = useSelector((state) => state.containersList.stoppedList);
@@ -31,21 +35,24 @@ const LineChartDisplay = () => {
const buildCpu = (data) => dispatch(actions.buildCpu(data));
const buildWrittenIO = (data) => dispatch(actions.buildWrittenIO(data));
const buildReadIO = (data) => dispatch(actions.buildReadIO(data));
+ const buildReceivedIO = (data) => dispatch(actions.buildReceivedIO(data));
+ const buildTransmittedIO = (data) =>
+ dispatch(actions.buildTransmittedIO(data));
// Grabbing the metrics data to be displayed on the charts
async function getContainerMetrics() {
const containerNamesArr = Object.keys(activeContainers);
- // console.log('this is here', containerNamesArr);
const response = await fetch('http://localhost:3000/init/getMetrics', {
method: 'POST',
headers: {
- 'Content-Type': 'application/json'
+ 'Content-Type': 'application/json',
},
body: JSON.stringify({
- containers: containerNamesArr
- })
+ containers: containerNamesArr,
+ time: timePeriod,
+ }),
});
- return await response.json();
+ return await response.json();
}
// Auxilary Object which will be passed into Line component
@@ -55,16 +62,31 @@ const LineChartDisplay = () => {
};
const cpuObj = {
labels: axis,
- datasets: cpu
+ datasets: cpu,
};
const writtenIOObj = {
labels: axis,
- datasets: writtenIO
+ datasets: writtenIO,
};
const readIOObj = {
labels: axis,
- datasets: readIO
+ datasets: readIO,
};
+ const receivedIOObj = {
+ labels: axis,
+ datasets: receivedIO,
+ };
+ const transmittedIOObj = {
+ labels: axis,
+ datasets: transmittedIO,
+ };
+ // Not yet implemented but expecting to use for
+ // countainer count metrics over many hosts
+ const activeContainersCountObj = {
+ labels: axis,
+ datasets: activeContainersCountArr,
+ };
+ const activeContainersCountArr = [];
/**
* Resets all graph data in global store
@@ -76,21 +98,24 @@ const LineChartDisplay = () => {
buildAxis('clear');
buildWrittenIO('clear');
buildReadIO('clear');
+ buildReceivedIO('clear');
+ buildTransmittedIO('clear');
+
// if active containers is empty render the empty graphs
if (!Object.keys(activeContainers).length) {
return;
}
- const input = await getContainerMetrics();
+ // const input = await getContainerMetrics();
const generateLineColor = (containerName, activeContainers) => {
const colorOptions = [
- 'red',
- 'blue',
- 'green',
- 'purple',
- 'yellow',
- 'grey',
- 'orange'
+ '#e74645',
+ '#2a6fdb',
+ '#1ac0c6',
+ '#ffb3f2',
+ '#facd60',
+ '#679186',
+ '#ff9400',
];
const idx = activeContainers.indexOf(containerName);
return colorOptions[idx];
@@ -101,25 +126,26 @@ const LineChartDisplay = () => {
const obj = {
label: containerName,
data: [],
- lineTension: .5,
- fill: false,
+ lineTension: 0.5,
+ fill: true,
borderColor: generateLineColor(
containerName,
- Object.keys(activeContainers)
- )
+ Object.keys(activeContainers),
+ ),
};
return obj;
};
// Datastructure for Bargraph
- const buildBarGraphObj = (containerName) => {
+ const buildBarGraphObj = (containerName, stackID = 'Stack 0') => {
const obj = {
label: containerName,
data: [],
fill: false,
backgroundColor: generateLineColor(
containerName,
- Object.keys(activeContainers)
- )
+ Object.keys(activeContainers),
+ ),
+ stack: stackID,
};
return obj;
};
@@ -129,54 +155,60 @@ const LineChartDisplay = () => {
buildAxis('clear');
buildWrittenIO('clear');
buildReadIO('clear');
+ buildReceivedIO('clear');
+ buildTransmittedIO('clear');
if (!Object.keys(activeContainers).length) {
return;
}
const containerMetrics = await getContainerMetrics();
-
+ console.log(
+ '🚀 ~ file: LineChartDisplay.js:138 ~ formatData ~ containerMetrics',
+ containerMetrics,
+ );
+
const auxObj = {};
Object.keys(activeContainers).forEach((container) => {
auxObj[container] = {
memory: buildLineGraphObj(container),
cpu: buildLineGraphObj(container),
- writtenIO: buildBarGraphObj(container),
- readIO: buildBarGraphObj(container)
+ writtenIO: buildBarGraphObj(container, 'Stack 1'),
+ readIO: buildBarGraphObj(container),
+ receivedIO: buildBarGraphObj(container), // added
+ transmittedIO: buildBarGraphObj(container, 'Stack 1'), // added
};
});
// iterate through each row from fetch and build Memory, CPU, Written/Read Block_IO objects [{}, {}, {}, {}]
+ // parse metrics received from DB, into a usable array
containerMetrics.rows.forEach((dataPoint) => {
const currentContainer = dataPoint.container_name;
const writtenReadIO = dataPoint.block_io.split('/');
- auxObj[currentContainer].cpu.data.push(
- dataPoint.cpu_pct.replace('%', '')
- );
+ const receivedAndTransmittedIO = dataPoint.net_io.split('/');
+ auxObj[currentContainer].cpu.data.push(dataPoint.cpu_pct.replace('%', ''));
auxObj[currentContainer].memory.data.push(
- dataPoint.memory_pct.replace('%', '')
+ dataPoint.memory_pct.replace('%', ''),
);
auxObj[currentContainer].writtenIO.data.push(
- parseFloat(writtenReadIO[0].replace(/([A-z])+/g, ''))
+ parseFloat(writtenReadIO[0].replace(/([A-z])+/g, '')),
);
auxObj[currentContainer].readIO.data.push(
- parseFloat(writtenReadIO[1].replace(/([A-z])+/g, ''))
+ parseFloat(writtenReadIO[1].replace(/([A-z])+/g, '')),
);
- let date = '';
- let time = '';
- for (let i = 1; i < dataPoint.created_at.length; i++){
- if (dataPoint.created_at[i] === 'T') {
- break;
- }
- else (date += dataPoint.created_at[i]);
- }
- for (let i = 11; i < dataPoint.created_at.length; i++){
- if (dataPoint.created_at[i] === '.') {
- break;
- }
- else (time += dataPoint.created_at[i]);
- }
+ auxObj[currentContainer].receivedIO.data.push(
+ parseFloat(receivedAndTransmittedIO[0].replace(/([A-z])+/g, '')),
+ );
+ auxObj[currentContainer].transmittedIO.data.push(
+ parseFloat(receivedAndTransmittedIO[1].replace(/([A-z])+/g, '')),
+ );
+
+ // created_at Sample: 2023-01-23T15:47:27.640Z
+ // key indicators "T" [10] and "." [20]
+ const date = dataPoint.created_at.slice(1,10);
+ const time = dataPoint.created_at.slice(11,16);
+
const timeStamp = `${date} @ ${time}`;
buildAxis(timeStamp);
});
@@ -198,12 +230,16 @@ const LineChartDisplay = () => {
auxObj[containerName].cpu.data.unshift('0.00');
auxObj[containerName].writtenIO.data.unshift('0.00');
auxObj[containerName].readIO.data.unshift('0.00');
+ auxObj[containerName].receivedIO.data.unshift('0.00');
+ auxObj[containerName].transmittedIO.data.unshift('0.00');
}
}
buildMemory([auxObj[containerName].memory]);
buildCpu([auxObj[containerName].cpu]);
buildWrittenIO([auxObj[containerName].writtenIO]);
buildReadIO([auxObj[containerName].readIO]);
+ buildReceivedIO([auxObj[containerName].receivedIO]);
+ buildTransmittedIO([auxObj[containerName].transmittedIO]);
});
};
@@ -222,9 +258,9 @@ const LineChartDisplay = () => {
const url =
urlObj.rows[0].github_url +
new URLSearchParams({
- since: `${date}`
+ since: `${date}`,
});
- // need an actual url to test this, right now it can't connect
+ // need an actual url to test this, right now it can't connect
const data = await fetch(url);
const jsonData = await data.json();
@@ -233,13 +269,13 @@ const LineChartDisplay = () => {
time: commitData.commit.author.date,
url: commitData.html_url,
author: commitData.commit.author.name,
- message: commitData.commit.message
+ message: commitData.commit.message,
});
});
} else {
ob[containerName].push({
time: '',
- url: 'Connect github repo in settings'
+ url: 'Connect github repo in settings',
});
}
return ob;
@@ -249,18 +285,27 @@ const LineChartDisplay = () => {
Promise.all(
Object.keys(activeContainers).map((container) => {
return fetchGitData(container);
- })
+ }),
).then((data) => setGitUrls(data));
};
// populating the github commits into a MUI DataGrid
- // This should allow multiple tables be stacked if multiple containers are selected
+ // This should allow multiple tables be stacked if multiple containers are selected
const columns = [
- {field: 'date', headerName: 'Date', width: 125 },
- {field: 'time', headerName: 'Time', width: 100 },
- {field: 'url', headerName: 'URL', width: 175, renderCell: (params) =>
{params.row.id} },
- {field: 'author', headerName: 'Author', width: 175 },
- {field: 'message', headerName: 'Message', width: 525, align: 'left' },
+ { field: 'date', headerName: 'Date', width: 125 },
+ { field: 'time', headerName: 'Time', width: 100 },
+ {
+ field: 'url',
+ headerName: 'URL',
+ width: 175,
+ renderCell: (params) => (
+
+ {params.row.id}
+
+ ),
+ },
+ { field: 'author', headerName: 'Author', width: 175 },
+ { field: 'message', headerName: 'Message', width: 525, align: 'left' },
];
const gitData = gitUrls.map((el, index) => {
const name = Object.keys(el);
@@ -276,8 +321,8 @@ const LineChartDisplay = () => {
author = ob.author;
url = ob.url;
message = '';
- if (ob.message){
- if (ob.message.includes('<')){
+ if (ob.message) {
+ if (ob.message.includes('<')) {
for (let i = 0; i < ob.message.length; i++) {
if (ob.message[i] === '<') break;
message += ob.message[i];
@@ -290,7 +335,10 @@ const LineChartDisplay = () => {
time = time.split('T');
date = time[0];
time = time[1];
- time = time.split('').slice(0, time.length - 1).join('');
+ time = time
+ .split('')
+ .slice(0, time.length - 1)
+ .join('');
}
rows.push({
date: date,
@@ -298,22 +346,22 @@ const LineChartDisplay = () => {
url: url,
author: author,
message: message,
- id: `Github Commit #${index}`
+ id: `Github Commit #${index}`,
});
});
return (
-
+
{name}
-
+
'auto'}
initialState={{
sorting: {
- sortModel: [{field: 'date', sort: 'asc'}]
- }
+ sortModel: [{ field: 'date', sort: 'asc' }],
+ },
}}
/>
@@ -322,29 +370,49 @@ const LineChartDisplay = () => {
});
let currentList;
+ let runningListEl;
+ let stoppedListEl;
const selectList = () => {
- const result = [];
- const completeContainerList = [...runningList, ...stoppedList];
- completeContainerList.forEach((container, index) => {
- const containerNameKey = container.Name
- ? container.Name
- : container.Names;
- result.push(
+ const result = [[], []];
+ // const completeContainerList = [...runningList, ...stoppedList];
+
+ runningList.forEach((container, index) => {
+ const containerNameKey = container.Name ? container.Name : container.Names;
+ result[0].push(
}
label={containerNameKey}
- />
+ />,
);
});
- currentList = result;
+ runningListEl = result[0];
+
+ stoppedList.forEach((container, index) => {
+ const containerNameKey = container.Name ? container.Name : container.Names;
+ result[1].push(
+
+ }
+ label={containerNameKey}
+ />,
+ );
+ });
+ stoppedListEl = result[1];
};
const handleChange = (e) => {
@@ -364,42 +432,107 @@ const LineChartDisplay = () => {
};
const cpuOptions = {
- plugins:{
- title: { display: true, text: 'CPU', font: {size: 18}, position: 'top' },
- tooltips: {enabled: true, mode: 'index'},
- legend: { display: true, position: 'bottom' }
+ plugins: {
+ title: {
+ display: true,
+ text: 'CPU',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
},
responsive: true,
- maintainAspectRatio: false
+ maintainAspectRatio: false,
};
const memoryOptions = {
- plugins:{
- title: { display: true, text: 'MEMORY', font: {size: 18}, position: 'top' },
- tooltips: {enabled: true, mode: 'index'},
- legend: { display: true, position: 'bottom' }
+ plugins: {
+ title: {
+ display: true,
+ text: 'MEMORY',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
},
responsive: true,
- maintainAspectRatio: false
+ maintainAspectRatio: false,
};
const writtenIOOptions = {
- plugins:{
- title: { display: true, text: 'IO BYTES WRITTEN BY IMAGE', font: {size: 18}, position: 'top' },
- tooltips: {enabled: true, mode: 'index'},
- legend: { display: true, position: 'bottom' }
+ plugins: {
+ title: {
+ display: true,
+ text: 'IO BYTES WRITTEN BY CONTAINER',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
},
responsive: true,
- maintainAspectRatio: false
+ maintainAspectRatio: false,
};
const readIOOptions = {
- plugins:{
- title: { display: true, text: 'IO BYTES READ BY IMAGE', font: {size: 18}, position: 'top' },
- tooltips: {enabled: true, mode: 'index'},
- legend: { display: true, position: 'bottom' }
+ plugins: {
+ title: {
+ display: true,
+ text: 'IO BYTES READ BY CONTAINER',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ };
+
+ const receivedIOOptions = {
+ plugins: {
+ title: {
+ display: true,
+ text: 'IO BYTES RECEIVED BY CONTAINER',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ };
+
+ const transmittedIOOptions = {
+ plugins: {
+ title: {
+ display: true,
+ text: 'IO BYTES TRANSMITTED BY CONTAINER',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ };
+
+ const activeContainersCountOptions = {
+ plugins: {
+ title: {
+ display: true,
+ text: 'CONTAINER COUNT',
+ font: { size: 18 },
+ position: 'top',
+ },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: true, position: 'bottom' },
},
responsive: true,
- maintainAspectRatio: false
+ maintainAspectRatio: false,
};
selectList();
@@ -410,59 +543,265 @@ const LineChartDisplay = () => {
return (
-
-
Over Time
+
+
Metrics Over Time
-
+
+
+ {/* first chart - start */}
-
-
-
+
+
+
+ {expanded['Line-Cpu-Display'] ? (
+ {
+ setExpanded({ ...expanded, ['Line-Cpu-Display']: false });
+ }}
+ >
+
+
+ ) : (
+
+ setExpanded({ ...expanded, ['Line-Cpu-Display']: true })
+ }
+ >
+
+
+ )}
+
+
+ {/* first chart - end */}
+ {/* second chart - start */}
+
+
+
+ {expanded['Line-Memory-Display'] ? (
+ {
+ setExpanded({ ...expanded, ['Line-Memory-Display']: false });
+ }}
+ >
+
+
+ ) : (
+
+ setExpanded({ ...expanded, ['Line-Memory-Display']: true })
+ }
+ >
+
+
+ )}
+
+
+ {/* second chart - end */}
+ {/* third chart - start */}
+
+
+
+ {expanded['written-IO'] ? (
+ {
+ setExpanded({ ...expanded, ['written-IO']: false });
+ }}
+ >
+
+
+ ) : (
+
+ setExpanded({ ...expanded, ['written-IO']: true })
+ }
+ >
+
+
+ )}
+
+
+ {/* third chart - end */}
-
-
-
-
-
-
-
-
-
-
+ {/* fourth chart - start */}
+
+
+
+ {expanded['read-IO'] ? (
+ {
+ setExpanded({ ...expanded, ['read-IO']: false });
+ }}
+ >
+
+
+ ) : (
+ setExpanded({ ...expanded, ['read-IO']: true })}
+ >
+
+
+ )}
+
+
+ {/* fourth chart - end */}
+
+ {/* fifth chart - start */}
+
+
+
+ {expanded['received-IO'] ? (
+ {
+ setExpanded({ ...expanded, ['received-IO']: false });
+ }}
+ >
+
+
+ ) : (
+
+ setExpanded({ ...expanded, ['received-IO']: true })
+ }
+ >
+
+
+ )}
+
+
+ {/* fifth chart - end */}
+
+ {/* sixth chart - start */}
+
+
+
+ {expanded['transmitted-IO'] ? (
+ {
+ setExpanded({ ...expanded, ['transmitted-IO']: false });
+ }}
+ >
+
+
+ ) : (
+
+ setExpanded({ ...expanded, ['transmitted-IO']: true })
+ }
+ >
+
+
+ )}
+
+
+ {/* sixth chart - end */}
+
+ {/*
+
+
*/}
+
+ {/*
GitHub History
-
- {gitData}
+
*/}
+ {/* {gitData} */}
);
};
diff --git a/src/components/display/ProcessLogsTable.tsx b/src/components/display/ProcessLogsTable.tsx
index fae3dcab..a704e4a4 100644
--- a/src/components/display/ProcessLogsTable.tsx
+++ b/src/components/display/ProcessLogsTable.tsx
@@ -39,27 +39,25 @@ const ProcessLogsTable = () => {
['container', 'type', 'time', 'message'],
]);
- const [logs, setLogs] = useState({ stdout: [], stderr: [] });
- const { stdout, stderr } = logs;
+
+ const [counter, setCounter] = useState(0);
+ const { stdout, stderr } = store.getState().processLogs.containerLogs;
// This will update the logs table after all logs have been pulled - there will be a lag before they render
useEffect(() => {
tableData();
- }, [logs.stderr.length, csvData.length]);
+ }, [counter, csvData.length]);
// Get logs button handler function. Grabs logs and updates component state
- const handleGetLogs = (idList: string[]) => {
+ const handleGetLogs = async (idList: string[]) => {
const optionsObj = buildOptionsObj(idList);
// Using a promise as the process to pull the container logs takes a fair bit of time
- const containerLogsPromise = Promise.resolve(
- getLogs(optionsObj, getContainerLogsDispatcher)
- );
- containerLogsPromise.then((data) => {
- const newLogs = data;
- setLogs(newLogs as keyof typeof setLogs);
- return newLogs;
- });
+ const containerLogs = await getLogs(optionsObj, getContainerLogsDispatcher);
+ getContainerLogsDispatcher(containerLogs);
+ console.log('containerLogs', containerLogs);
+ setCounter(counter + 1);
+ return containerLogs;
};
const columns = [
@@ -126,7 +124,7 @@ const ProcessLogsTable = () => {
}
};
-
+
type CSVData = string[];
@@ -136,7 +134,7 @@ const ProcessLogsTable = () => {
const newCSV: CSVData[] = [];
if (stdout) {
- stdout.forEach((log, index) => {
+ stdout.forEach((log: { [k: string]: any; }) => {
const currCont = runningList.find(
(el: ContainerType) => el.ID === log["containerName"]
);
@@ -149,8 +147,9 @@ const ProcessLogsTable = () => {
});
newCSV.push([currCont.Name, 'stdout', log['timeStamp'], log['logMsg']]);
});
-
- stderr.forEach((log, index) => {
+ }
+ if (stderr) {
+ stderr.forEach((log: { [k: string]: any; }, index: any) => {
const currCont = runningList.find(
(el: ContainerType) => el.ID === log["containerName"]
);
@@ -159,7 +158,7 @@ const ProcessLogsTable = () => {
type: 'stderr',
time: log['timeStamp'],
message: log['logMsg'],
- id: parseInt(`stderr ${index}`),
+ id: parseInt(index),
});
newCSV.push([currCont.Name, 'stderr', log['timeStamp'], log['logMsg']]);
});
@@ -171,96 +170,77 @@ const ProcessLogsTable = () => {
return (
+
+
Container Process Logs
+
+
+
+
Running Containers:
+
+ {containerSelectors} {/** Checkboxes for running containers */}
+
+
+
+
{
handleGetLogs(btnIdList);
}}
>
- Get Logs
-
-
+ GET LOGS
+
+
- Download To CSV
+ DOWNLOAD TO CSV
-
+
-
+
+
{
tog()} className="toggle-button">
{toggle ? (
- Hide Details
+ Hide Details
) : (
- Show Details
+ Show Details
)}
diff --git a/src/components/helper/commands.tsx b/src/components/helper/commands.tsx
index aeeec7c8..e6fce943 100644
--- a/src/components/helper/commands.tsx
+++ b/src/components/helper/commands.tsx
@@ -2,7 +2,6 @@
The below comment removes all Typescript errors. Please remove this line of code to see what needs to be configured for Typescript compliance
*/
// @ts-noCheck
-
import parseContainerFormat from './parseContainerFormat';
import {
filterOneProperty,
@@ -11,60 +10,9 @@ import {
import store from '../../renderer/store';
import { makeArrayOfObjects } from './processLogHelper';
import * as child_process from 'child_process';
+import { PostAdd } from '@mui/icons-material';
+import { removeContainer } from '../../redux/actions/actions';
-/**
- * Grabs all active containers on app-start up
- *
- * @param {*} runningList
- * @param {*} callback
- */
-
-
-export const addRunning = (runningList, callback) => {
- window.nodeMethod.runExec(
- 'docker stats --no-stream --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`addRunning stderr: ${stderr}`);
- return;
- }
- // trim whitespace at end out stdout, slice to remove trailing comma and remove spaces
-
- const dockerOutput = `[${stdout
- .trim()
- .slice(0, -1)
- .replaceAll(' ', '')}]`;
-
- const convertedValue = JSON.parse(dockerOutput);
-
- const newList = [];
-
- for (let i = 0; i < convertedValue.length; i++) {
- let isInTheList = false;
- for (const container of runningList) {
- if (container.ID === convertedValue[i].ID) {
- isInTheList = true;
- break;
- }
- }
- isInTheList ? '' : newList.push(convertedValue[i]);
- }
- // console.log('addrunning newlist', newList);
- newList.length ? callback(newList) : '';
- }
- );
-};
-
-/**
- * Refreshes running containers
- *
- * @param {*} callback
- * @param {*} runningList
- */
const errorsCalled = {};
@@ -73,216 +21,153 @@ const errorCheck = (key, error) => {
errorsCalled[key] = error.message;
alert(`Make sure Docker Desktop is running. \n\n ${error.message}`);
}
- else{
+ else {
console.log(error.message);
}
return;
};
+/**
+ * Grabs all active containers on app-start up
+ *
+ * @param {*} refreshHostData
+ */
+
+export const getHostStats = (refreshHostData) => {
+ fetch('http://localhost:3000/command/getHost')
+ .then((res) => res.json())
+ .then((data) => {
+ refreshHostData(data);
+ })
+ .catch((err) => console.log(err));
+};
+
+/**
+ * Refreshes running containers
+ *
+ * @param {*} refreshRunningContainers
+ */
+
+// moved existing "command" functions to backend '/command'
export const refreshRunning = (refreshRunningContainers) => {
- window.nodeMethod.runExec(
- 'docker stats --no-stream --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- errorCheck('refreshRunning', error);
- return;
- }
- if (stderr) {
- console.log(`refreshRunning stderr: ${stderr}`);
- return;
- }
-
- const dockerOutput = `[${stdout
- .trim()
- .slice(0, -1)
- .replaceAll(' ', '')}]`;
- const convertedValue = JSON.parse(dockerOutput);
- refreshRunningContainers(convertedValue);
- }
- );
+ fetch('http://localhost:3000/command/refreshRunning')
+ .then((data) => data.json())
+ .then((runningContainers) => {
+ refreshRunningContainers(runningContainers);
+ })
+ .catch((err) => console.log(err));
};
+
/**
* Refreshes stopped containers
*
- * @param {*} callback
+ * @param {*} refreshStoppedContainers
*/
export const refreshStopped = (refreshStoppedContainers) => {
- window.nodeMethod.runExec(
- 'docker ps -f "status=exited" --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- errorCheck('refreshStopped', error);
- return;
- }
- if (stderr) {
- console.log(`refreshStopped stderr: ${stderr}`);
- return;
- }
- // trim whitespace at end out stdout and slice to remove trailing comma
- const dockerOutput = stdout.trim().slice(0, -1);
- let output = `[${dockerOutput}]`;
- output = JSON.parse(output);
- refreshStoppedContainers(output);
- }
- );
+ fetch('http://localhost:3000/command/refreshStopped')
+ .then((data) => data.json())
+ .then((stoppedContainers) => {
+ refreshStoppedContainers(stoppedContainers);
+ })
+ .catch((err) => console.log(err));
};
/**
* Refreshes images
*
- * @param {*} callback
+ * @param {*} refreshImagesList
*/
-export const refreshImages = (callback) => {
- window.nodeMethod.runExec('docker images', (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- errorCheck('refreshImages', error);
- return;
- }
- if (stderr) {
- console.log(`refreshImages stderr: ${stderr}`);
- return;
- }
- const value = parseContainerFormat.convert(stdout);
- const objArray = ['reps', 'tag', 'imgid', 'size'];
- const resultImages = [];
-
- for (let i = 0; i < value.length; i++) {
- const innerArray = [];
- if (value[i][0] !== '
') {
- innerArray.push(value[i][0]);
- innerArray.push(value[i][1]);
- innerArray.push(value[i][2]);
- innerArray.push(value[i][6]);
- resultImages.push(innerArray);
- }
- }
-
- const convertedValue = parseContainerFormat.convertArrToObj(
- resultImages,
- objArray
- );
- callback(convertedValue);
- });
+export const refreshImages = (refreshImagesList) => {
+ fetch('http://localhost:3000/command/refreshImages')
+ .then((data) => data.json())
+ .then((imagesList) => {
+ refreshImagesList(imagesList);
+ })
+ .catch((err) => console.log(err));
};
/**
- * Removes images
+ * Removes stopped containers
*
- * @param {*} id
- * @param {*} callback
+ * @param {*} containerID
+ * @param {*} removeContainer
*/
-export const remove = (id, callback) => {
- window.nodeMethod.runExec(`docker rm ${id}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`remove stderr: ${stderr}`);
- return;
- }
- callback(id);
- });
+export const remove = (containerID, removeContainer) => {
+ fetch(`http://localhost:3000/command/removeContainer?id=${containerID}`)
+ .then((message) => message.json())
+ .then((message) => {
+ console.log({ message });
+ removeContainer(containerID);
+ })
+ .catch((err) => console.log(err));
};
/**
* Stops a container on what user selects
*
* @param {*} id
- * @param {*} callback
+ * @param {*} refreshStoppedContainers
*/
-export const stop = (id, callback) => {
- window.nodeMethod.runExec(`docker stop ${id}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`stop stderr: ${stderr}`);
- return;
- }
- callback(id);
- });
+export const stop = (id, refreshStoppedContainers) => {
+ fetch(`http://localhost:3000/command/stopContainer?id=${id}`)
+ .then((message) => message.json())
+ .then((message) => {
+ console.log({ message });
+ refreshStoppedContainers(id);
+ })
+ .catch((err) => console.log(err));
};
/**
- * Starts the container
+ * Starts a stopped container in containers tab
*
* @param {*} id
- * @param {*} callback
+ * @param {*} runStoppedContainerDispatcher
*/
-export const runStopped = (
- id,
- runStoppedContainerDispatcher,
-) => {
- window.nodeMethod.runExec(`docker start ${id}`, (error, stdout, stderr) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`runStopped stderr: ${stderr}`);
- return;
- }
- runStoppedContainerDispatcher(id);
- });
+export const runStopped = (id, runStoppedContainerDispatcher) => {
+ fetch(`http://localhost:3000/command/runStopped?id=${id}`)
+ .then((message) => message.json())
+ .then((message) => {
+ console.log({ message });
+ runStoppedContainerDispatcher(id);
+ })
+ .catch((err) => console.log(err));
};
/**
- * Run image
+ * Runs an image from the pulled images list in image tab
*
- * @param {*} id
- * @param {*} runningList
- * @param {*} callback_1
- * @param {*} callback_2
+ * @param {*} container
+ * @param {*} refreshRunningContainers
*/
-
-// this function is used to run an image from the image tab
-export const runIm = (container, runningList, callback_1, callback_2) => {
- // props.runIm(ele['imgid'], props.runningList, helper.addRunning, props.addRunningContainers)
- const { imgid, reps, tag } = container;
- const containerId = Math.floor(Math.random() * 100)
- const filteredRepo = reps
- .replace(/[,\/#!$%\^&\*;:{}=\`~()]/g, ".")
- .replace(/\s{2,}/g, " ");
- window.nodeMethod.runExec(`docker run --name ${filteredRepo}-${tag}_${containerId} ${reps}:${tag}`, (error, stdout, stderr) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`runIm stderr: ${stderr}`);
- return;
- }
-});
- callback_1(runningList, callback_2);
- alert('Running container');
+export const runIm = (container, refreshRunningContainers) => {
+ fetch('http://localhost:3000/command/runImage', {
+ method: 'post', headers: {
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify(container)
+ })
+ .then((data) => data.json())
+ .then((newRunningList) => {
+ refreshRunningContainers(newRunningList);
+ })
+ .catch((err) => console.log(err));
+ alert('Running container.');
};
/**
- * Remove Image
+ * Removes an image from pulled images list in image tab
*
* @param {*} id
- * @param {*} imagesList
- * @param {*} callback_1
- * @param {*} callback_2
+ * @param {*} refreshImages
+ * @param {*} refreshImagesList
*/
-export const removeIm = (id, imagesList, callback_1, callback_2) => {
- window.nodeMethod.runExec(`docker rmi -f ${id}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(
- `${error.message}` +
- '\nPlease stop running container first then remove.'
- );
- return;
- }
- if (stderr) {
- console.log(`removeIm stderr: ${stderr}`);
- return;
- }
- callback_1(callback_2);
- });
+export const removeIm = (id, refreshImages, refreshImagesList) => {
+ fetch(`http://localhost:3000/command/removeImage?id=${id}`)
+ .then(() => {
+ refreshImages(refreshImagesList)
+ .catch((err) => console.log(err));
+ });
};
/**
@@ -293,19 +178,12 @@ export const removeIm = (id, imagesList, callback_1, callback_2) => {
export const handlePruneClick = (e) => {
e.preventDefault();
- window.nodeMethod.runExec(
- 'docker system prune --force',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(`${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`handlePruneClick stderr: ${stderr}`);
- return;
- }
- }
- );
+ fetch(`http://localhost:3000/command/dockerPrune`)
+ .then((message) => message.json())
+ .then((message) => {
+ console.log({ message });
+ })
+ .catch((err) => console.log(err));
};
/**
@@ -315,22 +193,12 @@ export const handlePruneClick = (e) => {
*/
export const pullImage = (repo) => {
- window.nodeMethod.runExec(`docker pull ${repo}`, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(
- `Image repo '${repo}' seems to not exist, or may be a private repo.`
- );
- return;
- }
- if (stderr) {
- console.log(`pullImage stderr: ${stderr}`);
- return;
- }
-
- alert(`${repo} is currently being downloaded`);
- console.log(stdout);
- // if not error, add a loading component until page renders a new component
- });
+ fetch(`http://localhost:3000/command/pullImage?repo=${repo}`)
+ .then((message) => message.json())
+ .then((message) => {
+ console.log({ message });
+ })
+ .catch((err) => console.log(err));
};
/**
@@ -340,179 +208,85 @@ export const pullImage = (repo) => {
*/
export const networkContainers = (getNetworkContainers) => {
- window.nodeMethod.runExec(
- 'docker network ls --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.log(`networkContainers error: ${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`networkContainers stderr: ${stderr}`);
- return;
- }
-
- const dockerOutput = `[${stdout
- .trim()
- .slice(0, -1)
- .replaceAll(' ', '')}]`;
-
- // remove docker network defaults named: bridge, host, and none
- const networkContainers = JSON.parse(dockerOutput).filter(
- ({ Name }) => Name !== 'bridge' && Name !== 'host' && Name !== 'none'
- );
-
+ fetch(`http://localhost:3000/command/networkContainers`)
+ .then((data) => data.json())
+ .then((networkContainers) => {
getNetworkContainers(networkContainers);
- }
- );
+ })
+ .catch((err) => console.log(err));
};
+/**
+ * Inspects a specific containers
+ * Docketeer 9.0 => We don't see this called anywhere(?) Maybe if future iterators
+ * have a use for this, the backend routing / fetching is set up for you!
+ *
+ * @param {*} containerId
+ */
+
export const inspectDockerContainer = (containerId) => {
- window.nodeMethod.runExec(
- `docker inspect ${containerId}`,
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.log(`inspectDockerContainer error: ${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`inspectDockerContainer stderr: ${stderr}`);
- return;
- }
- console.log(stdout);
- }
- );
+ fetch(`http://localhost:3000/command/inspect?id=${containerId}`)
+ .then((data) => data.json())
+ .then((data) => {
+ console.log(data);
+ })
+ .catch((err) => console.log(err));
};
/**
* Compose up a docker container network
*
- * @param {*} fileLocation
+ * @param {*} getContainerStacks
+ * @param {*} filePath
* @param {*} ymlFileName
*/
-export const dockerComposeUp = (fileLocation, ymlFileName) => {
- console.log(fileLocation, ymlFileName);
- return new Promise((resolve, reject) => {
- const nativeYmlFilenames = [
- 'docker-compose.yml',
- 'docker-compose.yaml',
- 'compose.yml',
- 'compose.yaml',
- ];
- let cmd = `cd ${fileLocation} && docker compose up -d`;
- // if ymlFilename is not a native yml/yaml file name, add -f flag and non-native filename
-
- if (!nativeYmlFilenames.includes(ymlFileName)) {
- cmd = `cd ${fileLocation} && docker compose -f ${ymlFileName} up -d`;
- }
-
- window.nodeMethod.runExec(cmd, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.warn(error.message);
- return;
- }
- if (stderr) {
- resolve(stderr);
- }
- if (stdout) {
- console.log(stdout);
- }
- });
- });
+export const dockerComposeUp = (getContainerStacks, filePath, ymlFileName) => {
+ fetch('http://localhost:3000/command/composeUp', {
+ method: 'post', headers: {
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify({ filePath: filePath, ymlFileName: ymlFileName })
+ })
+ .then((data) => data.json())
+ .then((dockerOutput) => {
+ getContainerStacks(dockerOutput);
+ })
+ .catch((err) => console.log(err));
};
/**
* Get list of running container networks
*
* @param {*} getContainerStacks
- * @param {*} filePath
- * @param {*} ymlFileName
*/
-export const dockerComposeStacks = (
- getContainerStacks,
- filePath,
- ymlFileName
-) => {
- let parseDockerOutput;
-
- window.nodeMethod.runExec(
- 'docker network ls --filter "label=com.docker.compose.network" --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.log(`dockerComposeStacks error: ${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`dockerComposeStacks stderr: ${stderr}`);
- return;
- }
-
- // create array of running container network objects
- // the array is sorted in alphabetical order based on network Name
- const dockerOutput = `[${stdout
- .trim()
- .slice(0, -1)
- .replaceAll(' ', '')}]`;
- parseDockerOutput = JSON.parse(dockerOutput);
-
- // if container network was composed through the application, add a filePath and ymlFileName property to its container network object
- if (filePath && ymlFileName) {
- const directoryNameArray = filePath.split('/');
- const containerNetworkName =
- directoryNameArray[directoryNameArray.length - 1].concat('_default');
-
- parseDockerOutput.forEach((obj) => {
- if (containerNetworkName === obj.Name) {
- obj.FilePath = filePath;
- obj.YmlFileName = ymlFileName;
- }
- });
- }
-
- getContainerStacks(parseDockerOutput);
- }
- );
+export const dockerComposeStacks = (getContainerStacks) => {
+ fetch('http://localhost:3000/command/composeStacks')
+ .then((data) => data.json())
+ .then((dockerOutput) => {
+ getContainerStacks(dockerOutput);
+ })
+ .catch((err) => console.log(err));
};
/**
* Compose down selected container network
*
- * @param {*} fileLocation
+ * @param {*} filePath
* @param {*} ymlFileName
*/
-export const dockerComposeDown = (fileLocation, ymlFileName) => {
- return new Promise((resolve, reject) => {
- const nativeYmlFilenames = [
- 'docker-compose.yml',
- 'docker-compose.yaml',
- 'compose.yml',
- 'compose.yaml',
- ];
- let cmd = `cd ${fileLocation} && docker-compose down`;
- // if ymlFilename is not a native yml/yaml file name, add -f flag and non-native filename
- if (!nativeYmlFilenames.includes(ymlFileName)) {
- cmd = `cd ${fileLocation} && docker-compose -f ${ymlFileName} down`;
- }
-
- window.nodeMethod.runExec(cmd, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.warn(error.message);
- return;
- }
-
- if (stderr) {
- console.log(stderr);
- resolve(stderr);
- }
-
- if (stdout) {
- console.log(stdout);
- }
- });
- });
+export const dockerComposeDown = (getContainerStacks, filePath, ymlFileName) => {
+ fetch('http://localhost:3000/command/composeDown', {
+ method: 'post', headers: {
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify({ filePath: filePath, ymlFileName: ymlFileName })
+ })
+ .then((data) => data.json())
+ .then((dockerOutput) => {
+ getContainerStacks(dockerOutput);
+ })
+ .catch((err) => console.log(err));
};
/**
@@ -520,19 +294,24 @@ export const dockerComposeDown = (fileLocation, ymlFileName) => {
*/
export const writeToDb = () => {
- const interval = 300000;
+ const interval = 150000;
setInterval(() => {
const state = store.getState();
+
const runningContainers = state.containersList.runningList;
+
const stoppedContainers = state.containersList.stoppedList;
if (!runningContainers.length) return;
const containerParameters = {};
+ // used_memory = memory_stats.usage - memory_stats.stats.cache
+
runningContainers.forEach((container) => {
containerParameters[container.Name] = {
ID: container.ID,
names: container.Name,
+ Image: container.Image,
cpu: container.CPUPerc,
mem: container.MemPerc,
memuse: container.MemUsage,
@@ -549,9 +328,9 @@ export const writeToDb = () => {
names: container.Names,
cpu: '0.00%',
mem: '0.00%',
- memuse: '00.0MiB/0.00GiB',
+ memuse: '0.00MiB/0.00MiB',
net: '0.00kB/0.00kB',
- block: '00.0MB/00.0MB',
+ block: '0.00kB/0.00kB',
pid: '0',
timestamp: 'current_timestamp',
};
@@ -614,25 +393,14 @@ export const getContainerGitUrl = async (container) => {
export const getAllDockerVolumes = (getVolumeList) => {
- window.nodeMethod.runExec(
- 'docker volume ls --format "{{json .}},"',
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.log(`getAllDockerVolumes error: ${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`getAllDockerVolumes stderr: ${stderr}`);
- return;
- }
-
- const dockerOutput = JSON.parse(
- `[${stdout.trim().slice(0, -1).replaceAll(' ', '')}]`
- );
-
- return getVolumeList(filterOneProperty(dockerOutput, 'Name'));
- }
- );
+ fetch('http://localhost:3000/command/allDockerVolumes')
+ .then((volumes) => volumes.json())
+ .then((dockerVolumes) => {
+ return getVolumeList(filterOneProperty(dockerVolumes, 'Name'));
+ })
+ .catch((err) => {
+ console.log(err);
+ });
};
/**
@@ -643,24 +411,15 @@ export const getAllDockerVolumes = (getVolumeList) => {
*/
export const getVolumeContainers = (volumeName, getVolumeContainersList) => {
- window.nodeMethod.runExec(
- `docker ps -a --filter volume=${volumeName} --format "{{json .}},"`,
- (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- console.log(`getVolumeContainers error: ${error.message}`);
- return;
- }
- if (stderr) {
- console.log(`getVolumeContainers stderr: ${stderr}`);
- return;
- }
- const dockerOutput = JSON.parse(`[${stdout.trim().slice(0, -1)}]`);
-
- return getVolumeContainersList(
- listOfVolumeProperties(volumeName, dockerOutput)
+ fetch(`http://localhost:3000/command/volumeContainers?volumeName=${volumeName}`)
+ .then((data) => data.json())
+ .then((volumeContainers) => {
+ return getVolumeContainersList(listOfVolumeProperties(volumeName, volumeContainers)
);
- }
- );
+ })
+ .catch((err) => {
+ console.log(err);
+ });
};
/**
@@ -672,35 +431,18 @@ export const getVolumeContainers = (volumeName, getVolumeContainersList) => {
*/
export const getLogs = async (optionsObj, getContainerLogsDispatcher) => {
- const containerLogs = { stdout: [], stderr: [] };
-
- // iterate through containerIds array in optionsObj
- for (let i = 0; i < optionsObj.containerIds.length; i++) {
- // build inputCommandString to get logs from command line
- let inputCommandString = 'docker logs --timestamps ';
- if (optionsObj.since) {
- inputCommandString += `--since ${optionsObj.since} `;
- }
- optionsObj.tail
- ? (inputCommandString += `--tail ${optionsObj.tail} `)
- : (inputCommandString += '--tail 50 ');
- inputCommandString += `${optionsObj.containerIds[i]}`;
-
- window.nodeMethod.runExec(inputCommandString, (error: child_process.ExecException | null, stdout: string, stderr: string) => {
- if (error) {
- alert(`Please enter a valid rfc3339 date, Unix timestamp, or Go duration string.`);
- console.error(`exec error: ${error}`);
- return;
- }
- containerLogs.stdout = [
- ...containerLogs.stdout,
- ...makeArrayOfObjects(stdout, optionsObj.containerIds[i]),
- ];
- containerLogs.stderr = [
- ...containerLogs.stderr,
- ...makeArrayOfObjects(stderr, optionsObj.containerIds[i]),
- ];
- });
+ try {
+ const response = await fetch('http://localhost:3000/command/allLogs',
+ { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(optionsObj) });
+ return await response.json();
+ }
+ catch {
+ console.log(err);
}
- return containerLogs;
+ // fetch(`http://localhost:3000/command/allLogs?optionsObj=${optionsObj}`)
+ // .then((data) => data.json())
+ // .then((allLogs) => {return allLogs})
+ // .catch((err) => {
+ // console.log(err);
+ // });
};
diff --git a/src/components/helper/newUserHelper.ts b/src/components/helper/newUserHelper.ts
index 51b7d550..1523793f 100644
--- a/src/components/helper/newUserHelper.ts
+++ b/src/components/helper/newUserHelper.ts
@@ -102,8 +102,8 @@ export const createNewUser = (email: string, username: string, password: string,
window.alert(`New user has been successfully created. \n\n
An email with the user's credentials and login instructions has been sent to ${email}`);
-
- }). then (() =>{
+
+ }).then(() => {
getUpdatedUserList();
})
.catch((err) => {
@@ -133,6 +133,13 @@ export const getUpdatedUserList = () => {
});
};
-export const updateUserList = (data: object[]) => {
+export const updateUserList = (data: object[]) => {
store.dispatch(actions.updateUserList(data));
};
+
+export const checkDbInit = () => {
+ fetch('http://localhost:3000/db')
+ .then((response) => response.json())
+ .then((data) => console.log(data))
+ .catch((err) => { console.log(err); });
+};
\ No newline at end of file
diff --git a/src/components/helper/parseContainerFormat.ts b/src/components/helper/parseContainerFormat.ts
index 854d6064..6a771f68 100644
--- a/src/components/helper/parseContainerFormat.ts
+++ b/src/components/helper/parseContainerFormat.ts
@@ -80,7 +80,6 @@ const convertToMetricsArr = (array: any[]) => {
netArray = [netArray[0].toFixed(2), netArray[1].toFixed(2)];
newArr.push(netArray);
newArr.push(blockArray);
-
return newArr;
};
diff --git a/src/components/helper/processLogHelper.js b/src/components/helper/processLogHelper.js
index 77363f1a..f8eb64f8 100644
--- a/src/components/helper/processLogHelper.js
+++ b/src/components/helper/processLogHelper.js
@@ -5,6 +5,7 @@
* @param {string} containerId
* @returns {object} optionsObj
*/
+
export const buildOptionsObj = (containerIDs) => {
const optionsObj = {
containerIds: containerIDs
diff --git a/src/components/login/login.tsx b/src/components/login/login.tsx
deleted file mode 100644
index 54a4b4d9..00000000
--- a/src/components/login/login.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * @module Login
- * @description Login component which renders a login page, and sign-up modal. This is the first component that is appended to the dist/.renderer-index-template.html via renderer/index.js
- */
-import React from 'react';
-import { useNavigate } from 'react-router-dom';
-
-import { useDispatch } from 'react-redux';
-import * as actions from '../../redux/actions/actions';
-
-//MUI Elements
-import TextField from '@mui/material/TextField';
-import Button from '@mui/material/Button';
-import {UserInfo} from '../../../types';
-
-// @ts-ignore
-import Docketeer from '../../../assets/docketeer-title.png';
-
-const Login = () => {
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const updateSession = () => dispatch(actions.updateSession());
- const updateUser = (userInfo: UserInfo) =>
- dispatch(actions.updateUser(userInfo));
-
- // callback function which will send request to endpoint http://localhost:3000/login
- const authenticateUser = (username: string, password: string) => {
- fetch("http://localhost:3000/login", {
- method: "POST",
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- username: username,
- password: password,
- }),
- })
- .then((response) => response.json())
- .then((data) => {
- if (Object.prototype.hasOwnProperty.call(data, 'error')) {
- window.alert(data.error);
- } else {
- updateSession(); // loggedIn = true
- updateUser(data); // update user info in sessions reducer
- navigate('/');
- }
- })
- .catch((err) => {
- console.log('Fetch: POST error to /login', err);
- // created a pop window for wrong username/password
- window.alert('Wrong Password or Username. Please try Again!');
- });
- };
-
- // callback function invoked when 'login' button is clicked
- const handleLogin = (e: React.ChangeEvent | React.ChangeEvent) => {
- e.preventDefault(); // prevents form submit from reloading page
- const usernameInput = document.getElementById("username");
- const passwordInput = document.getElementById("password");
- if(usernameInput != null || passwordInput != null) {
- const username: string = (usernameInput as HTMLInputElement).value;
- const password: string = (passwordInput as HTMLInputElement).value;
-
- // clears input fields after login
- (usernameInput as HTMLInputElement).value = "";
- (passwordInput as HTMLInputElement).value = "";
-
- console.log("username:", username);
- console.log("password:", password);
- authenticateUser(username, password);
-
- };
-
- return (
-
-
-
-
-
-
-
-
-
- );
-};
-}
-export default Login;
diff --git a/src/components/tabs/Containers.tsx b/src/components/tabs/Containers.tsx
index b23ca41a..8469df4a 100644
--- a/src/components/tabs/Containers.tsx
+++ b/src/components/tabs/Containers.tsx
@@ -2,7 +2,7 @@
import React from 'react';
import { Chart } from 'react-chartjs-2';
import ToggleDisplay from '../display/ToggleDisplay';
-import { ContainerProps, ContainerType, ChartInfoType } from '../../../types';
+import { ContainerProps, ContainerType, ChartInfoType } from '../../../types';
/**
* Display all running and stopped containers
*
@@ -15,19 +15,20 @@ const Containers = (props: ContainerProps) => {
{container.Names}
-
ID: {container.ID}
+ {/*
Image: {container.Image}
+
ID: {container.ID}
*/}
-
- Img: {container.Image}
+ Image: {container.Image}
-
- Created: {container.RunningFor}
+ ID: {container.ID}
-
- Name: {container.Names}
+ Created: {container.RunningFor}
@@ -42,7 +43,7 @@ const Containers = (props: ContainerProps) => {
RUN
props.remove(container['ID'], props.removeContainer)}
>
REMOVE
@@ -75,7 +76,8 @@ const Containers = (props: ContainerProps) => {
{
stack,
label: Math.random().toString(),
- data: [(100 - Number(cpuData)).toFixed(2), (100 - Number(memoryData)).toFixed(2)],
+ // data: [(100 - Number(cpuData)).toFixed(2), (100 - Number(memoryData)).toFixed(2)],
+ data: ['100', '100'],
backgroundColor: ['rgba(155, 198, 233, 1)', 'rgba(217, 252, 219, 1)'],
borderColor: 'rgba(0,0,0,0)',
borderWidth: 1,
@@ -87,7 +89,8 @@ const Containers = (props: ContainerProps) => {
return (
-
Name: {container.Name}
+
{container.Name}
+
Image: {container.Image}
ID: {container.ID}
@@ -115,7 +118,8 @@ const Containers = (props: ContainerProps) => {
plugins: { legend: { display: false } },
scales: {
y: {
- stacked: true
+ // stacked: true
+ stacked: false
},
}
}}
@@ -124,14 +128,15 @@ const Containers = (props: ContainerProps) => {
-
-
props.stop(container.ID, props.stopRunningContainer)}
+ {/* */}
+
+ props.stop(container.ID, props.refreshStoppedContainers)}
>
STOP
+ {/*
*/}
);
});
diff --git a/src/components/tabs/Images.tsx b/src/components/tabs/Images.tsx
index 8309fc43..b25c2a19 100644
--- a/src/components/tabs/Images.tsx
+++ b/src/components/tabs/Images.tsx
@@ -1,7 +1,7 @@
/* eslint-disable react/prop-types */
import React, { useState } from 'react';
import * as helper from '../helper/commands';
-import { ContainerObj, imageObj, ImagesProps } from '../../../types';
+import { ContainerObj, imageObj, ImagesProps } from '../../../types';
/**
* Render Images of the user has
@@ -18,11 +18,11 @@ const Images = (props: ImagesProps) => {
}
else {
let existingRepo = false;
- if(repo.includes(':')){
+ if (repo.includes(':')) {
const splitRepo = repo.split(':');
// can't break out of a forEach, so opted to use map as temp solution
- props.imagesList.map((el)=>{
- if(el.reps === splitRepo[0] && el.tag === splitRepo[1]){
+ props.imagesList.map((el) => {
+ if (el.reps === splitRepo[0] && el.tag === splitRepo[1]) {
existingRepo = true;
return;
}
@@ -38,21 +38,21 @@ const Images = (props: ImagesProps) => {
helper.pullImage(repo);
return;
}
- }
-
+ }
+
else {
- props.imagesList.map((el)=>{
- if (el.reps === repo && el.tag === 'latest'){
+ props.imagesList.map((el) => {
+ if (el.reps === repo && el.tag === 'latest') {
existingRepo = true;
return;
}
});
// ignore was used below because Typescript says the codition will never be true, but this is not an accurate error
// @ts-ignore
- if (existingRepo === true){
+ if (existingRepo === true) {
alert('This image already exists!');
return;
- }
+ }
else {
alert('Looking for image');
helper.pullImage(repo);
@@ -86,16 +86,14 @@ const Images = (props: ImagesProps) => {
onClick={() =>
props.runIm(
ele,
- props.runningList,
- helper.addRunning,
- props.addRunningContainers
+ props.refreshRunningContainers
)
}
>
RUN
props.removeIm(
ele['imgid'],
@@ -116,22 +114,22 @@ const Images = (props: ImagesProps) => {
diff --git a/src/components/tabs/ImagesUser.js b/src/components/tabs/ImagesUser.tsx
similarity index 88%
rename from src/components/tabs/ImagesUser.js
rename to src/components/tabs/ImagesUser.tsx
index 4362b6ae..0d2b86bf 100644
--- a/src/components/tabs/ImagesUser.js
+++ b/src/components/tabs/ImagesUser.tsx
@@ -1,16 +1,17 @@
/* eslint-disable react/prop-types */
-import React, { useState } from 'react';
+import React, { useState, MouseEvent } from 'react';
import * as helper from '../helper/commands';
+import { ImagesProps } from '../../../types';
/**
* Render Images of the user has
*
* @param {*} props
*/
-const Images = (props) => {
+const Images = (props: ImagesProps) => {
const [repo, setRepo] = useState('');
- const handleClick = (e) => {
+ const handleClick = (e: MouseEvent) => {
e.preventDefault();
helper.pullImage(repo);
};
diff --git a/src/components/tabs/Metrics.js b/src/components/tabs/Metrics.js
deleted file mode 100644
index c7168e9d..00000000
--- a/src/components/tabs/Metrics.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* eslint-disable no-tabs */
-/* eslint-disable react/prop-types */
-import React from 'react';
-import { convertToMetricsArr } from '../helper/parseContainerFormat';
-import { Chart } from 'react-chartjs-2';
-import LineChartDisplay from '../display/LineChartDisplay';
-
-/**
- * Display general metrics
- *
- * @param {*} props
- */
-const Metrics = (props) => {
- const result = convertToMetricsArr(props.runningList);
- const cpuData = (100 - result[0]).toFixed(2);
- const memoryData = (100 - result[1]).toFixed(2);
-
- const cpu = {
- labels: [`Available: ${cpuData}%`, `Usage: ${result[0].toFixed(2)}%`],
- datasets: [
- {
- label: 'CPU',
- backgroundColor: ['rgba(44, 130, 201, 1)', 'rgba(19, 221, 29, 1)'],
- data: [cpuData, result[0]],
- },
- ],
- };
-
- const memory = {
- labels: [`Available: ${memoryData}%`, `Usage: ${result[1].toFixed(2)}%`],
- datasets: [
- {
- label: 'Memory',
- backgroundColor: ['rgba(44, 130, 201, 1)', 'rgba(19, 221, 29, 1)'],
- data: [memoryData, result[1]],
- },
- ],
- };
-
- const options = {
- responsive: true,
- maintainAspectRatio: true,
- plugins: {
- title: { display: true, text: 'MEMORY', font: {size: 20}},
- tooltips: { enabled: true, mode: 'index' },
- legend: {display: false},
- datalabels: {
- formatter: (value, ctx) => {
- let sum = 0;
- const dataArr = ctx.chart.data.datasets[0].data;
- dataArr.map((data) => {
- sum += data;
- });
- const percentage = ((value * 100) / sum).toFixed(2) + '%';
- return percentage;
- },
- color: '#fff',
- },
- },
- };
-
- const options2 = {
- responsive: true,
- maintainAspectRatio: true,
- plugins: {
- title: { display: true, text: 'CPU', font: {size: 20}},
- tooltips: { enabled: false },
- legend: {display: false},
- datalabels: {
- formatter: (value, ctx) => {
- let sum = 0;
- const dataArr = ctx.chart.data.datasets[0].data;
- dataArr.map((data) => {
- sum += data;
- });
- const percentage = ((value * 100) / sum).toFixed(2) + '%';
- return percentage;
- },
- color: '#fff',
- },
- },
- };
-
- return (
-
-
-
Metrics
-
- Click here for more information on these metrics
-
-
-
-
Aggregate
-
-
-
-
-
-
-
-
Available {Math.round(cpuData)}%
-
-
-
-
Usage {Math.round(result[0].toFixed(2))}%
-
-
-
-
-
-
-
-
-
-
Available {Math.round(memoryData)}%
-
-
-
-
Usage {Math.round(result[1].toFixed(2))}%
-
-
-
-
-
-
-
NET IO:
-
- {Math.floor(result[2][0])}kB / {Math.floor(result[2][1])}kB
-
-
-
-
BLOCK IO:
-
- {Math.floor(result[3][0])}B / {Math.floor(result[3][1])}B
-
-
-
-
-
-
- );
-};
-
-export default Metrics;
\ No newline at end of file
diff --git a/src/components/tabs/Metrics.tsx b/src/components/tabs/Metrics.tsx
new file mode 100644
index 00000000..6b8670f3
--- /dev/null
+++ b/src/components/tabs/Metrics.tsx
@@ -0,0 +1,185 @@
+/* eslint-disable no-tabs */
+/* eslint-disable react/prop-types */
+import React from 'react';
+import { Chart } from 'react-chartjs-2';
+import LineChartDisplay from '../display/LineChartDisplay';
+import { useSelector } from 'react-redux';
+import { MetricsProps } from '../../../types';
+
+/**
+ * Display general metrics
+ *
+ * @param {*} props
+ */
+const Metrics = (props: MetricsProps) => {
+ const fullRunningList = props.runningList;
+ const hostStats = useSelector((state: any) => state.containersList.hostStats);
+ const cpuData = 100 - hostStats.cpuPerc;
+ const memoryData = 100 - hostStats.memPerc;
+ const cpuThreshold = props.threshold[0];
+ const memThreshold = props.threshold[1];
+
+ let cpuFails = 0
+ let memFails = 0
+
+ // used to monitor threshold and fail counts
+ for (const each of fullRunningList) {
+ const cpu = parseFloat(each['CPUPerc'].replace(/([%])+/g, ''))
+ const memory = parseFloat(each['MemPerc'].replace(/([%])+/g, ''))
+ if (cpu >= cpuThreshold) cpuFails++
+ if (memory >= memThreshold) memFails++
+ }
+
+ const cpu = {
+ labels: [`Available: ${cpuData}%`, `Usage: ${hostStats.cpuPerc}%`],
+ datasets: [
+ {
+ label: 'CPU',
+ backgroundColor: ['#4594ce', '#67f267'],
+ data: [cpuData, hostStats.cpuPerc],
+ },
+ ],
+ }
+
+ const memory = {
+ labels: [`Available: ${memoryData}%`, `Usage: ${hostStats.memPerc}%`],
+ datasets: [
+ {
+ label: 'Memory',
+ backgroundColor: ['#4594ce', '#67f267'],
+ data: [memoryData, hostStats.memPerc],
+ },
+ ],
+ }
+
+ const memOptions = {
+ responsive: true,
+ maintainAspectRatio: true,
+ plugins: {
+ title: { display: true, text: 'MEMORY', font: { size: 20 } },
+ tooltips: { enabled: true, mode: 'index' },
+ legend: { display: false },
+ datalabels: {
+ formatter: (value: number, ctx: any) => {
+ let sum = 0;
+ const dataArr = ctx.chart.data.datasets[0].data;
+ dataArr.map((data: any) => {
+ sum += data;
+ });
+ const percentage = (value * 100) / sum + '%';
+ return percentage;
+ },
+ color: '#fff',
+ },
+ },
+ }
+
+ const cpuOptions = {
+ responsive: true,
+ maintainAspectRatio: true,
+ plugins: {
+ title: { display: true, text: 'CPU', font: { size: 20 } },
+ tooltips: { enabled: false },
+ legend: { display: false },
+ datalabels: {
+ formatter: (value: number, ctx: any) => {
+ let sum = 0;
+ const dataArr = ctx.chart.data.datasets[0].data;
+ dataArr.map((data: any) => {
+ sum += data;
+ });
+ const percentage = (value * 100) / sum + '%';
+ return percentage;
+ },
+ color: '#fff',
+ },
+ },
+ }
+
+ return (
+
+
+
Metrics
+
+
+
Host Metrics
+
+
+
+
+
+
+
+
Available {Math.round(cpuData)}%
+
+
+
+
Usage {Math.round(hostStats.cpuPerc)}%
+
+
+
+
+
+
+
+
+
+
+ {' '}
+ Available {Math.round(memoryData)}%
+
+
+
+
+
Usage {Math.round(hostStats.memPerc)}%
+
+
+
+
+
+
+
# of Running Containers:
+
{fullRunningList.length}
+
+
+
CPU Fail Counts:
+
Threshold: {cpuThreshold}%
+
{cpuFails}
+
+
+
Memory Fail Counts:
+
Threshold: {memThreshold}%
+
{memFails}
+
+
+
+
+ {/*
+
+ Click here
+ {' '}
+ for more information on these metrics
+
*/}
+
+ )
+}
+
+export default Metrics
diff --git a/src/components/tabs/ProcessLogs.js b/src/components/tabs/ProcessLogs.js
deleted file mode 100644
index 1318e752..00000000
--- a/src/components/tabs/ProcessLogs.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* eslint-disable react/prop-types */
-import React from 'react';
-import ProcessLogsCard from '../display/ProcessLogsCard';
-
-/**
- * Display all running and stopped containers. Each box can be selected to view process log tables.
- *
- * @param {*} props
- */
-
-const ProcessLogs = (props) => {
- const renderRunningList = [];
- props.runningList.map((container, index) => {
- renderRunningList.push(
-
- );
- });
-
- const renderStoppedList = [];
- props.stoppedList.map((container, index) => {
- renderStoppedList.push(
-
- );
- });
-
- return (
-
-
-
Process Logs
-
-
-
Running Containers: {props.runningList.length}
-
-
{renderRunningList}
-
-
Stopped Containers: {props.stoppedList.length}
-
-
{renderStoppedList}
-
- );
-};
-
-export default ProcessLogs;
diff --git a/src/components/tabs/ProcessLogs.tsx b/src/components/tabs/ProcessLogs.tsx
new file mode 100644
index 00000000..c578e05f
--- /dev/null
+++ b/src/components/tabs/ProcessLogs.tsx
@@ -0,0 +1,61 @@
+/* eslint-disable react/prop-types */
+import { AnyAsyncThunk } from '@reduxjs/toolkit/dist/matchers';
+import React from 'react';
+import ProcessLogsCard from '../display/ProcessLogsCard';
+import { ContainerType } from '../../../types';
+
+/**
+ * Display all running and stopped containers. Each box can be selected to view process log tables.
+ *
+ * @param {*} props
+ */
+
+const ProcessLogs = (props: any) => {
+ const renderRunningList: any[] = [];
+ props.runningList.map((container: ContainerType, index: number) => {
+ renderRunningList.push(
+ ,
+ )
+ })
+
+ const renderStoppedList: any[] = [];
+ props.stoppedList.map((container: ContainerType, index: number) => {
+ renderStoppedList.push(
+ ,
+ )
+ })
+
+ return (
+
+
+
Process Logs
+
+
+
+ Running Containers: {props.runningList.length}
+
+
+
{renderRunningList}
+
+
+
+
+ Stopped Containers: {props.stoppedList.length}
+
+
+
{renderStoppedList}
+
+ )
+}
+
+export default ProcessLogs
diff --git a/src/components/tabs/Stopped.js b/src/components/tabs/Stopped.js
deleted file mode 100644
index 04ce03b0..00000000
--- a/src/components/tabs/Stopped.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* eslint-disable react/prop-types */
-import React from "react";
-
-/**
- * Display all stopped containers with functionality
- *
- * @param {*} props
- */
-const Stopped = (props) => {
- const renderStoppedList = props.stoppedList.map((container, i) => {
- return (
-
-
-
{container.Names}
-
{container.ID}
-
-
-
-
Img: {container.Image}
- Created: {container.RunningFor}
- name: {container.Names}
-
-
-
- props.runStopped(container["ID"], props.runStoppedContainer)
- }
- >
- RUN
-
- props.remove(container["ID"], props.removeContainer)}
- >
- REMOVE
-
-
-
- );
- });
-
- return (
-
-
-
Exited Containers
-
-
{renderStoppedList}
-
- );
-};
-
-export default Stopped;
diff --git a/src/components/tabs/Users.js b/src/components/tabs/Users.js
index ca4060d1..f66efcb6 100644
--- a/src/components/tabs/Users.js
+++ b/src/components/tabs/Users.js
@@ -1,15 +1,15 @@
-import React, { useState, useMemo } from 'react';
-import { useSelector, useDispatch } from 'react-redux';
-import { Box, Typography } from '@mui/material';
-import { DataGrid } from '@mui/x-data-grid';
-import NewUserDisplay from '../display/NewUserDisplay';
-import * as actions from '../../redux/actions/actions';
+import React, { useState, useMemo } from 'react'
+import { useSelector, useDispatch } from 'react-redux'
+import { Box, Typography } from '@mui/material'
+import { DataGrid } from '@mui/x-data-grid'
+import NewUserDisplay from '../display/NewUserDisplay'
+import * as actions from '../../redux/actions/actions'
const UserTable = () => {
- const userList = useSelector((state) => state.userList.userList);
- const dispatch = useDispatch();
- const updateUserRole = (data) => dispatch(actions.updateUserRole(data));
- const [pageSize, setPageSize] = useState(5);
+ const userList = useSelector((state) => state.userList.userList)
+ const dispatch = useDispatch()
+ const updateUserRole = (data) => dispatch(actions.updateUserRole(data))
+ const [pageSize, setPageSize] = useState(5)
// Create columns for table
const columns = useMemo(() => [
@@ -24,7 +24,7 @@ const UserTable = () => {
type: 'singleSelect',
valueOptions: ['user', 'admin', 'system admin'],
editable: true,
- preProcessEditCellProps: (params) => handleRoleChange(params)
+ preProcessEditCellProps: (params) => handleRoleChange(params),
},
{ field: 'email', headerName: 'Email', width: '200' },
@@ -35,75 +35,83 @@ const UserTable = () => {
{ field: 'mem_threshold', headerName: 'Memory', width: '100' },
- { field: 'cpu_threshold', headerName: 'CPU', width: '100' }
- ]);
+ { field: 'cpu_threshold', headerName: 'CPU', width: '100' },
+ ])
const handleRoleChange = (event) => {
- const id = event.id;
- const role = event.props.value;
+ const id = event.id
+ const role = event.props.value
return new Promise((resolve) => {
// preProcessEditCellProps requires you to use a Promise/Resolve
fetch('http://localhost:3000/admin/switch', {
method: 'POST',
headers: {
- 'Content-Type': 'application/json'
+ 'Content-Type': 'application/json',
},
body: JSON.stringify({
_id: id,
- role: role
- })
+ role: role,
+ }),
})
.then((response) => response.json())
.then((data) => {
// Sets hasError to true/false based on API call. This will be true if the user tries to remove the last sysadmin
- const hasError = data;
+ const hasError = data
if (data) {
- console.log('no change');
+ console.log('no change')
window.alert(
- 'Uh-oh! You\'re the LAST sysadmin! Before reassigning yourself you need to assign a new sysadmin.'
- );
+ "Uh-oh! You're the LAST sysadmin! Before reassigning yourself you need to assign a new sysadmin.",
+ )
} else {
const payload = {
_id: id,
- role
- };
- updateUserRole(payload); // Updates local state
+ role,
+ }
+ updateUserRole(payload) // Updates local state
}
- event.props.value = role; // Set's the cell's props to the role that was passed in
+ event.props.value = role // Set's the cell's props to the role that was passed in
resolve({
...event.props, // Send the resolve with the selected props.
- error: hasError // If this is false, the value of the cell will not be updated. If it is true, it will be udpated
- });
+ error: hasError, // If this is false, the value of the cell will not be updated. If it is true, it will be udpated
+ })
})
.catch((err) => {
- console.log('Error in front end switching roles: ', err);
- });
- });
- };
+ console.log('Error in front end switching roles: ', err)
+ })
+ })
+ }
return (
-
+
+
+
Users
+
-
+
Manage Users
* Double click on the role to access the drop down menu
{
getRowSpacing={(params) => ({
// Sets spacing between rows
top: params.isFirstVisible ? 0 : 5, // Sets spacing for top row to zero and 5 for everything else
- bottom: params.isLastVisible ? 0 : 5
+ bottom: params.isLastVisible ? 0 : 5,
})}
/>
- );
-};
+ )
+}
-export default UserTable;
+export default UserTable
diff --git a/src/components/tabs/VolumeHistory.js b/src/components/tabs/VolumeHistory.js
index 4c8f1fde..082c5a92 100644
--- a/src/components/tabs/VolumeHistory.js
+++ b/src/components/tabs/VolumeHistory.js
@@ -17,18 +17,14 @@ const volumeHistory = (props) => {
className="volume-container-details"
key={`vol-${i}`}
>
-
Container Name:
+
Container:
{container['Names']}
-
- -
- Status:
- {container['State']}
-
- -
- Running For:
- {container['Status']}
-
-
+
+
Status:
+ {container['State']}
+
+
Runtime:
+ {container['Status']}
);
};
@@ -40,14 +36,14 @@ const volumeHistory = (props) => {
ele.containers.length
? ele.containers.forEach(el => details.push(containerDetails(el, i)))
: details.push(
-
+
No container found in this volume
);
return (
-
+
{ele.vol_name}
{details}
@@ -71,23 +67,23 @@ const volumeHistory = (props) => {
-
{renderList}
+
{renderList}
);
};
diff --git a/src/components/tabs/Yml.js b/src/components/tabs/Yml.js
index 126f6670..35727215 100644
--- a/src/components/tabs/Yml.js
+++ b/src/components/tabs/Yml.js
@@ -29,7 +29,7 @@ const Yml = () => {
dispatch(actions.getContainerStacks(data));
const composeDown = (data) => dispatch(actions.composeDown(data));
-
+
useEffect(() => {
// upon page render, get list of currently running container networks
helper.dockerComposeStacks(getContainerStacks);
@@ -67,14 +67,14 @@ const Yml = () => {
// get yml file name from the filepath for composing up a new container network
const ymlRegex = /\/docker-compose.*.yml/;
const ymlFileName = filePath.match(ymlRegex)[0].replace('/', '');
-
+
const directoryPath = filePath.replace(ymlRegex, '');
setFilePath(directoryPath);
setYmlFileName(ymlFileName);
}
};
}, []);
-
+
// creates table of running container networks
const TableData = () => {
return composeStack.map((container, index) => {
@@ -102,17 +102,10 @@ const Yml = () => {
{
- helper
- .dockerComposeDown(container.FilePath, container.YmlFileName)
- .then((res) => {
- if (res) {
- helper.dockerComposeStacks(getContainerStacks, container.FilePath, container.YmlFileName);
- setYmlFile('');
- setFilePath('');
- setYmlFileName('');
- }
- })
- .catch((err) => console.log(err));
+ helper.dockerComposeDown(getContainerStacks, container.FilePath, container.YmlFileName);
+ setYmlFile('');
+ setFilePath('');
+ setYmlFileName('');
}}
>
Docker Compose Down
@@ -131,7 +124,25 @@ const Yml = () => {
- Upload your Docker Compose file here to compose
+
+ Upload your Docker Compose file here to compose
+
+
+
+ UPLOAD FILE
+
+ {
+ helper.dockerComposeUp(getContainerStacks, filePath, ymlFileName);
+ setYmlFile('');
+ setFilePath('');
+ setYmlFileName('');
+ }}
+ >
+ DOCKER COMPOSE UP
+
+
+
{ymlFile && (
{ymlFile}
@@ -139,43 +150,6 @@ const Yml = () => {
)}
-
-
-
- Upload File
-
- {
- helper
- .dockerComposeUp(filePath, ymlFileName)
- .then((res) => {
- if (res) {
- helper.dockerComposeStacks(getContainerStacks, filePath, ymlFileName);
- setYmlFile('');
- setFilePath('');
- setYmlFileName('');
- }
- })
- .catch((err) => console.log(err));
- }}
- >
- Docker Compose Up
-
-
diff --git a/src/components/views/Admin.tsx b/src/components/views/Admin.tsx
index ad876915..6d785783 100644
--- a/src/components/views/Admin.tsx
+++ b/src/components/views/Admin.tsx
@@ -57,6 +57,7 @@ const AdminView = () => {
const runningList = useSelector((state: StateType) => state.containersList.runningList);
const stoppedList = useSelector((state: StateType) => state.containersList.stoppedList);
const imagesList = useSelector((state: StateType) => state.images.imagesList);
+ const { mem_threshold, cpu_threshold } = useSelector((state: StateType) => state.session);
// const networkList = useSelector((state: StateType) => state.networkList.networkList);
const arrayOfVolumeNames = useSelector(
@@ -249,7 +250,7 @@ const AdminView = () => {
+
}
/>
{
{
{
{
{
let navigate = useNavigate();
const dispatch = useDispatch();
- const addRunningContainers = (data: ContainerObj[]) =>
- dispatch(actions.addRunningContainers(data));
+ const refreshHostData = (data: ContainerObj[]) =>
+ dispatch(actions.refreshHostData(data));
+ const addRunningContainers = (data: ContainerObj[]) =>
+ dispatch(actions.addRunningContainers(data));
const refreshRunningContainers = (data: ContainerObj[]) =>
dispatch(actions.refreshRunningContainers(data));
const refreshStoppedContainers = (data: StoppedContainerObj[]) =>
dispatch(actions.refreshStoppedContainers(data));
- const refreshImagesList = (data: ImageObj[]) =>
+ const refreshImagesList = (data: ImageObj[]) =>
dispatch(actions.refreshImages(data));
// const composeymlFiles = (data) => dispatch(actions.composeymlFiles(data));
const getNetworkContainers = (data: NetworkObj[]) =>
dispatch(actions.getNetworkContainers(data));
- const removeContainer = (id: string) =>
+ const removeContainer = (id: string) =>
dispatch(actions.removeContainer(id));
const runStoppedContainer = (id: string) =>
dispatch(actions.runStoppedContainer(id));
const stopRunningContainer = (id: string) =>
dispatch(actions.stopRunningContainer(id));
- const updateSession = () =>
+ const updateSession = () =>
dispatch(actions.updateSession());
- const logoutUser = () =>
+ const logoutUser = () =>
dispatch(actions.logoutUser());
- const updateUserList = (data: UserObj[]) =>
+ const updateUserList = (data: UserObj[]) =>
dispatch(actions.updateUserList(data)); //* Feature only for SysAdmin
const getVolumeList = (data: { Name: string }[]) =>
dispatch(actions.getVolumeList(data));
@@ -64,6 +66,7 @@ const SysAdmin = () => {
const runningList = useSelector((state: StateType) => state.containersList.runningList);
const stoppedList = useSelector((state: StateType) => state.containersList.stoppedList);
const imagesList = useSelector((state: StateType) => state.images.imagesList);
+ const { mem_threshold, cpu_threshold } = useSelector((state: StateType) => state.session);
// const networkList = useSelector((state: StateType) => state.networkList.networkList);
const userInfo = useSelector((state: StateType) => state.session); //* Feature only for SysAdmin
const arrayOfVolumeNames = useSelector(
@@ -109,11 +112,14 @@ const SysAdmin = () => {
.catch((err) => {
console.log(err);
});
- navigate('/login');
+ navigate('/login');
};
+
+ // Initial refresh
useEffect(() => {
initDatabase();
+ helper.getHostStats(refreshHostData);
helper.refreshRunning(refreshRunningContainers);
helper.refreshStopped(refreshStoppedContainers);
helper.refreshImages(refreshImagesList);
@@ -134,6 +140,7 @@ const SysAdmin = () => {
// every 5 seconds invoke helper functions to refresh running, stopped and images, as well as notifications
useEffect(() => {
const interval = setInterval(() => {
+ helper.getHostStats(refreshHostData);
helper.refreshRunning(refreshRunningContainers);
helper.refreshStopped(refreshStoppedContainers);
helper.refreshImages(refreshImagesList);
@@ -179,7 +186,7 @@ const SysAdmin = () => {
{/* Navbar */}