From 18b568ce20b66c4e16521c043df804279a5cd163 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samuel_wilkins@brown.edu>
Date: Wed, 26 Jun 2019 23:19:12 -0400
Subject: implemented drag drop template from key value key selection

---
 src/client/views/nodes/KeyValueBox.tsx | 72 ++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 4 deletions(-)

(limited to 'src/client/views/nodes/KeyValueBox.tsx')

diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index cd65c42bc..4beb70284 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -7,13 +7,23 @@ import { FieldView, FieldViewProps } from './FieldView';
 import "./KeyValueBox.scss";
 import { KeyValuePair } from "./KeyValuePair";
 import React = require("react");
-import { NumCast, Cast, FieldValue } from "../../../new_fields/Types";
-import { Doc, Field } from "../../../new_fields/Doc";
+import { NumCast, Cast, FieldValue, StrCast } from "../../../new_fields/Types";
+import { Doc, Field, FieldResult } from "../../../new_fields/Doc";
 import { ComputedField } from "../../../new_fields/ScriptField";
+import { SetupDrag } from "../../util/DragManager";
+import { Docs } from "../../documents/Documents";
+import { RawDataOperationParameters } from "../../northstar/model/idea/idea";
+import { Templates } from "../Templates";
+import { List } from "../../../new_fields/List";
+import { TextField } from "../../util/ProsemirrorCopy/prompt";
+import { RichTextField } from "../../../new_fields/RichTextField";
+import { ImageField } from "../../../new_fields/URLField";
 
 @observer
 export class KeyValueBox extends React.Component<FieldViewProps> {
     private _mainCont = React.createRef<HTMLDivElement>();
+    private _keyHeader = React.createRef<HTMLTableHeaderCellElement>();
+    @observable private rows: KeyValuePair[] = [];
 
     public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(KeyValueBox, fieldStr); }
     @observable private _keyInput: string = "";
@@ -90,7 +100,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         let rows: JSX.Element[] = [];
         let i = 0;
         for (let key of Object.keys(ids).sort()) {
-            rows.push(<KeyValuePair doc={realDoc} keyWidth={100 - this.splitPercentage} rowStyle={"keyValueBox-" + (i++ % 2 ? "oddRow" : "evenRow")} key={key} keyName={key} />);
+            rows.push(<KeyValuePair doc={realDoc} ref={(el) => { if (el) this.rows.push(el); }} keyWidth={100 - this.splitPercentage} rowStyle={"keyValueBox-" + (i++ % 2 ? "oddRow" : "evenRow")} key={key} keyName={key} />);
         }
         return rows;
     }
@@ -134,6 +144,58 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         document.addEventListener('pointerup', this.onDividerUp);
     }
 
+    getTemplate = async () => {
+        let parent = Docs.FreeformDocument([], { width: 800, height: 800, title: "Template" });
+        for (let row of this.rows.filter(row => row.isChecked)) {
+            await this.createTemplateField(parent, row);
+            row.uncheck();
+        }
+        return parent;
+    }
+
+    createTemplateField = async (parent: Doc, row: KeyValuePair) => {
+        let collectionKeyProp = `fieldKey={"data"}`;
+        let metaKey = row.props.keyName;
+        let metaKeyProp = `fieldKey={"${metaKey}"}`;
+
+        let sourceDoc = await Cast(this.props.Document.data, Doc);
+        if (!sourceDoc) {
+            return;
+        }
+        let target = this.inferType(sourceDoc[metaKey], metaKey);
+
+        let template = Doc.MakeAlias(target);
+        template.proto = parent;
+        template.title = metaKey;
+        template.nativeWidth = 300;
+        template.nativeHeight = 300;
+        template.embed = true;
+        template.isTemplate = true;
+        template.templates = new List<string>([Templates.TitleBar(metaKey)]);
+        if (target.backgroundLayout) {
+            let metaAnoKeyProp = `fieldKey={"${metaKey}"} fieldExt={"annotations"}`;
+            let collectionAnoKeyProp = `fieldKey={"annotations"}`;
+            template.layout = StrCast(target.layout).replace(collectionAnoKeyProp, metaAnoKeyProp);
+            template.backgroundLayout = StrCast(target.backgroundLayout).replace(collectionKeyProp, metaKeyProp);
+        } else {
+            template.layout = StrCast(target.layout).replace(collectionKeyProp, metaKeyProp);
+        }
+        Doc.AddDocToList(parent, "data", template);
+        row.uncheck();
+    }
+
+    inferType = (field: FieldResult, metaKey: string) => {
+        let options = { width: 300, height: 300, title: metaKey };
+        if (field instanceof RichTextField || typeof field === "string" || typeof field === "number") {
+            return Docs.TextDocument(options);
+        } else if (field instanceof List) {
+            return Docs.FreeformDocument([], options);
+        } else if (field instanceof ImageField) {
+            return Docs.ImageDocument("https://www.freepik.com/free-icon/picture-frame-with-mountain-image_748687.htm", options);
+        }
+        return new Doc;
+    }
+
     render() {
         let dividerDragger = this.splitPercentage === 0 ? (null) :
             <div className="keyValueBox-dividerDragger" style={{ transform: `translate(calc(${100 - this.splitPercentage}% - 5px), 0px)` }}>
@@ -144,7 +206,9 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
             <table className="keyValueBox-table">
                 <tbody className="keyValueBox-tbody">
                     <tr className="keyValueBox-header">
-                        <th className="keyValueBox-key" style={{ width: `${100 - this.splitPercentage}%` }}>Key</th>
+                        <th className="keyValueBox-key" style={{ width: `${100 - this.splitPercentage}%` }} ref={this._keyHeader}
+                            onPointerDown={SetupDrag(this._keyHeader, this.getTemplate)}
+                        >Key</th>
                         <th className="keyValueBox-fields" style={{ width: `${this.splitPercentage}%` }}>Fields</th>
                     </tr>
                     {this.createTable()}
-- 
cgit v1.2.3-70-g09d2

