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

Docker Registry display and sorting

Sean Rhee 5 лет назад
Родитель
Сommit
9060ac7925

+ 42 - 2
dashboard/src/main/home/integrations/IntegrationList.tsx

@@ -8,6 +8,7 @@ import api from '../../../shared/api';
 type PropsType = {
   setCurrent: (x: any) => void,
   integrations: string[],
+  titles?: string[],
   isCategory?: boolean
 };
 
@@ -16,8 +17,32 @@ type StateType = {
 
 export default class IntegrationList extends Component<PropsType, StateType> {
   renderContents = () => {
-    let { integrations, setCurrent, isCategory } = this.props;
-    if (integrations && integrations.length > 0) {
+    let { integrations, titles, setCurrent, isCategory } = this.props;
+    if (titles && titles.length > 0) {
+      return integrations.map((integration: string, i: number) => {
+        let icon = integrationList[integration] && integrationList[integration].icon;
+        let subtitle = integrationList[integration] && integrationList[integration].label;
+        let label = titles[i];
+        let disabled = integration === 'repo' || integration === 'kubernetes';
+        return (
+          <Integration
+            key={i}
+            onClick={() => disabled ? null : setCurrent(integration)}
+            isCategory={isCategory}
+            disabled={disabled}
+          >
+            <Flex>
+              <Icon src={icon && icon} />
+              <Description>
+                <Label>{label}</Label>
+                <Subtitle>{subtitle}</Subtitle>
+              </Description>
+            </Flex>
+            <i className="material-icons">{isCategory ? 'launch' : 'more_vert'}</i>
+          </Integration>
+        );
+      });
+    } else if (integrations && integrations.length > 0) {
       return integrations.map((integration: string, i: number) => {
         let icon = integrationList[integration] && integrationList[integration].icon;
         let label = integrationList[integration] && integrationList[integration].label;
@@ -90,12 +115,27 @@ const Integration = styled.div`
   }
 `;
 
+const Description = styled.div`
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+`;
+
 const Label = styled.div`
   color: #ffffff;
   font-size: 14px;
   font-weight: 500;
 `;
 
+const Subtitle = styled.div`
+  color: #aaaabb;
+  font-size: 13px;
+  display: flex;
+  align-items: center;
+  padding-top: 5px;
+`;
+
 const Icon = styled.img`
   width: 30px;
   margin-right: 18px;

+ 29 - 3
dashboard/src/main/home/integrations/Integrations.tsx

@@ -16,6 +16,7 @@ type StateType = {
   currentCategory: string | null,
   currentIntegration: string | null,
   currentOptions: any[],
+  currentTitles: any[],
   currentIntegrationData: any[],
 };
 
@@ -24,6 +25,7 @@ export default class Integrations extends Component<PropsType, StateType> {
     currentCategory: null as string | null,
     currentIntegration: null as string | null,
     currentOptions: [] as any[],
+    currentTitles: [] as any[],
     currentIntegrationData: [] as any[],
   }
 
@@ -45,11 +47,25 @@ export default class Integrations extends Component<PropsType, StateType> {
           if (err) {
             console.log(err);
           } else {
+            // Sort res.data into service type and sort each service's registry alphabetically
+            let grouped: any = {}
+            let final: any = [];
+            for (let i = 0; i < res.data.length; i++) {
+              let p = res.data[i].service;
+              if (!grouped[p]) { grouped[p] = []; }
+              grouped[p].push(res.data[i]);
+            }
+            Object.values(grouped).forEach((val: any) => {
+              final = final.concat(val.sort((a: any, b: any) => (a.name > b.name) ? 1 : -1));
+            });
+
             let currentOptions = [] as string[];
-            res.data.forEach((integration: any, i: number) => {
-              currentOptions.includes(integration.service) ? null : currentOptions.push(integration.service);
+            let currentTitles = [] as string[];
+            final.forEach((integration: any, i: number) => {
+              currentOptions.push(integration.service);
+              currentTitles.push(integration.name);
             });
-            this.setState({ currentOptions, currentIntegrationData: res.data });
+            this.setState({ currentOptions, currentTitles, currentIntegrationData: res.data });
           }
         });
         break;
@@ -150,8 +166,11 @@ export default class Integrations extends Component<PropsType, StateType> {
             </Button>
           </TitleSectionAlt>
 
+          <LineBreak />
+
           <IntegrationList
             integrations={this.state.currentOptions}
+            titles={this.state.currentTitles}
             setCurrent={(x: string) => this.setState({ currentIntegration: x })}
           />
         </div>
@@ -293,4 +312,11 @@ const StyledIntegrations = styled.div`
   width: calc(90% - 150px);
   min-width: 300px;
   padding-top: 45px;
+`;
+
+const LineBreak = styled.div`
+  width: calc(100% - 0px);
+  height: 2px;
+  background: #ffffff20;
+  margin: 32px 0px 24px;
 `;

+ 2 - 2
dashboard/src/main/home/sidebar/Sidebar.tsx

@@ -117,9 +117,9 @@ export default class Sidebar extends Component<PropsType, StateType> {
             Templates
           </NavButton>
           <NavButton
-            // onClick={() => this.props.setCurrentView('integrations')}
+            onClick={() => this.props.setCurrentView('integrations')}
             selected={this.props.currentView === 'integrations'}
-            onClick={() => this.context.setCurrentModal('IntegrationsInstructionsModal', {})}
+            //onClick={() => this.context.setCurrentModal('IntegrationsInstructionsModal', {})}
           >
             <img src={integrations} />
             Integrations