浏览代码

HUE-9418. [docs] Tech to render web components in docs (sree)

sreenaths 5 年之前
父节点
当前提交
e13e9b5b86

+ 7 - 5
docs/docs-site/content/developer/components/er-diagram/_index.md

@@ -5,9 +5,13 @@ draft: false
 
 
 The [Entity-relationship model](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model) (ERD) provides an illustration of various SQL entities, and the relationship between them. Entity types supported by the ERD diagram are currently `Table` & `Literal`. It has a very generic architecture, and more types of entities can be supported in the future.
 The [Entity-relationship model](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model) (ERD) provides an illustration of various SQL entities, and the relationship between them. Entity types supported by the ERD diagram are currently `Table` & `Literal`. It has a very generic architecture, and more types of entities can be supported in the future.
 
 
-!["EDR Table Component"](https://cdn.gethue.com/uploads/2020/07/erd_table_viz.png)
+{{< webcomp name="er-diagram"
+    src="demo/er-diagram.js"
+    attrSrc="demo/attrs.json"
+    events="entity-clicked:name"
+/>}}
 
 
-## Import
+### Import
 
 
 Please refer [here](/developer/components/#using-ui-components-in-your-project) for importing the component in your own project. Also [er-diagram-demo](https://github.com/cloudera/hue/tree/master/tools/examples/components/er-diagram-demo) app have working examples.
 Please refer [here](/developer/components/#using-ui-components-in-your-project) for importing the component in your own project. Also [er-diagram-demo](https://github.com/cloudera/hue/tree/master/tools/examples/components/er-diagram-demo) app have working examples.
 
 
@@ -15,8 +19,6 @@ Once imported `er-diagram` can be used like a native HTML tag.
 
 
     <er-diagram id="erd-element-id"/>
     <er-diagram id="erd-element-id"/>
 
 
-## Properties
-
 ### Attributes
 ### Attributes
 
 
 - entities: Array &lt;[IEntity](https://github.com/cloudera/hue/blob/master/desktop/core/src/desktop/js/components/er-diagram/lib/interfaces.ts#L21)&gt; - An array of entity objects. Each entity will be a box in the UI.
 - entities: Array &lt;[IEntity](https://github.com/cloudera/hue/blob/master/desktop/core/src/desktop/js/components/er-diagram/lib/interfaces.ts#L21)&gt; - An array of entity objects. Each entity will be a box in the UI.
@@ -28,7 +30,7 @@ Please refer the [interfaces](https://github.com/cloudera/hue/blob/master/deskto
 
 
 - entity-clicked: Function([IEntity](https://github.com/cloudera/hue/blob/master/desktop/core/src/desktop/js/components/er-diagram/lib/interfaces.ts#L21)) - Will be triggered when an entity is clicked.
 - entity-clicked: Function([IEntity](https://github.com/cloudera/hue/blob/master/desktop/core/src/desktop/js/components/er-diagram/lib/interfaces.ts#L21)) - Will be triggered when an entity is clicked.
 
 
-### Resource Files
+#### Resource Files
 
 
 - Hue
 - Hue
   - **Web Component:** gethue/web/er-diagram.js
   - **Web Component:** gethue/web/er-diagram.js

+ 189 - 0
docs/docs-site/content/developer/components/er-diagram/demo/attrs.json

@@ -0,0 +1,189 @@
+{
+  "entities": [
+    {
+      "id": "default.inventory",
+      "type": "TABLE",
+      "database": "default",
+      "name": "inventory",
+      "columns": [
+        {
+          "id": "default.inventory.id",
+          "type": "COLUMN",
+          "tableId": "default.inventory",
+          "name": "id"
+        },
+        {
+          "id": "default.inventory.quantity",
+          "type": "COLUMN",
+          "tableId": "default.inventory",
+          "name": "quantity"
+        },
+        {
+          "id": "default.inventory.product_id",
+          "type": "COLUMN",
+          "tableId": "default.inventory",
+          "name": "product_id"
+        },
+        {
+          "id": "default.inventory.vendor_id",
+          "type": "COLUMN",
+          "tableId": "default.inventory",
+          "name": "vendor_id"
+        }
+      ]
+    },
+    {
+      "id": "market.products",
+      "type": "TABLE",
+      "database": "market",
+      "name": "products",
+      "columns": [
+        {
+          "id": "market.products.id",
+          "type": "COLUMN",
+          "tableId": "market.products",
+          "name": "id"
+        },
+        {
+          "id": "market.products.name",
+          "type": "COLUMN",
+          "tableId": "market.products",
+          "name": "name"
+        },
+        {
+          "id": "market.products.description",
+          "type": "COLUMN",
+          "tableId": "market.products",
+          "name": "description"
+        },
+        {
+          "id": "market.products.category_id",
+          "type": "COLUMN",
+          "tableId": "market.products",
+          "name": "category_id"
+        }
+      ]
+    },
+    {
+      "id": "market.vendors",
+      "type": "TABLE",
+      "database": "market",
+      "name": "vendors",
+      "columns": [
+        {
+          "id": "market.vendors.id",
+          "type": "COLUMN",
+          "tableId": "market.vendors",
+          "name": "id"
+        },
+        {
+          "id": "market.vendors.name",
+          "type": "COLUMN",
+          "tableId": "market.vendors",
+          "name": "name"
+        }
+      ]
+    },
+    {
+      "id": "market.product_categories",
+      "type": "TABLE",
+      "database": "market",
+      "name": "product_categories",
+      "columns": [
+        {
+          "id": "market.product_categories.id",
+          "type": "COLUMN",
+          "tableId": "market.product_categories",
+          "name": "id"
+        },
+        {
+          "id": "market.product_categories.name",
+          "type": "COLUMN",
+          "tableId": "market.product_categories",
+          "name": "name"
+        },
+        {
+          "id": "market.product_categories.description",
+          "type": "COLUMN",
+          "tableId": "market.product_categories",
+          "name": "description"
+        }
+      ]
+    }
+  ],
+  "relations": [
+    {
+      "desc": "Foreign Key",
+      "left": {
+        "id": "default.inventory.product_id",
+        "type": "COLUMN",
+        "tableId": "default.inventory",
+        "name": "product_id"
+      },
+      "right": {
+        "id": "market.products.id",
+        "type": "COLUMN",
+        "tableId": "market.products",
+        "name": "id"
+      }
+    },
+    {
+      "desc": "Foreign Key",
+      "left": {
+        "id": "default.inventory.vendor_id",
+        "type": "COLUMN",
+        "tableId": "default.inventory",
+        "name": "vendor_id"
+      },
+      "right": {
+        "id": "market.vendors.id",
+        "type": "COLUMN",
+        "tableId": "market.vendors",
+        "name": "id"
+      }
+    },
+    {
+      "desc": "Foreign Key",
+      "left": {
+        "id": "market.products.category_id",
+        "type": "COLUMN",
+        "tableId": "market.products",
+        "name": "category_id"
+      },
+      "right": {
+        "id": "market.product_categories.id",
+        "type": "COLUMN",
+        "tableId": "market.product_categories",
+        "name": "id"
+    }
+    },
+    {
+      "desc": "Foreign Key",
+      "left": {
+        "id": "market.product_categories.name",
+        "type": "COLUMN",
+        "tableId": "market.product_categories",
+        "name": "name"
+    },
+      "right": {
+        "id": "Laptop",
+        "type": "LITERAL",
+        "value": "Laptop"
+      }
+    },
+    {
+      "desc": "Foreign Key",
+      "left": {
+        "id": "market.vendors.name",
+        "type": "COLUMN",
+        "tableId": "market.vendors",
+        "name": "name"
+      },
+      "right": {
+        "id": "Apple",
+        "type": "LITERAL",
+        "value": "Apple"
+      }
+    }
+  ]
+}

文件差异内容过多而无法显示
+ 13 - 0
docs/docs-site/content/developer/components/er-diagram/demo/er-diagram.js


+ 206 - 0
docs/docs-site/layouts/shortcodes/webcomp.html

@@ -0,0 +1,206 @@
+<style>
+  .webcomp-sc {
+    position: relative;
+    color: var(--MAIN-TITLES-TEXT-color);
+  }
+
+  .comp-container {
+    margin-right: 30px;
+    transition: margin-right .5s ease-in-out;
+  }
+  .webcomp-sc.expanded .comp-container {
+    margin-right: 250px;
+  }
+
+  // customizer panel
+  .customizer-panel {
+    position: absolute;
+    top: 0px;
+    right: 0px;
+
+    overflow: hidden;
+
+    width: 25px;
+    height: 100%;
+
+    border: 1px solid #d6d8db;
+    border-radius: 5px;
+
+    padding: 3px 5px;
+
+    transition: width .5s ease-in-out;
+  }
+  .webcomp-sc.expanded .customizer-panel {
+    width: 245px;
+  }
+
+  // customizer panel content
+  .customizer-panel .panel-content {
+    height: 100%;
+    margin-left: 20px;
+    transition: margin-left .5s ease-in-out;
+
+    display: flex;
+    flex-direction: column;
+  }
+  .webcomp-sc.expanded .customizer-panel .panel-content {
+    margin-left: 0;
+  }
+  .webcomp-sc.hide-events .wc-events {
+    display: none;
+  }
+
+  .customizer-panel .panel-content textarea {
+    width: 232px;
+    margin-bottom: 5px;
+
+    resize: none;
+
+    font-family: "Lucida Console", Courier, monospace;
+    font-size: .7em;
+    white-space: pre;
+  }
+
+  .customizer-panel .panel-content .attributes-txt {
+    flex: 4;
+  }
+  .customizer-panel .panel-content .events-txt {
+    flex: 1;
+  }
+
+  // Expand collapse button
+  .customizer-panel .exp-collapse-button {
+    position: absolute;
+    right: 5px;
+    top: 3px;
+    height: 100%;
+
+    display: inline-block;
+    user-select: none;
+  }
+  .customizer-panel .exp-collapse-button em.fa-plus {
+    transition: transform .5s ease-in-out;
+  }
+  .webcomp-sc.expanded .customizer-panel .exp-collapse-button em.fa-plus {
+    transform: rotate(45deg);
+  }
+
+  .customizer-panel .exp-collapse-button .cust-txt {
+    position: absolute;
+    left: -5px;
+    top: 50%;
+    margin-top: -50px;
+
+    writing-mode: vertical-rl;
+    color: var(--MAIN-TITLES-TEXT-color);
+    letter-spacing: .15em;
+
+    transition: left .2s ease-in-out;
+  }
+  .webcomp-sc.expanded .customizer-panel .exp-collapse-button .cust-txt {
+    left: 20px;
+  }
+</style>
+
+<div class="webcomp-sc">
+  <script type = "text/javascript" src={{ .Get "src" }}></script>
+
+  <div class="comp-container"></div>
+
+  <div class="customizer-panel">
+    <div class="panel-content">
+      <b>Attributes</b>
+      <textarea class="attributes-txt"></textarea>
+      <b class="wc-events">Events</b>
+      <textarea class="wc-events events-txt" readonly></textarea>
+    </div>
+
+    <div class="exp-collapse-button">
+      <a href="javascript:void(0);"><em class="fa fa-plus"></em></a>
+      <span class="cust-txt">Customize</span>
+    </div>
+  </div>
+</div>
+
+<script type = "text/javascript">
+  function initWebcomp() {
+    const webcomps = document.querySelectorAll(".webcomp-sc");
+    const currentWebcomp = webcomps[webcomps.length - 1];
+
+    currentWebcomp.querySelector(".exp-collapse-button a")
+        .addEventListener("click", event => {
+          currentWebcomp.classList.toggle("expanded");
+        });
+
+    return currentWebcomp;
+  }
+
+  function createComponent(name, innerHTML) {
+    const webcomp = initWebcomp();
+    const container = webcomp.querySelector(".comp-container");
+    const eventsTxtArea = webcomp.querySelector("textarea.events-txt");
+    const attributesTextArea = webcomp.querySelector("textarea.attributes-txt");
+
+    const component = document.createElement(name);
+    component.innerHTML = innerHTML;
+    container.appendChild(component);
+
+    return {webcomp, component, eventsTxtArea, attributesTextArea};
+  }
+
+  function loadAttrs(url, callback) {
+    fetch(url)
+      .then(response => response.json())
+      .then(json => callback(json));
+  }
+
+  (function ({webcomp, component, eventsTxtArea, attributesTextArea}, params){
+    const attrsPrefix = "-";
+
+    // Init attributes
+    function initAttrs(attrs) {
+      Object.assign(component, attrs);
+      attributesTextArea.value = JSON.stringify(attrs, null, 2);
+    }
+
+    if(params.attrSrc) {
+      loadAttrs(params.attrSrc, initAttrs);
+    } else {
+      const attrs = params.filter(param => param.startsWith(attrsPrefix));
+      initAttrs(params);
+    }
+
+    attributesTextArea.addEventListener("input", function () {
+      Object.assign(component, JSON.parse(attributesTextArea.value));
+    });
+
+    // Add event listeners
+    function handleEvent(propertyName, event) {
+      console.log("Event triggered:", event, $);
+
+      let eventTxt = event.type;
+
+      const eventProp = event.detail[0][propertyName];
+
+      if(eventProp) {
+        eventTxt = `${eventTxt} : ${eventProp}`;
+      }
+
+      eventsTxtArea.value +=  `${eventTxt}\r\n`;
+      eventsTxtArea.scrollTop = eventsTxtArea.scrollHeight;
+    }
+
+    if(params.events) {
+      params.events.split(",").forEach(event => {
+        const [eventName, propertyName] = event.split(":");
+        component.addEventListener(eventName, handleEvent.bind(this, propertyName));
+      });
+    } else {
+      webcomp.classList.add("hide-events");
+    }
+
+  })(
+    createComponent({{ .Get "name" }}, {{ .Inner }}),
+    {{ .Params }}
+  );
+</script>

部分文件因为文件数量过多而无法显示