From aedd283fb9f9eff4145e27658bc6647982256032 Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Fri, 5 Jul 2019 00:34:19 -0400
Subject: beginning implementation of key value tags for all imported documents
---
.../util/Import & Export/DirectoryImportBox.tsx | 181 +++++++++++++++++++++
1 file changed, 181 insertions(+)
create mode 100644 src/client/util/Import & Export/DirectoryImportBox.tsx
(limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
new file mode 100644
index 000000000..2d77f6ae6
--- /dev/null
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -0,0 +1,181 @@
+import "fs";
+import React = require("react");
+import { Doc } from "../../../new_fields/Doc";
+import { DocServer } from "../../DocServer";
+import { RouteStore } from "../../../server/RouteStore";
+import { action, observable, runInAction } from "mobx";
+import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
+import Measure, { ContentRect } from "react-measure";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faArrowUp, faTag, faFileExcel } from '@fortawesome/free-solid-svg-icons';
+import { Docs, DocumentOptions } from "../../documents/Documents";
+import { EditableView } from "../../views/EditableView";
+
+export default class DirectoryImportBox extends React.Component {
+ private selector = React.createRef();
+ @observable private top = 0;
+ @observable private left = 0;
+ private dimensions = 50;
+
+ @observable private key = "Key";
+ @observable private value = "Value";
+
+ public static LayoutString() { return FieldView.LayoutString(DirectoryImportBox); }
+
+ constructor(props: FieldViewProps) {
+ super(props);
+ library.add(faArrowUp, faTag);
+ }
+
+ updateKey = (newKey: string) => {
+ runInAction(() => this.key = newKey);
+ console.log("KEY ", this.key);
+ return true;
+ }
+
+ updateValue = (newValue: string) => {
+ runInAction(() => this.value = newValue);
+ console.log("VALUE ", this.value);
+ return true;
+ }
+
+ handleSelection = async (e: React.ChangeEvent) => {
+ let promises: Promise[] = [];
+ let docs: Doc[] = [];
+
+ let files = e.target.files;
+ if (!files || files.length === 0) return;
+
+ let directory = (files.item(0) as any).webkitRelativePath.split("/", 1);
+
+ for (let i = 0; i < files.length; i++) {
+ let uploaded_file = files.item(i);
+
+ if (!uploaded_file) {
+ continue;
+ }
+
+ let formData = new FormData();
+ formData.append('file', uploaded_file);
+ let dropFileName = uploaded_file ? uploaded_file.name : "-empty-";
+ let type = uploaded_file.type;
+
+ let prom = fetch(DocServer.prepend(RouteStore.upload), {
+ method: 'POST',
+ body: formData
+ }).then(async (res: Response) => {
+ (await res.json()).map(action((file: any) => {
+ let path = DocServer.prepend(file);
+ console.log(path);
+ let docPromise = Docs.getDocumentFromType(type, path, { nativeWidth: 300, width: 300, title: dropFileName });
+ docPromise.then(doc => doc && docs.push(doc));
+ }));
+ });
+ promises.push(prom);
+ }
+
+ await Promise.all(promises);
+
+ let doc = this.props.Document;
+ let options: DocumentOptions = { title: `Import of ${directory}`, width: 500, height: 500, x: Doc.GetT(doc, "x", "number"), y: Doc.GetT(doc, "y", "number") };
+ let parent = this.props.ContainingCollectionView;
+ if (parent) {
+ let importContainer = Docs.StackingDocument(docs, options);
+ Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer);
+ this.props.removeDocument && this.props.removeDocument(doc);
+ }
+ }
+
+ componentDidMount() {
+ this.selector.current!.setAttribute("directory", "");
+ this.selector.current!.setAttribute("webkitdirectory", "");
+ }
+
+ @action
+ preserveCentering = (rect: ContentRect) => {
+ let bounds = rect.offset!;
+ if (bounds.width === 0 || bounds.height === 0) {
+ return;
+ }
+ let offset = this.dimensions / 2;
+ this.left = bounds.width / 2 - offset;
+ this.top = bounds.height / 2 - offset;
+ }
+
+ render() {
+ let dimensions = 50;
+ let keyValueStyle = { paddingLeft: 5, width: "50%" };
+ return (
+
+ {({ measureRef }) =>
+
+
+
+
+
+
+
+
+
+ this.key}
+ oneLine={true}
+ />
+
+
+ this.value}
+ oneLine={true}
+ />
+
+
+
+ }
+
+ );
+ }
+
+}
\ No newline at end of file
--
cgit v1.2.3-70-g09d2
From 12788cbe0586d0349f70b73d1b6f6a481b4bf2cf Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Fri, 5 Jul 2019 17:31:20 -0400
Subject: first pass at implementation of directory import
---
deploy/assets/loading.gif | Bin 0 -> 114208 bytes
.../util/Import & Export/DirectoryImportBox.scss | 0
.../util/Import & Export/DirectoryImportBox.tsx | 194 +++++++++++++++------
src/client/util/Import & Export/KeyValue.tsx | 79 +++++++++
src/client/views/MainView.tsx | 2 +-
5 files changed, 217 insertions(+), 58 deletions(-)
create mode 100644 deploy/assets/loading.gif
delete mode 100644 src/client/util/Import & Export/DirectoryImportBox.scss
create mode 100644 src/client/util/Import & Export/KeyValue.tsx
(limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
diff --git a/deploy/assets/loading.gif b/deploy/assets/loading.gif
new file mode 100644
index 000000000..0652bf021
Binary files /dev/null and b/deploy/assets/loading.gif differ
diff --git a/src/client/util/Import & Export/DirectoryImportBox.scss b/src/client/util/Import & Export/DirectoryImportBox.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 2d77f6ae6..cbc8c6fdc 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -3,44 +3,46 @@ import React = require("react");
import { Doc } from "../../../new_fields/Doc";
import { DocServer } from "../../DocServer";
import { RouteStore } from "../../../server/RouteStore";
-import { action, observable, runInAction } from "mobx";
+import { action, observable, autorun, runInAction } from "mobx";
import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
import Measure, { ContentRect } from "react-measure";
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faArrowUp, faTag, faFileExcel } from '@fortawesome/free-solid-svg-icons';
+import { faArrowUp, faTag, faPlus } from '@fortawesome/free-solid-svg-icons';
import { Docs, DocumentOptions } from "../../documents/Documents";
-import { EditableView } from "../../views/EditableView";
+import { observer } from "mobx-react";
+import KeyValue from "./KeyValue";
+import { Utils } from "../../../Utils";
+import { doesNotReject } from "assert";
+import { remove } from "typescript-collections/dist/lib/arrays";
+@observer
export default class DirectoryImportBox extends React.Component {
private selector = React.createRef();
@observable private top = 0;
@observable private left = 0;
private dimensions = 50;
- @observable private key = "Key";
- @observable private value = "Value";
+ @observable private editingMetadata = false;
+ @observable private metadata_guids: string[] = [];
+ @observable private entries: KeyValue[] = [];
+
+ @observable private quota = 1;
+ @observable private remaining = 1;
+
+ @observable private uploadBegun = false;
public static LayoutString() { return FieldView.LayoutString(DirectoryImportBox); }
constructor(props: FieldViewProps) {
super(props);
- library.add(faArrowUp, faTag);
- }
-
- updateKey = (newKey: string) => {
- runInAction(() => this.key = newKey);
- console.log("KEY ", this.key);
- return true;
- }
-
- updateValue = (newValue: string) => {
- runInAction(() => this.value = newValue);
- console.log("VALUE ", this.value);
- return true;
+ library.add(faArrowUp, faTag, faPlus);
}
+ @action
handleSelection = async (e: React.ChangeEvent) => {
+ this.uploadBegun = true;
+
let promises: Promise[] = [];
let docs: Doc[] = [];
@@ -49,9 +51,15 @@ export default class DirectoryImportBox extends React.Component
let directory = (files.item(0) as any).webkitRelativePath.split("/", 1);
+ let validated: File[] = [];
for (let i = 0; i < files.length; i++) {
- let uploaded_file = files.item(i);
+ let file = files.item(i);
+ file && validated.push(file);
+ }
+
+ this.quota = validated.length;
+ for (let uploaded_file of validated) {
if (!uploaded_file) {
continue;
}
@@ -61,15 +69,18 @@ export default class DirectoryImportBox extends React.Component
let dropFileName = uploaded_file ? uploaded_file.name : "-empty-";
let type = uploaded_file.type;
+ this.remaining++;
+
let prom = fetch(DocServer.prepend(RouteStore.upload), {
method: 'POST',
body: formData
}).then(async (res: Response) => {
(await res.json()).map(action((file: any) => {
let path = DocServer.prepend(file);
- console.log(path);
let docPromise = Docs.getDocumentFromType(type, path, { nativeWidth: 300, width: 300, title: dropFileName });
- docPromise.then(doc => doc && docs.push(doc));
+ docPromise.then(doc => {
+ doc && docs.push(doc) && runInAction(() => this.remaining--);
+ });
}));
});
promises.push(prom);
@@ -77,11 +88,14 @@ export default class DirectoryImportBox extends React.Component
await Promise.all(promises);
+ docs.forEach(doc => this.entries.forEach(entry => doc[entry.key] = entry.value));
+
let doc = this.props.Document;
let options: DocumentOptions = { title: `Import of ${directory}`, width: 500, height: 500, x: Doc.GetT(doc, "x", "number"), y: Doc.GetT(doc, "y", "number") };
let parent = this.props.ContainingCollectionView;
if (parent) {
let importContainer = Docs.StackingDocument(docs, options);
+ importContainer.singleColumn = false;
Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer);
this.props.removeDocument && this.props.removeDocument(doc);
}
@@ -103,9 +117,29 @@ export default class DirectoryImportBox extends React.Component
this.top = bounds.height / 2 - offset;
}
+ @action
+ addMetadataEntry = () => {
+ this.metadata_guids.push(Utils.GenerateGuid());
+ }
+
+ @action
+ remove = (entry: KeyValue) => {
+ let index = this.entries.indexOf(entry);
+ let key = entry.key;
+ this.entries.splice(index, 1);
+ this.metadata_guids.splice(this.metadata_guids.indexOf(key), 1);
+ }
+
render() {
let dimensions = 50;
- let keyValueStyle = { paddingLeft: 5, width: "50%" };
+ let guids = this.metadata_guids.map(el => el);
+ let isEditing = this.editingMetadata;
+ let remaining = this.remaining;
+ let quota = this.quota;
+ let percent = `${100 - (remaining / quota * 100)}`;
+ let uploadBegun = this.uploadBegun;
+ percent = percent.split(".")[0];
+ percent = percent.startsWith("100") ? "99" : percent;
return (
{({ measureRef }) =>
@@ -113,14 +147,20 @@ export default class DirectoryImportBox extends React.Component
-
+ }}>Template will be {persistent ? "kept" : "removed"} after upload
{percent}%
borderRadius: "50%",
width: 25,
height: 25,
- background: "black"
+ background: "black",
+ pointerEvents: uploading ? "none" : "all",
+ opacity: uploading ? 0 : 1,
+ transition: "0.4s opacity ease"
}}
title={isEditing ? "Back to Upload" : "Add Metadata"}
onClick={action(() => this.editingMetadata = !this.editingMetadata)}
@@ -263,7 +307,9 @@ export default class DirectoryImportBox extends React.Component
pointerEvents: "none",
position: "absolute",
right: isEditing ? 16.3 : 14.5,
- top: isEditing ? 15.4 : 16
+ top: isEditing ? 15.4 : 16,
+ opacity: uploading ? 0 : 1,
+ transition: "0.4s opacity ease"
}}
icon={isEditing ? faArrowUp : faTag}
color="#FFFFFF"
@@ -304,9 +350,10 @@ export default class DirectoryImportBox extends React.Component
Add metadata to your import...
- {guids.map(guid =>
+ {entries.map(doc =>
{ if (el) this.entries.push(el); }}
next={this.addMetadataEntry}
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index 3b2a6ebb5..f5198c39b 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx
@@ -5,20 +5,20 @@ import { observable, action, computed } from "mobx";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { library } from '@fortawesome/fontawesome-svg-core';
-import { Opt } from "../../../new_fields/Doc";
+import { Opt, Doc } from "../../../new_fields/Doc";
+import { StrCast, BoolCast } from "../../../new_fields/Types";
interface KeyValueProps {
+ Document: Doc;
remove: (self: ImportMetadataEntry) => void;
next: () => void;
}
-const keyPlaceholder = "Key";
-const valuePlaceholder = "Value";
+export const keyPlaceholder = "Key";
+export const valuePlaceholder = "Value";
@observer
export default class ImportMetadataEntry extends React.Component {
- @observable public key = keyPlaceholder;
- @observable public value = valuePlaceholder;
private keyRef = React.createRef();
private valueRef = React.createRef();
@@ -34,8 +34,36 @@ export default class ImportMetadataEntry extends React.Component
return (this.key.length > 0 && this.key !== keyPlaceholder) && (this.value.length > 0 && this.value !== valuePlaceholder);
}
+ @computed
+ private get backing() {
+ return this.props.Document;
+ }
+
+ @computed
public get onDataDoc() {
- return this.checkRef.current && this.checkRef.current.checked;
+ return BoolCast(this.backing.checked);
+ }
+
+ public set onDataDoc(value: boolean) {
+ this.backing.checked = value;
+ }
+
+ @computed
+ public get key() {
+ return StrCast(this.backing.key);
+ }
+
+ public set key(value: string) {
+ this.backing.key = value;
+ }
+
+ @computed
+ public get value() {
+ return StrCast(this.backing.value);
+ }
+
+ public set value(value: string) {
+ this.backing.value = value;
}
@action
@@ -75,10 +103,12 @@ export default class ImportMetadataEntry extends React.Component
}}
>
this.onDataDoc = e.target.checked}
ref={this.checkRef}
style={{ margin: "0 10px 0 15px" }}
type="checkbox"
title={"Add to Data Document?"}
+ checked={this.onDataDoc}
/>
, document.getElementById('root'));
-})();
+})();
\ No newline at end of file
--
cgit v1.2.3-70-g09d2
From a1bbdbbcfb9ad704c42fae48bfe88a720803f756 Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Sat, 6 Jul 2019 12:03:25 -0400
Subject: added embedding of size and modified time
---
.../util/Import & Export/DirectoryImportBox.tsx | 23 +++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
(limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index b75944745..093cee168 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -19,6 +19,8 @@ import { List } from "../../../new_fields/List";
import { Cast, BoolCast, NumCast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
+const unsupported = ["text/html", "text/plain"];
+
@observer
export default class DirectoryImportBox extends React.Component {
private selector = React.createRef();
@@ -77,21 +79,24 @@ export default class DirectoryImportBox extends React.Component
let validated: File[] = [];
for (let i = 0; i < files.length; i++) {
let file = files.item(i);
- file && validated.push(file);
+ console.log(file);
+ file && !unsupported.includes(file.type) && validated.push(file);
}
runInAction(() => this.quota = validated.length);
- for (let uploaded_file of validated) {
- if (!uploaded_file) {
- continue;
- }
+ let sizes = [];
+ let modifiedDates = [];
+ for (let uploaded_file of validated) {
let formData = new FormData();
formData.append('file', uploaded_file);
let dropFileName = uploaded_file ? uploaded_file.name : "-empty-";
let type = uploaded_file.type;
+ sizes.push(uploaded_file.size);
+ modifiedDates.push(uploaded_file.lastModified);
+
runInAction(() => this.remaining++);
let prom = fetch(DocServer.prepend(RouteStore.upload), {
@@ -99,6 +104,7 @@ export default class DirectoryImportBox extends React.Component
body: formData
}).then(async (res: Response) => {
(await res.json()).map(action((file: any) => {
+ console.log(file);
let docPromise = Docs.getDocumentFromType(type, DocServer.prepend(file), { nativeWidth: 300, width: 300, title: dropFileName });
docPromise.then(doc => {
doc && docs.push(doc) && runInAction(() => this.remaining--);
@@ -110,12 +116,15 @@ export default class DirectoryImportBox extends React.Component
await Promise.all(promises);
- docs.forEach(doc => {
+ for (let i = 0; i < docs.length; i++) {
+ let doc = docs[i];
+ doc.size = sizes[i];
+ doc.modified = modifiedDates[i];
this.entries.forEach(entry => {
let target = entry.onDataDoc ? Doc.GetProto(doc) : doc;
target[entry.key] = entry.value;
});
- });
+ }
let doc = this.props.Document;
let height: number = NumCast(doc.height) || 0;
--
cgit v1.2.3-70-g09d2
From 5ce2d59b4544a7473a910c121daf0c34d1546214 Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Sat, 6 Jul 2019 12:20:58 -0400
Subject: removed console.log
---
src/client/util/Import & Export/DirectoryImportBox.tsx | 1 -
1 file changed, 1 deletion(-)
(limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 093cee168..1a939882c 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -104,7 +104,6 @@ export default class DirectoryImportBox extends React.Component
body: formData
}).then(async (res: Response) => {
(await res.json()).map(action((file: any) => {
- console.log(file);
let docPromise = Docs.getDocumentFromType(type, DocServer.prepend(file), { nativeWidth: 300, width: 300, title: dropFileName });
docPromise.then(doc => {
doc && docs.push(doc) && runInAction(() => this.remaining--);
--
cgit v1.2.3-70-g09d2
From 04887c8a578147015421d3909bd100c82ac5e31d Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Mon, 8 Jul 2019 19:55:15 -0400
Subject: fixed readonly and hopefully cursor proto bugs
---
src/client/DocServer.ts | 4 +-
.../util/Import & Export/DirectoryImportBox.tsx | 1 -
src/client/views/collections/CollectionSubView.tsx | 9 ++-
src/client/views/nodes/KeyValueBox.tsx | 81 +++++++++++++++-------
4 files changed, 66 insertions(+), 29 deletions(-)
(limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index cbcf751ee..652a9b701 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -12,7 +12,9 @@ export namespace DocServer {
const GUID: string = Utils.GenerateGuid();
export function makeReadOnly() {
- _CreateField = emptyFunction;
+ _CreateField = field => {
+ _cache[field[Id]] = field;
+ };
_UpdateField = emptyFunction;
_respondToUpdate = emptyFunction;
}
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 1a939882c..ce95ba90e 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -79,7 +79,6 @@ export default class DirectoryImportBox extends React.Component
let validated: File[] = [];
for (let i = 0; i < files.length; i++) {
let file = files.item(i);
- console.log(file);
file && !unsupported.includes(file.type) && validated.push(file);
}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index bf17088ae..a8810f336 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -19,6 +19,7 @@ import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
import { CollectionView } from "./CollectionView";
import React = require("react");
+import { MainView } from "../MainView";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -67,10 +68,16 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) {
let email = CurrentUserUtils.email;
let pos = { x: position[0], y: position[1] };
if (id && email) {
- const proto = await doc.proto;
+ const proto = Doc.GetProto(doc);
if (!proto) {
return;
}
+ if (proto[Id] === "collectionProto") {
+ alert("COLLECTION PROTO CURSOR ISSUE DETECTED! Check console for more info...");
+ console.log(doc);
+ console.log(proto);
+ throw new Error(`AHA! You were trying to set a cursor on a collection's proto, which is the original collection proto! Look at the two previously printed lines for document values!`);
+ }
let cursors = Cast(proto.cursors, listSpec(CursorField));
if (!cursors) {
proto.cursors = cursors = new List();
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 9407d742c..fbabe224e 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -18,6 +18,7 @@ import { List } from "../../../new_fields/List";
import { TextField } from "../../util/ProsemirrorCopy/prompt";
import { RichTextField } from "../../../new_fields/RichTextField";
import { ImageField } from "../../../new_fields/URLField";
+import { SelectionManager } from "../../util/SelectionManager";
@observer
export class KeyValueBox extends React.Component {
@@ -167,44 +168,72 @@ export class KeyValueBox extends React.Component {
return parent;
}
- createTemplateField = async (parent: Doc, row: KeyValuePair) => {
- let collectionKeyProp = `fieldKey={"data"}`;
- let metaKey = row.props.keyName;
- let metaKeyProp = `fieldKey={"${metaKey}"}`;
+ createTemplateField = async (parentStackingDoc: 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 = 0;
+ // template.nativeHeight = 0;
+ // template.embed = true;
+ // template.isTemplate = true;
+ // template.templates = new List([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);
+ // }
+
+ let metaKey = row.props.keyName;
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 = 0;
- template.nativeHeight = 0;
- template.embed = true;
- template.isTemplate = true;
- template.templates = new List([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);
+ let fieldTemplate = this.inferType(sourceDoc[metaKey], metaKey);
+
+ // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??)
+ let backgroundLayout = StrCast(fieldTemplate.backgroundLayout);
+ let layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
+ if (backgroundLayout) {
+ layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"annotations"}/, `fieldKey={"${metaKey}"} fieldExt={"annotations"}`);
+ backgroundLayout = backgroundLayout.replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
}
- Doc.AddDocToList(parent, "data", template);
+ let nw = NumCast(fieldTemplate.nativeWidth);
+ let nh = NumCast(fieldTemplate.nativeHeight);
+
+ fieldTemplate.title = metaKey;
+ fieldTemplate.layout = layout;
+ fieldTemplate.backgroundLayout = backgroundLayout;
+ fieldTemplate.nativeWidth = nw;
+ fieldTemplate.nativeHeight = nh;
+ fieldTemplate.embed = true;
+ fieldTemplate.isTemplate = true;
+ fieldTemplate.templates = new List([Templates.TitleBar(metaKey)]);
+ fieldTemplate.proto = Doc.GetProto(parentStackingDoc);
+
+ Doc.AddDocToList(parentStackingDoc, "data", fieldTemplate);
row.uncheck();
}
- inferType = (field: FieldResult, metaKey: string) => {
+ inferType = (data: FieldResult, metaKey: string) => {
let options = { width: 300, height: 300, title: metaKey };
- if (field instanceof RichTextField || typeof field === "string" || typeof field === "number") {
+ if (data instanceof RichTextField || typeof data === "string" || typeof data === "number") {
return Docs.TextDocument(options);
- } else if (field instanceof List) {
+ } else if (data instanceof List) {
return Docs.StackingDocument([], options);
- } else if (field instanceof ImageField) {
+ } else if (data instanceof ImageField) {
return Docs.ImageDocument("https://www.freepik.com/free-icon/picture-frame-with-mountain-image_748687.htm", options);
}
return new Doc;
--
cgit v1.2.3-70-g09d2