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

Merge pull request #799 from porter-dev/0.5.0-better-showif-logic

[0.5.0] [Frontend, Forms] Improvements for show_if and other form variables
abelanger5 4 лет назад
Родитель
Сommit
2eec063aee

+ 4 - 1
dashboard/src/components/values-form/FormDebugger.tsx

@@ -281,7 +281,10 @@ tabs:
     - type: subtitle
       label: "Note: Hidden required fields aren't supported yet (global only)"
   - name: controlled-by-external
-    show_if: checkbox_a
+    show_if:
+      or:
+        - checkbox_a
+        - not_a_variable
     contents:
     - type: heading
       label: Conditional Display (A)

+ 11 - 1
dashboard/src/components/values-form/FormWrapper.tsx

@@ -65,7 +65,17 @@ export default class FormWrapper extends Component<PropsType, StateType> {
       let tabOptions = [] as { value: string; label: string }[];
       let tabs = this.props.formData?.tabs;
       let requiredFields = [] as string[];
-      let metaState: any = {};
+      let metaState: any = {
+        "currentCluster.service.is_gcp": {
+          value: this.context.currentCluster.service == "gke",
+        },
+        "currentCluster.service.is_aws": {
+          value: this.context.currentCluster.service == "eks",
+        },
+        "currentCluster.service.is_do": {
+          value: this.context.currentCluster.service == "doks",
+        },
+      };
       if (tabs) {
         tabs.forEach((tab: any, i: number) => {
           if (tab?.name && tab.label) {

+ 43 - 8
dashboard/src/components/values-form/ValuesForm.tsx

@@ -1,7 +1,14 @@
 import React, { Component } from "react";
 import styled from "styled-components";
 
-import { Section, FormElement } from "shared/types";
+import {
+  Section,
+  FormElement,
+  ShowIf,
+  ShowIfOr,
+  ShowIfAnd,
+  ShowIfNot,
+} from "shared/types";
 import { Context } from "shared/Context";
 
 import CheckboxRow from "./CheckboxRow";
@@ -305,17 +312,45 @@ export default class ValuesForm extends Component<PropsType, StateType> {
     });
   };
 
+  evalShowIf = (vals: ShowIf): boolean => {
+    if (!vals) {
+      return false;
+    }
+    if (typeof vals == "string") {
+      return !!this.props.metaState[vals]?.value;
+    }
+    if ((vals as ShowIfOr).or) {
+      vals = vals as ShowIfOr;
+      for (let i = 0; i < vals.or.length; i++) {
+        if (this.evalShowIf(vals.or[i])) {
+          return true;
+        }
+      }
+      return false;
+    }
+    if ((vals as ShowIfAnd).and) {
+      vals = vals as ShowIfAnd;
+      for (let i = 0; i < vals.and.length; i++) {
+        if (!this.evalShowIf(vals.and[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    if ((vals as ShowIfNot).not) {
+      vals = vals as ShowIfNot;
+      return !this.evalShowIf(vals.not);
+    }
+
+    return false;
+  };
+
   renderFormContents = () => {
     if (this.props.metaState) {
       return this.props.sections?.map((section: Section, i: number) => {
         // Hide collapsible section if deciding field is false
-        if (section.show_if) {
-          if (
-            !this.props.metaState[section.show_if] ||
-            this.props.metaState[section.show_if].value === false
-          ) {
-            return null;
-          }
+        if (section.show_if && !this.evalShowIf(section.show_if)) {
+          return null;
         }
 
         return <div key={i}>{this.renderSection(section)}</div>;

+ 15 - 1
dashboard/src/shared/types.tsx

@@ -104,9 +104,23 @@ export interface FormYAML {
   }[];
 }
 
+export interface ShowIfAnd {
+  and: ShowIf[];
+}
+
+export interface ShowIfOr {
+  or: ShowIf[];
+}
+
+export interface ShowIfNot {
+  not: ShowIf;
+}
+
+export type ShowIf = string | ShowIfAnd | ShowIfOr | ShowIfNot;
+
 export interface Section {
   name?: string;
-  show_if?: string;
+  show_if?: ShowIf;
   contents: FormElement[];
 }
 

+ 1 - 1
internal/models/templates.go

@@ -36,7 +36,7 @@ type FormTab struct {
 type FormSection struct {
 	Context  *FormContext   `yaml:"context" json:"context"`
 	Name     string         `yaml:"name" json:"name"`
-	ShowIf   string         `yaml:"show_if" json:"show_if"`
+	ShowIf   interface{}    `yaml:"show_if" json:"show_if"`
 	Contents []*FormContent `yaml:"contents" json:"contents,omitempty"`
 }