Browse Source

Merge pull request #197 from porter-dev/beta.3.integration-frontend

Beta.3.integration frontend
jusrhee 5 years ago
parent
commit
6083e5e2a7

+ 2 - 5
dashboard/src/main/home/Home.tsx

@@ -77,9 +77,7 @@ export default class Home extends Component<PropsType, StateType> {
                 }
               });
               
-              console.log('infras viewdata: ', viewData);
               if (viewData.length > 0) {
-                console.log('setting to provisioner...');
                 this.setState({ currentView: 'provisioner', viewData, sidebarReady: true, });
               } else {
                 this.setState({ sidebarReady: true });
@@ -108,7 +106,6 @@ export default class Home extends Component<PropsType, StateType> {
           prevProjectId: this.context.currentProject.id,
           currentView: 'dashboard'
         });
-        console.log('setting view to dashboard from Home');
       }
     }
   }
@@ -300,8 +297,8 @@ const ProjectModalStyles = {
     width: '565px',
     maxWidth: '80vw',
     margin: '0 auto',
-    height: '225px',
-    top: 'calc(50% - 120px)',
+    height: '275px',
+    top: 'calc(50% - 160px)',
     backgroundColor: '#202227',
     animation: 'floatInModal 0.5s 0s',
     overflow: 'visible',

+ 0 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/graph/GraphDisplay.tsx

@@ -136,7 +136,6 @@ export default class GraphDisplay extends Component<PropsType, StateType> {
   // Live update on rollback/upgrade
   componentDidUpdate(prevProps: PropsType) {
     if (prevProps.components !== this.props.components) {
-      console.log(this.props.components);
       this.storeChartGraph(prevProps);
       this.getChartGraph();
     }

+ 48 - 17
dashboard/src/main/home/modals/UpdateClusterModal.tsx

@@ -91,6 +91,16 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
           />
         </InputWrapper>
 
+        <Warning highlight={true}>
+          ⚠️ Deletion may result in dangling resources. Please visit the AWS console to ensure that all resources have been removed.
+        </Warning>
+        <Help 
+          href='https://docs.getporter.dev/docs/getting-started-with-porter-on-aws#deleting-provisioned-resources'
+          target='_blank'
+        >
+          <i className="material-icons">help_outline</i> Help
+        </Help>
+
         <SaveButton
           text='Delete Cluster'
           color='#b91133'
@@ -104,12 +114,6 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
           onYes={this.handleDelete}
           onNo={() => this.setState({ showDeleteOverlay: false })}
         />
-
-        <Warning>
-         ⚠️ Deletion via Porter may result in dangling resources.  
-         Please visit the AWS console to ensure that all resources have been removed.
-        </Warning>
-
       </StyledUpdateProjectModal>
       );
   }
@@ -117,6 +121,42 @@ export default class UpdateClusterModal extends Component<PropsType, StateType>
 
 UpdateClusterModal.contextType = Context;
 
+const Help = styled.a`
+  position: absolute;
+  left: 31px;
+  bottom: 35px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #ffffff55;
+  font-size: 13px;
+  :hover {
+    color: #ffffff;
+  }
+
+  > i {
+    margin-right: 9px;
+    font-size: 16px;
+  }
+`;
+
+const Warning = styled.div`
+  font-size: 13px;
+  display: flex;
+  border-radius: 3px;
+  width: calc(100%);
+  margin-top: 10px;
+  margin-left: 2px;
+  line-height: 1.4em;
+  align-items: center;
+  color: white;
+  > i {
+    margin-right: 10px;
+    font-size: 18px;
+  }
+  color: ${(props: { highlight: boolean, makeFlush?: boolean }) => props.highlight ? '#f5cb42' : ''};
+`;
+
 const DashboardIcon = styled.div`
   width: 25px;
   min-width: 25px;
@@ -198,17 +238,8 @@ const StyledUpdateProjectModal= styled.div`
   left: 0;
   top: 0;
   height: 100%;
-  padding: 25px 32px;
+  padding: 25px 30px;
   overflow: hidden;
   border-radius: 6px;
   background: #202227;
-`;
-
-const Warning = styled.div`
-  width: 65%;
-  margin-top: 3px;
-  font-family: 'Work Sans', sans-serif;
-  font-size: 13px;
-  color: #aaaabb;
-  text-align: justify;
-`
+`;

+ 48 - 15
dashboard/src/main/home/modals/UpdateProjectModal.tsx

@@ -115,6 +115,16 @@ export default class UpdateProjectModal extends Component<PropsType, StateType>
           />
         </InputWrapper>
 
+        <Warning highlight={true}>
+          ⚠️ Deletion may result in dangling resources. Please visit the AWS console to ensure that all resources have been removed.
+        </Warning>
+        <Help 
+          href='https://docs.getporter.dev/docs/getting-started-with-porter-on-aws#deleting-provisioned-resources'
+          target='_blank'
+        >
+          <i className="material-icons">help_outline</i> Help
+        </Help>
+
         <SaveButton
           text='Delete Project'
           color='#b91133'
@@ -128,17 +138,49 @@ export default class UpdateProjectModal extends Component<PropsType, StateType>
           onYes={this.handleDelete}
           onNo={() => this.setState({ showDeleteOverlay: false })}
         />
-        <Warning>
-         ⚠️ Deletion via Porter may result in dangling resources.  
-         Please visit the AWS console to ensure that all resources have been removed.
-        </Warning>
       </StyledUpdateProjectModal>
-      );
+    );
   }
 }
 
 UpdateProjectModal.contextType = Context;
 
