aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/KeyValueBox.scss6
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx72
-rw-r--r--src/client/views/nodes/KeyValuePair.scss39
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx62
-rw-r--r--src/scraping/buxton/scraper.py8
5 files changed, 153 insertions, 34 deletions
diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss
index 20cae03d4..87a9565e8 100644
--- a/src/client/views/nodes/KeyValueBox.scss
+++ b/src/client/views/nodes/KeyValueBox.scss
@@ -91,12 +91,12 @@ $header-height: 30px;
width: 4px;
float: left;
height: 30px;
- width: 10px;
+ width: 5px;
z-index: 20;
right: 0;
top: 0;
- border-radius: 10px;
- background: gray;
+ border-radius: 0;
+ background: black;
pointer-events: all;
}
.keyValueBox-dividerDragger{
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()}
diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss
index a1c5d5537..f78767234 100644
--- a/src/client/views/nodes/KeyValuePair.scss
+++ b/src/client/views/nodes/KeyValuePair.scss
@@ -3,6 +3,7 @@
.keyValuePair-td-key {
display:inline-block;
+
.keyValuePair-td-key-container{
width:100%;
height:100%;
@@ -10,14 +11,23 @@
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
+ align-items: center;
.keyValuePair-td-key-delete{
position: relative;
background-color: transparent;
color:red;
}
+ .keyValuePair-td-key-check {
+ position: relative;
+ margin: 0;
+ }
.keyValuePair-keyField {
width:100%;
- text-align: center;
+ margin-left: 20px;
+ margin-top: -1px;
+ font-family: monospace;
+ // text-align: center;
+ align-self: center;
position: relative;
overflow: auto;
}
@@ -26,12 +36,25 @@
.keyValuePair-td-value {
display:inline-block;
overflow: scroll;
- img {
- max-height: 36px;
- width: auto;
- }
- .videoBox-cont{
- width: auto;
- max-height: 36px;
+ font-family: monospace;
+ height: 30px;
+ .keyValuePair-td-value-container {
+ display: flex;
+ align-items: center;
+ align-content: center;
+ flex-direction: row;
+ justify-content: space-between;
+ flex-wrap: nowrap;
+ width: 100%;
+ height: 100%;
+
+ img {
+ max-height: 36px;
+ width: auto;
+ }
+ .videoBox-cont{
+ width: auto;
+ max-height: 36px;
+ }
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index ede4e3858..b5db52ac7 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -12,6 +12,7 @@ import React = require("react");
import { Doc, Opt, Field } from '../../../new_fields/Doc';
import { FieldValue } from '../../../new_fields/Types';
import { KeyValueBox } from './KeyValueBox';
+import { DragManager, SetupDrag } from '../../util/DragManager';
// Represents one row in a key value plane
@@ -23,6 +24,20 @@ export interface KeyValuePairProps {
}
@observer
export class KeyValuePair extends React.Component<KeyValuePairProps> {
+ @observable private isPointerOver = false;
+ @observable public isChecked = false;
+ private checkbox = React.createRef<HTMLInputElement>();
+
+ @action
+ handleCheck = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.isChecked = e.currentTarget.checked;
+ }
+
+ @action
+ uncheck = () => {
+ this.checkbox.current!.checked = false;
+ this.isChecked = false;
+ }
render() {
let props: FieldViewProps = {
@@ -44,12 +59,16 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
addDocTab: returnZero,
};
let contents = <FieldView {...props} />;
- let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")";
+ // let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")";
+ let keyStyle = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? "black" : "blue";
+
+ let hover = { transition: "0.3s ease opacity", opacity: this.isPointerOver || this.isChecked ? 1 : 0 };
+
return (
- <tr className={this.props.rowStyle}>
+ <tr className={this.props.rowStyle} onPointerEnter={action(() => this.isPointerOver = true)} onPointerLeave={action(() => this.isPointerOver = false)}>
<td className="keyValuePair-td-key" style={{ width: `${this.props.keyWidth}%` }}>
<div className="keyValuePair-td-key-container">
- <button className="keyValuePair-td-key-delete" onClick={() => {
+ <button style={hover} className="keyValuePair-td-key-delete" onClick={() => {
if (Object.keys(props.Document).indexOf(props.fieldKey) !== -1) {
props.Document[props.fieldKey] = undefined;
}
@@ -57,22 +76,35 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
}}>
X
</button>
- <div className="keyValuePair-keyField">{fieldKey}</div>
+ <input
+ className={"keyValuePair-td-key-check"}
+ type="checkbox"
+ style={hover}
+ onChange={this.handleCheck}
+ ref={this.checkbox}
+ />
+ <div className="keyValuePair-keyField" style={{ color: keyStyle }}>{props.fieldKey}</div>
</div>
</td>
<td className="keyValuePair-td-value" style={{ width: `${100 - this.props.keyWidth}%` }}>
- <EditableView contents={contents} height={36} GetValue={() => {
- const onDelegate = Object.keys(props.Document).includes(props.fieldKey);
+ <div className="keyValuePair-td-value-container">
+ <EditableView
+ contents={contents}
+ height={36}
+ GetValue={() => {
+ const onDelegate = Object.keys(props.Document).includes(props.fieldKey);
- let field = FieldValue(props.Document[props.fieldKey]);
- if (Field.IsField(field)) {
- return (onDelegate ? "=" : "") + Field.toScriptString(field);
- }
- return "";
- }}
- SetValue={(value: string) =>
- KeyValueBox.SetField(props.Document, props.fieldKey, value)}>
- </EditableView></td>
+ let field = FieldValue(props.Document[props.fieldKey]);
+ if (Field.IsField(field)) {
+ return (onDelegate ? "=" : "") + Field.toScriptString(field);
+ }
+ return "";
+ }}
+ SetValue={(value: string) =>
+ KeyValueBox.SetField(props.Document, props.fieldKey, value)}>
+ </EditableView>
+ </div>
+ </td>
</tr>
);
}
diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py
index 97af10519..fcffeac13 100644
--- a/src/scraping/buxton/scraper.py
+++ b/src/scraping/buxton/scraper.py
@@ -60,7 +60,7 @@ def protofy(fieldId):
}
-def write_schema(parse_results, display_fields):
+def write_schema(parse_results, display_fields, storage_key):
view_guids = parse_results["child_guids"]
data_doc = parse_results["schema"]
@@ -87,7 +87,7 @@ def write_schema(parse_results, display_fields):
}
fields["proto"] = protofy("collectionProto")
- fields["data"] = listify(proxify_guids(view_guids))
+ fields[storage_key] = listify(proxify_guids(view_guids))
fields["schemaColumns"] = listify(display_fields)
fields["backgroundColor"] = "white"
fields["scale"] = 0.5
@@ -304,7 +304,7 @@ for file_name in os.listdir(source):
if file_name.endswith('.docx'):
candidates += 1
schema_guids.append(write_schema(
- parse_document(file_name), ["title", "data"]))
+ parse_document(file_name), ["title", "data"], "image_data"))
print("writing parent schema...")
parent_guid = write_schema({
@@ -314,7 +314,7 @@ parent_guid = write_schema({
"__type": "Doc"
},
"child_guids": schema_guids
-}, ["title", "short_description", "original_price"])
+}, ["title", "short_description", "original_price"], "data")
print("appending parent schema to main workspace...\n")
db.newDocuments.update_one(