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 --- .../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 +- 4 files changed, 217 insertions(+), 58 deletions(-) delete mode 100644 src/client/util/Import & Export/DirectoryImportBox.scss create mode 100644 src/client/util/Import & Export/KeyValue.tsx (limited to 'src') 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 -