+const Help = styled.a`
+  position: absolute;
+  left: 31px;
+  bottom: 35px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #ffffff55;
+  font-size: 13px;
+  :hover {
+    color: #ffffff;
+  }
+
+  > i {
+    margin-right: 9px;
+    font-size: 16px;
+  }
+`;
+
+const Warning = styled.div`
+  font-size: 13px;
+  display: flex;
+  border-radius: 3px;
+  width: calc(100%);
+  margin-top: 10px;
+  margin-left: 2px;
+  line-height: 1.4em;
+  align-items: center;
+  color: white;
+  > i {
+    margin-right: 10px;
+    font-size: 18px;
+  }
+  color: ${(props: { highlight: boolean, makeFlush?: boolean }) => props.highlight ? '#f5cb42' : ''};
+`;
+
 const Letter = styled.div`
   height: 100%;
   width: 100%;
@@ -232,13 +274,4 @@ const StyledUpdateProjectModal= styled.div`
   overflow: hidden;
   border-radius: 6px;
   background: #202227;
-`;
-
-const Warning = styled.div`
-  width: 65%;
-  margin-top: 3px;
-  font-family: 'Work Sans', sans-serif;
-  font-size: 13px;
-  color: #aaaabb;
-  text-align: justify;
-`
+`;

+ 0 - 3
dashboard/src/main/home/new-project/Provisioner.tsx

