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

Merge pull request #2298 from porter-dev/nico/por-652-porter-form-add-url-link-component

[POR-652] Porter form add url link component
abelanger5 3 лет назад
Родитель
Сommit
2cae3e76ec

+ 8 - 0
dashboard/src/components/porter-form/FormDebugger.tsx

@@ -11,6 +11,7 @@ import "ace-builds/src-noconflict/mode-text";
 
 import Heading from "../form-components/Heading";
 import Helper from "../form-components/Helper";
+import { ChartType } from "shared/types";
 
 type PropsType = {
   goBack: () => void;
@@ -170,6 +171,13 @@ export default class FormDebugger extends Component<PropsType, StateType> {
           rightTabOptions={this.state.showBonusTabs ? tabOptions : []}
           renderTabContents={this.renderTabContents}
           saveButtonText={"Test Submit"}
+          injectedProps={{
+            "url-link": {
+              chart: {
+                name: "something",
+              } as ChartType,
+            },
+          }}
         />
       </StyledFormDebugger>
     );

+ 4 - 0
dashboard/src/components/porter-form/PorterForm.tsx

@@ -12,6 +12,7 @@ import {
   SelectField,
   ServiceIPListField,
   TextAreaField,
+  UrlLinkField,
 } from "./types";
 import TabRegion, { TabOption } from "../TabRegion";
 import Heading from "../form-components/Heading";
@@ -29,6 +30,7 @@ import ResourceList from "./field-components/ResourceList";
 import VeleroForm from "./field-components/VeleroForm";
 import CronInput from "./field-components/CronInput";
 import TextAreaInput from "./field-components/TextAreaInput";
+import UrlLink from "./field-components/UrlLink";
 
 interface Props {
   leftTabOptions?: TabOption[];
@@ -98,6 +100,8 @@ const PorterForm: React.FC<Props> = (props) => {
         return <CronInput {...(bundledProps as CronField)} />;
       case "text-area":
         return <TextAreaInput {...(bundledProps as TextAreaField)} />;
+      case "url-link":
+        return <UrlLink {...(bundledProps as UrlLinkField)} />;
     }
     return <p>Not Implemented: {(field as any).type}</p>;
   };

+ 94 - 0
dashboard/src/components/porter-form/field-components/UrlLink.tsx

@@ -0,0 +1,94 @@
+import { get } from "lodash";
+import React from "react";
+import styled from "styled-components";
+import { UrlLinkField } from "../types";
+import { hasSetValue } from "../utils";
+
+const populate = (str: string, obj: unknown) => {
+  return str.replace(/{[^{}]*}+/g, (match) => {
+    const key = match.replace("{", "").replace("}", "");
+    let value;
+    if (key[0] === ".") {
+      value = get(obj, key.substring(1));
+    } else {
+      value = get(obj, key);
+    }
+
+    if (typeof value !== "string") {
+      return "Couldn't find value " + key;
+    }
+
+    return value;
+  });
+};
+
+const UrlLink = (props: UrlLinkField) => {
+  const { value, label, injectedProps } = props;
+
+  if (!hasSetValue(props)) {
+    return null;
+  }
+
+  let val = value;
+
+  if (Array.isArray(value)) {
+    val = value[0];
+  }
+
+  if (typeof val !== "string") {
+    return null;
+  }
+
+  if (!injectedProps?.chart) {
+    return null;
+  }
+
+  const populatedUrl = populate(val, injectedProps.chart);
+
+  return (
+    <>
+      <Label>{label}</Label>
+      <StyledServiceRow>
+        <a href={populatedUrl} target="_blank">
+          <i className="material-icons-outlined">link</i>
+          {populatedUrl}
+        </a>
+      </StyledServiceRow>
+    </>
+  );
+};
+
+export default UrlLink;
+
+const StyledServiceRow = styled.div`
+  width: 100%;
+  height: 40px;
+  background: #ffffff11;
+  margin-bottom: 15px;
+  border-radius: 5px;
+  padding: 15px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  > a {
+    margin-left: 2px;
+    font-size: 13px;
+    user-select: text;
+    display: flex;
+    -webkit-box-align: center;
+    align-items: center;
+    > i {
+      font-size: 15px;
+      margin-right: 10px;
+    }
+  }
+`;
+
+const Label = styled.div`
+  color: #ffffff;
+  margin-bottom: 10px;
+  display: flex;
+  align-items: center;
+  font-size: 13px;
+  font-family: "Work Sans", sans-serif;
+`;

+ 11 - 2
dashboard/src/components/porter-form/types.ts

@@ -5,7 +5,7 @@
 
 // YAML Field interfaces
 
-import { ContextProps } from "../../shared/types";
+import { ChartType, ContextProps } from "../../shared/types";
 
 export interface GenericField {
   id: string;
@@ -146,6 +146,14 @@ export interface TextAreaField extends GenericInputField {
   };
 }
 
+export interface UrlLinkField extends GenericInputField {
+  type: "url-link";
+  label: string;
+  injectedProps: {
+    chart: ChartType;
+  };
+}
+
 export type FormField =
   | HeadingField
   | SubtitleField
@@ -159,7 +167,8 @@ export type FormField =
   | VeleroBackupField
   | VariableField
   | CronField
-  | TextAreaField;
+  | TextAreaField
+  | UrlLinkField;
 
 export interface ShowIfAnd {
   and: ShowIf[];

+ 3 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -870,6 +870,9 @@ const ExpandedChart: React.FC<Props> = (props) => {
                                 ? stackEnvGroups
                                 : undefined,
                           },
+                          "url-link": {
+                            chart: currentChart,
+                          },
                         }}
                       />
                     </BodyWrapper>

+ 3 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedJobChart.tsx

@@ -395,6 +395,9 @@ export const ExpandedJobChartFC: React.FC<{
                   availableSyncEnvGroups:
                     isStack && !disableForm ? stackEnvGroups : undefined,
                 },
+                "url-link": {
+                  chart: chart,
+                },
               }}
             />
           )}