Просмотр исходного кода

provisioning integrated, unstyled

sunguroku 5 лет назад
Родитель
Сommit
5555125f24

+ 28 - 6
dashboard/src/main/home/provisioner/InfraStatuses.tsx

@@ -8,6 +8,7 @@ import { infraNames } from 'shared/common';
 type PropsType = {
   infras: InfraType[],
   selectInfra: (infra: InfraType) => void,
+  selectedInfra: InfraType,
 };
 
 type StateType = {
@@ -20,9 +21,9 @@ export default class InfraStatuses extends Component<PropsType, StateType> {
   renderStatusIcon = (status: string) => {
     if (status === 'created') {
       return <StatusIcon>✓</StatusIcon>;
-    } else if (status === 'creating') {
+    } else if (status === 'creating' || status === 'destroying') {
       return <StatusIcon><img src={loadingDots} /></StatusIcon>
-    } else if (status === 'error') {
+    } else if (status === 'error' || status === 'destroyed') {
       return <StatusIcon color='#e3366d'>✗</StatusIcon>
     }
   }
@@ -34,10 +35,11 @@ export default class InfraStatuses extends Component<PropsType, StateType> {
           return (
             <InfraRow 
               key={infra.id}
+              selected={(infra.id === this.props.selectedInfra?.id)}
               onClick={() => this.props.selectInfra(infra)}
             >
-              {this.renderStatusIcon(infra.status)}
               {infraNames[infra.kind]}
+              {this.renderStatusIcon(infra.status)}
             </InfraRow>
           )
         })}
@@ -53,21 +55,41 @@ const StatusIcon = styled.div<{ color?: string }>`
   width: 20px;
   font-size: 16px;
   color: ${props => props.color ? props.color : '#68c49c'};
-  margin-right: 10px;
+  margin-left: 10px;
 `;
 
-const InfraRow = styled.div`
+const Tab = styled.div`
   width: 100%;
   height: 25px;
   padding-left: 2px;
   margin-top: 10px;
   font-size: 13px;
   color: #aaaabb;
+  color: white;
   display: flex;
   align-items: center;
 `;
 
+const InfraRow = styled.div`
+  width: 100%;
+  height: 50px;
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  color: ${(props: {selected: boolean}) => props.selected ? 'white' : '#ffffff66'};
+  background: ${(props: {selected: boolean}) => props.selected ? '#ffffff18' : ''};
+  font-size: 13px;
+  padding: 20px 19px 20px 42px;
+  text-shadow: 0px 0px 8px none;
+  overflow: visible;
+  cursor: pointer;
+  :hover {
+    color: white;
+    background: #ffffff18;
+  }
+`;
+
 const StyledInfraStatuses = styled.div`
-  margin-top: 20px;
   margin-bottom: 0;
 `;

+ 8 - 24
dashboard/src/main/home/provisioner/Provisioner.tsx

@@ -58,12 +58,14 @@ class Provisioner extends Component<PropsType, StateType> {
       this.setState({ 
         error: false, 
         infras: res.data, 
-        loading: false 
+        loading: false,
+        selectedInfra: res.data[0],
       });
     });
   }
 
   render() {
+    console.log(this.state.infras)
     if (this.state.loading) {
       return (
         <StyledProvisioner> 
@@ -79,10 +81,14 @@ class Provisioner extends Component<PropsType, StateType> {
             <InfraStatuses 
               infras={this.state.infras} 
               selectInfra={this.selectInfra.bind(this)}
+              selectedInfra={this.state.selectedInfra}
             />
           </TabWrapper>
 
-          <ProvisionerLogs selectedInfra={this.state.selectedInfra} />
+          <ProvisionerLogs 
+            key={this.state.selectedInfra?.id} 
+            selectedInfra={this.state.selectedInfra} 
+          />
         </StyledProvisioner>
       )
     }
@@ -99,28 +105,6 @@ Provisioner.contextType = Context;
 
 export default withRouter(Provisioner);
 
-const Wrapper = styled.div`
-  width: 100%;
-  height: 100%;
-  overflow: auto;
-  padding: 20px 25px;
-`;
-
-const Log = styled.div`
-  font-family: monospace;
-`;
-
-const LogStream = styled.div`
-  height: 300px;
-  margin-top: 20px;
-  font-size: 13px;
-  border: 2px solid #ffffff55;
-  border-radius: 10px;
-  width: 100%;
-  background: #00000022;
-  user-select: text;
-`;
-
 const StyledProvisioner = styled.div`
   width: 100%;
   height: 350px;

+ 34 - 7
dashboard/src/main/home/provisioner/ProvisionerLogs.tsx

@@ -3,13 +3,14 @@ import styled from 'styled-components';
 import { Context } from 'shared/Context';
 import { InfraType } from 'shared/types';
 import posthog from 'posthog-js';