@@ -181,7 +181,6 @@ export default class Provisioner extends Component<PropsType, StateType> {
         <TitleSection>
           <Title><img src={loading} /> Setting Up Porter</Title>
         </TitleSection>
-
         <Helper>
           Porter is currently being provisioned to your AWS account:
         </Helper>
@@ -193,13 +192,11 @@ export default class Provisioner extends Component<PropsType, StateType> {
     let msg = '🛠️ ' + this.context.user.email + ' completed provisioning.';
     handleSubmitFeedback(msg);
     let myInterval = setInterval(() => {
-      console.log('interval')
       api.getClusters('<token>', {}, { id: this.context.currentProject.id }, (err: any, res: any) => {
         if (err) {
           console.log(err);
         } else if (res.data) {
           let clusters = res.data;
-          console.log('found clusters:', res.data);
           if (clusters.length > 0) {
             this.props.setCurrentView('dashboard');
             clearInterval(myInterval);

+ 0 - 4
dashboard/src/main/home/sidebar/ClusterSection.tsx

@@ -53,14 +53,12 @@ export default class ClusterSection extends Component<PropsType, StateType> {
         // TODO: handle uninitialized kubeconfig
         if (res.data) {
           let clusters = res.data;
-          console.log('found clusters:', res.data);
           if (clusters.length > 0) {
             this.setState({ clusters });
             setCurrentCluster(clusters[0]);
           } else if (this.props.currentView !== 'provisioner') {
             this.setState({ clusters: [] });
             setCurrentCluster(null);
-            console.log('set to dashboard from clustersection');
             this.props.setCurrentView('dashboard');
           }
         }
@@ -70,7 +68,6 @@ export default class ClusterSection extends Component<PropsType, StateType> {
 
   componentDidMount() {
     this.updateClusters();
-    console.log('mounted clustersection');
   }
 
   // Need to override showDrawer when the sidebar is closed
@@ -84,7 +81,6 @@ export default class ClusterSection extends Component<PropsType, StateType> {
       } else if (this.props.forceRefreshClusters === true) {
         this.updateClusters();
         this.props.setRefreshClusters(false);
-        console.log('hard refereshed clusters');
       }
 
       if (this.props.forceCloseDrawer && this.state.showDrawer) {

+ 0 - 1
dashboard/src/main/home/sidebar/ProjectSection.tsx

@@ -42,7 +42,6 @@ export default class ProjectSection extends Component<PropsType, StateType> {
         if (viewData.length > 0) {
           this.props.setCurrentView('provisioner', viewData);
         } else {
-          console.log('set to dashboard from projectsection');
           this.props.setCurrentView('dashboard');
         }
       }

+ 19 - 13
dashboard/src/main/home/templates/Templates.tsx

@@ -13,6 +13,12 @@ const tabOptions = [
   { label: 'Community Templates', value: 'community' }
 ];
 
+// TODO: read in from metadata
+const hardcodedNames: any = {
+  'postgresql': 'PostgreSQL',
+  'docker': 'Docker',
+};
+
 type PropsType = {
   setCurrentView: (x: string) => void, // Link to add integration from source selector
 };
@@ -20,7 +26,7 @@ type PropsType = {
 type StateType = {
   currentTemplate: PorterTemplate | null,
   currentTab: string,
-  PorterTemplates: PorterTemplate[],
+  porterTemplates: PorterTemplate[],
   loading: boolean,
   error: boolean
 };
@@ -29,7 +35,7 @@ export default class Templates extends Component<PropsType, StateType> {
   state = {
     currentTemplate: null as (PorterTemplate | null),
     currentTab: 'community',
-    PorterTemplates: [] as PorterTemplate[],
+    porterTemplates: [] as PorterTemplate[],
     loading: true,
     error: false,
   }
@@ -39,7 +45,8 @@ export default class Templates extends Component<PropsType, StateType> {
       if (err) {
         this.setState({ loading: false, error: true });
       } else {
-        this.setState({ PorterTemplates: res.data, loading: false, error: false });
+        this.setState({ porterTemplates: res.data, loading: false, error: false });
+        console.log(res.data)
       }
     });
   }
@@ -55,7 +62,7 @@ export default class Templates extends Component<PropsType, StateType> {
   }
 
   renderTemplateList = () => {
-    let { loading, error, PorterTemplates } = this.state;
+    let { loading, error, porterTemplates } = this.state;
 
     if (loading) {
       return <LoadingWrapper><Loading /></LoadingWrapper>
@@ -65,7 +72,7 @@ export default class Templates extends Component<PropsType, StateType> {
           <i className="material-icons">error</i> Error retrieving templates.
         </Placeholder>
       );
-    } else if (PorterTemplates.length === 0) {
+    } else if (porterTemplates.length === 0) {
       return (
         <Placeholder>
           <i className="material-icons">category</i> No templates found.
@@ -73,17 +80,16 @@ export default class Templates extends Component<PropsType, StateType> {
       );
     }
 
-    return this.state.PorterTemplates.map((template: PorterTemplate, i: number) => {
+    return this.state.porterTemplates.map((template: PorterTemplate, i: number) => {
       let { name, icon, description } = template;
+      if (hardcodedNames[name]) {
+        name = hardcodedNames[name];
+      }
       return (
         <TemplateBlock key={i} onClick={() => this.setState({ currentTemplate: template })}>
-          {icon ? this.renderIcon(icon) : this.renderIcon(template.icon)}
-          <TemplateTitle>
-            {name ? name : template.name}
-          </TemplateTitle>
-          <TemplateDescription>
-            {description ? description : template.description}
-          </TemplateDescription>
+          {this.renderIcon(icon)}
+          <TemplateTitle>{name}</TemplateTitle>
+          <TemplateDescription>{description}</TemplateDescription>
         </TemplateBlock>
       )
     });

+ 1 - 0
dashboard/src/main/home/templates/expanded-template/ExpandedTemplate.tsx

@@ -45,6 +45,7 @@ export default class ExpandedTemplate extends Component<PropsType, StateType> {
         this.setState({ loading: false, error: true });
       } else {
         let { form, values, markdown, metadata } = res.data;
+        console.log(form)
         let keywords = metadata.keywords;
         this.setState({ form, values, markdown, keywords, loading: false, error: false });
       }

+ 68 - 41
dashboard/src/main/home/templates/expanded-template/LaunchTemplate.tsx

@@ -125,24 +125,22 @@ export default class LaunchTemplate extends Component<PropsType, StateType> {
         saveValuesStatus={this.state.saveValuesStatus}
         disabled={!this.state.selectedImageUrl}
       >
-        {
-          (metaState: any, setMetaState: any) => {
-            return this.props.form?.tabs.map((tab: any, i: number) => {
-
-              // If tab is current, render
-              if (tab.name === this.state.currentTab) {
-                return (
-                  <ValuesForm 
-                    metaState={metaState}
-                    setMetaState={setMetaState}
-                    key={tab.name}
-                    sections={tab.sections} 
-                  />
-                );
-              }
-            });
-          }
-        }
+        {(metaState: any, setMetaState: any) => {
+          return this.props.form?.tabs.map((tab: any, i: number) => {
+
+            // If tab is current, render
+            if (tab.name === this.state.currentTab) {
+              return (
+                <ValuesForm 
+                  metaState={metaState}
+                  setMetaState={setMetaState}
+                  key={tab.name}
+                  sections={tab.sections} 
+                />
+              );
+            }
+          });
+        }}
       </ValuesWrapper>
     );
   }
@@ -212,19 +210,28 @@ export default class LaunchTemplate extends Component<PropsType, StateType> {
   renderTabRegion = () => {
     if (this.state.tabOptions.length > 0) {
       return (
-        <TabRegion
-          options={this.state.tabOptions}
-          currentTab={this.state.currentTab}
-          setCurrentTab={(x: string) => this.setState({ currentTab: x })}
-        >
-          {this.renderTabContents()}
-        </TabRegion>
+        <>
+          <Subtitle>Configure additional settings for this template (optional).</Subtitle>
+          <TabRegion
+            options={this.state.tabOptions}
+            currentTab={this.state.currentTab}
+            setCurrentTab={(x: string) => this.setState({ currentTab: x })}
+          >
+            {this.renderTabContents()}
+          </TabRegion>
+        </>
       );
     } else {
       return (
         <Wrapper>
           <Placeholder>
-            No additional settings found.
+            To configure this chart through Porter, 
+            <Link 
+              target='_blank'
+              href='https://docs.getporter.dev/docs/porter-templates'
+            >
+              refer to our docs
+            </Link>.
           </Placeholder>
           <SaveButton
             text='Deploy'
@@ -237,6 +244,27 @@ export default class LaunchTemplate extends Component<PropsType, StateType> {
     }
   }
 
+  // Display if current template uses source (image or repo)
+  renderSourceSelector = () => {
+    if (this.props.form?.hasSource) {
+      return (
+        <>
+          <Subtitle>Select the container image you would like to connect to this template.</Subtitle>
+          <DarkMatter />
+          <ImageSelector
+            selectedTag={this.state.selectedTag}
+            selectedImageUrl={this.state.selectedImageUrl}
+            setSelectedImageUrl={this.setSelectedImageUrl}
+            setSelectedTag={(x: string) => this.setState({ selectedTag: x })}
+            forceExpanded={true}
+            setCurrentView={this.props.setCurrentView}
+          />
+          <br />
+        </>
+      );
+    }
+  }
+
   render() {
     let { name, icon } = this.props.currentTemplate;
     let { currentTemplate } = this.props;
@@ -281,20 +309,7 @@ export default class LaunchTemplate extends Component<PropsType, StateType> {
             closeOverlay={true}
           />
         </ClusterSection>
-
-        <Subtitle>Select the container image you would like to connect to this template.</Subtitle>
-        <DarkMatter />
-        <ImageSelector
-          selectedTag={this.state.selectedTag}
-          selectedImageUrl={this.state.selectedImageUrl}
-          setSelectedImageUrl={this.setSelectedImageUrl}
-          setSelectedTag={(x: string) => this.setState({ selectedTag: x })}
-          forceExpanded={true}
-          setCurrentView={this.props.setCurrentView}
-        />
-
-        <br />
-        <Subtitle>Configure additional settings for this template (optional).</Subtitle>
+        {this.renderSourceSelector()}
         {this.renderTabRegion()}
       </StyledLaunchTemplate>
     );
@@ -303,9 +318,21 @@ export default class LaunchTemplate extends Component<PropsType, StateType> {
 
 LaunchTemplate.contextType = Context;
 
+const Link = styled.a`
+  margin-left: 5px;
+`;
+
+const LineBreak = styled.div`
+  width: calc(100% - 0px);
+  height: 2px;
+  background: #ffffff20;
+  margin: 35px 0px 35px;
+`;
+
 const Wrapper = styled.div`
   width: 100%;
   position: relative;
+  padding-top: 20px;
   padding-bottom: 70px;
 `;
 
@@ -315,7 +342,7 @@ const Placeholder = styled.div`
   background: #ffffff11;
   border: 1px solid #ffffff44;
   border-radius: 5px;
-  color: #ffffff44;
+  color: #aaaabb;
   font-size: 13px;
   display: flex;
   align-items: center;

+ 19 - 5
dashboard/src/main/home/templates/expanded-template/TemplateInfo.tsx

@@ -4,11 +4,16 @@ import rocket from '../../../../assets/rocket.png';
 import Markdown from 'markdown-to-jsx';
 
 import { Context } from '../../../../shared/Context';
-import api from '../../../../shared/api';
 import Loading from '../../../../components/Loading';
 
 import { PorterTemplate } from '../../../../shared/types';
-import { timeStamp } from 'console';
+import Helper from '../../../../components/values-form/Helper';
+
+// TODO: read in from metadata
+const hardcodedNames: any = {
+  'postgresql': 'PostgreSQL',
+  'docker': 'Docker',
+};
 
 type PropsType = {
   currentTemplate: any,
@@ -52,8 +57,11 @@ export default class TemplateInfo extends Component<PropsType, StateType> {
     return currentTemplate.description;
   }
 
+
   renderTagSection = () => {
-    if (this.props.keywords && this.props.keywords.length > 0) {
+
+    // Rendering doesn't make sense until search + clicking on tags is supported
+    if (false && this.props.keywords && this.props.keywords.length > 0) {
       return (
         <TagSection>
           <i className="material-icons">local_offer</i>
@@ -96,8 +104,13 @@ export default class TemplateInfo extends Component<PropsType, StateType> {
 
   render() {
     let { currentCluster } = this.context;
-    let { name, icon } = this.props.currentTemplate;
+    let { name, icon, description } = this.props.currentTemplate;
     let { currentTemplate } = this.props;
+
+    if (hardcodedNames[name]) {
+      name = hardcodedNames[name];
+    }
+
     return (
       <StyledExpandedTemplate>
         <TitleSection>
@@ -116,6 +129,7 @@ export default class TemplateInfo extends Component<PropsType, StateType> {
             Launch Template
           </Button>
         </TitleSection>
+        <Helper>{description}</Helper>
         {this.renderTagSection()}
         <LineBreak />
         {this.renderBanner()}
@@ -182,7 +196,7 @@ const Tag = styled.div`
 `;
 
 const TagSection = styled.div`
-  margin-top: 20px;
+  margin-top: 25px;
   display: flex;
   font-size: 13px;
   font-family: 'Work Sans', sans-serif;

+ 1 - 0
internal/models/templates.go

@@ -59,6 +59,7 @@ type FormContent struct {
 type FormYAML struct {
 	Name        string     `yaml:"name" json:"name"`
 	Icon        string     `yaml:"icon" json:"icon"`
+	HasSource   string     `yaml:"hasSource" json:"hasSource"`
 	Description string     `yaml:"description" json:"description"`
 	Tags        []string   `yaml:"tags" json:"tags"`
 	Tabs        []*FormTab `yaml:"tabs" json:"tabs,omitempty"`