+import { RouteComponentProps, withRouter } from "react-router";
 
 import ansiparse from 'shared/ansiparser'
 import loading from 'assets/loading.gif';
 import warning from 'assets/warning.png';
 
-type PropsType = {
-  selectedInfra: InfraType,
+type PropsType = RouteComponentProps & {
+    selectedInfra: InfraType
 };
 
 type StateType = {
@@ -20,7 +21,7 @@ type StateType = {
   currentStep: number,
 };
 
-export default class Logs extends Component<PropsType, StateType> {
+class ProvisionerLogs extends Component<PropsType, StateType> {
   
   state = {
     logs: [] as string[],
@@ -34,17 +35,33 @@ export default class Logs extends Component<PropsType, StateType> {
   parentRef = React.createRef<HTMLDivElement>()
 
   scrollToBottom = () => {
+    console.log(this.parentRef.current)
     this.parentRef.current.lastElementChild.scrollIntoView({ behavior: "auto" })
   }
 
   renderLogs = () => {
     let { selectedInfra } = this.props;
+
     if (!selectedInfra) {
-      return <Message>Please select a pod to view its logs.</Message>
+        return <Message>Please select a resource.</Message>
+    }
+
+    if (selectedInfra.status == 'destroyed') {
+        return (
+            <Message>
+                This resource has been auto-destroyed due to an error during provisioning.
+            </Message>
+        )
     }
+
+    if (selectedInfra.status == 'error' && this.state.logs.length == 0) {
+        return <Message>Porter encountered an error while provisioning this resource.</Message>
+    }
+
     if (this.state.logs.length == 0) {
-      return <Message>No logs to display from this pod.</Message>
+        return <Message>{selectedInfra.status}</Message>
     }
+
     return this.state.logs.map((log, i) => {
         return <Log key={i}>{log}</Log>
     })
@@ -60,7 +77,6 @@ export default class Logs extends Component<PropsType, StateType> {
   }
 
   setupWebsocket = () => {
-    let { selectedInfra }= this.props;
     this.ws.onopen = () => {
       console.log('connected to websocket')
     }
@@ -133,6 +149,14 @@ export default class Logs extends Component<PropsType, StateType> {
   }
 
   componentDidMount() {
+    let { currentProject } = this.context;
+    let { selectedInfra } = this.props;
+
+    if (!selectedInfra) return;
+
+    let protocol = process.env.NODE_ENV == 'production' ? 'wss' : 'ws'
+    this.ws = new WebSocket(`${protocol}://${process.env.API_SERVER}/api/projects/${currentProject.id}/provision/${selectedInfra.kind}/${selectedInfra.id}/logs`)
+
     this.setupWebsocket()
     this.scrollToBottom();
   }
@@ -154,7 +178,8 @@ export default class Logs extends Component<PropsType, StateType> {
   }
 }
 
-Logs.contextType = Context;
+ProvisionerLogs.contextType = Context;
+export default withRouter(ProvisionerLogs);
 
 const Scroll = styled.div`
   align-items: center;
@@ -226,6 +251,7 @@ const LogStream = styled.div`
 
 const Message = styled.div`
   display: flex;
+  flex-direction: column;
   height: 100%;
   width: 100%;
   align-items: center;
@@ -236,4 +262,5 @@ const Message = styled.div`
 
 const Log = styled.div`
   font-family: monospace;
+  font-size: 12px;
 `;

+ 1 - 42
dashboard/src/main/home/provisioner/ProvisionerStatus.tsx

@@ -315,7 +315,7 @@ class ProvisionerStatus extends Component<PropsType, StateType> {
             }
           />
         </LoadingBar>
-        
+
         <LogStream>
           <Wrapper ref={this.parentRef}>{this.renderLogs()}</Wrapper>
         </LogStream>
@@ -330,47 +330,6 @@ ProvisionerStatus.contextType = Context;
 
 export default withRouter(ProvisionerStatus);
 
-const Options = styled.div`
-  width: 100%;
-  height: 25px;
-  background: #397ae3;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  justify-content: space-between;
-`
-
-const Refresh = styled.div`
-  display: flex;
-  align-items: center;
-  width: 87px;
-  user-select: none;
-  cursor: pointer;
-  height: 100%;
-
-  > i {
-    margin-left: 6px;
-    font-size: 17px;
-    margin-right: 6px;
-  }
-
-  :hover {
-    background: #2468d6;
-  }
-`
-
-// const Link = styled.a`
-//   cursor: pointer;
-//   margin-left: 5px;
-//   margin-right: 5px;
-// `;
-
-const Warning = styled.span`
-  color: ${(props: { highlight: boolean, makeFlush?: boolean }) => props.highlight ? '#f5cb42' : ''};
-  margin-left: ${(props: { highlight: boolean, makeFlush?: boolean }) => props.makeFlush ? '' : '5px'};
-  margin-right: 5px;
-`;
-
 const Wrapper = styled.div`
   width: 100%;
   height: 100%;