From d53ad748d90ca1c863a7ef52d0835573ce967a54 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sat, 27 Jul 2019 16:49:07 -0400 Subject: init --- src/client/util/TooltipTextMenu.tsx | 6 +++++- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 30 ++++++++++++++++++++++++++++- src/client/views/nodes/PDFBox.tsx | 14 ++++++++++++++ src/client/views/pdf/Page.tsx | 11 ++++++++--- 5 files changed, 57 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index a4c053de2..6214b568c 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -1,6 +1,6 @@ import { action } from "mobx"; import { Dropdown, MenuItem, icons, } from "prosemirror-menu"; //no import css -import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; +import { EditorState, NodeSelection, TextSelection, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { schema } from "./RichTextSchema"; import { Schema, NodeType, MarkType, Mark, ResolvedPos } from "prosemirror-model"; @@ -321,6 +321,10 @@ export class TooltipTextMenu { } } + makeLinkWithState = (state: EditorState, target: string, location: string) => { + let link = state.schema.mark(state.schema.marks.link, { href: target, location: location }); + } + makeLink = (target: string, location: string) => { let node = this.view.state.selection.$from.nodeAfter; let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location }); diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 7477c5b4f..6c80c7645 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -151,9 +151,9 @@ export default class KeyManager { stopPropagation = false; break; case "a": - case "c": case "v": case "x": + case "c": stopPropagation = false; preventDefault = false; break; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 0a79677e2..cf913a4c7 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -6,7 +6,7 @@ import { baseKeymap } from "prosemirror-commands"; import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { NodeType } from 'prosemirror-model'; -import { EditorState, Plugin, Transaction } from "prosemirror-state"; +import { EditorState, Plugin, Transaction, Selection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc, Opt } from "../../../new_fields/Doc"; import { Id, Copy } from '../../../new_fields/FieldSymbols'; @@ -123,12 +123,40 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this.props.isOverlay) { DragManager.StartDragFunctions.push(() => FormattedTextBox.InputBoxOverlay = undefined); } + + document.addEventListener("paste", this.paste); } @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); } @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : Doc.GetProto(this.props.Document); } + paste = (e: ClipboardEvent) => { + if (e.clipboardData && this._editorView) { + let pdfPasteText = `${Utils.GenerateDeterministicGuid("pdf paste")}`; + for (let i = 0; i < e.clipboardData.items.length; i++) { + let item = e.clipboardData.items.item(i); + if (item.type === "text/plain") { + item.getAsString((text) => { + let pdfPasteIndex = text.indexOf(pdfPasteText); + if (pdfPasteIndex > -1) { + let insertText = text.substr(0, pdfPasteIndex); + const tx = this._editorView!.state.tr.insertText(insertText); + // tx.setSelection(new Selection(tx.)) + const state = this._editorView!.state; + this._editorView!.dispatch(tx); + if (this._toolTipTextMenu) { + // this._toolTipTextMenu.makeLinkWithState(state) + } + e.stopPropagation(); + e.preventDefault(); + } + }); + } + } + } + } + dispatchTransaction = (tx: Transaction) => { if (this._editorView) { const state = this._editorView.state.apply(tx); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 5a5e6e6dd..282312dca 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -24,6 +24,8 @@ import { Flyout, anchorPoints } from '../DocumentDecorations'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ScriptField } from '../../../new_fields/ScriptField'; import { KeyCodes } from '../../northstar/utils/KeyCodes'; +import { Utils } from '../../../Utils'; +import { Id } from '../../../new_fields/FieldSymbols'; type PdfDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; const PdfDocument = makeInterface(positionSchema, pageSchema); @@ -32,6 +34,7 @@ export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === K @observer export class PDFBox extends DocComponent(PdfDocument) { public static LayoutString() { return FieldView.LayoutString(PDFBox); } + public selectionText: string = ""; @observable private _alt = false; @observable private _scrollY: number = 0; @@ -63,6 +66,8 @@ export class PDFBox extends DocComponent(PdfDocumen this._keyRef = React.createRef(); this._valueRef = React.createRef(); this._scriptRef = React.createRef(); + + document.addEventListener("keydown", this.onKeyDown); } componentDidMount() { @@ -73,6 +78,14 @@ export class PDFBox extends DocComponent(PdfDocumen this._reactionDisposer && this._reactionDisposer(); } + onKeyDown = (e: KeyboardEvent) => { + if (e.ctrlKey && e.keyCode === KeyCodes.C) { + let text = this.selectionText; + text += `${Utils.GenerateDeterministicGuid("pdf paste")}/${this.props.Document[Id]}`; + navigator.clipboard.writeText(text); + } + } + public GetPage() { return Math.floor(NumCast(this.props.Document.scrollY) / NumCast(this.dataDoc.pdfHeight)) + 1; } @@ -241,6 +254,7 @@ export class PDFBox extends DocComponent(PdfDocumen let classname = "pdfBox-cont" + (this.props.active() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : ""); return (
{ else { let sel = window.getSelection(); if (sel && sel.type === "Range") { - this.createTextAnnotation(sel); + let selRange = sel.getRangeAt(0); + this.createTextAnnotation(sel, selRange); PDFMenu.Instance.jumpTo(e.clientX, e.clientY); } } @@ -375,8 +376,8 @@ export default class Page extends React.Component { } @action - createTextAnnotation = (sel: Selection) => { - let clientRects = sel.getRangeAt(0).getClientRects(); + createTextAnnotation = (sel: Selection, selRange: Range) => { + let clientRects = selRange.getClientRects(); if (this._textLayer.current) { let boundingRect = this._textLayer.current.getBoundingClientRect(); for (let i = 0; i < clientRects.length; i++) { @@ -393,6 +394,10 @@ export default class Page extends React.Component { } } } + let text = selRange.extractContents().textContent; + if (text) { + this.props.parent.selectionText = text; + } // clear selection if (sel.empty) { // Chrome sel.empty(); -- cgit v1.2.3-70-g09d2 From 92b848b79eaf90235fed550bc96b6ca982bd07df Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sat, 27 Jul 2019 21:23:12 -0400 Subject: asdfkjlsdafds --- src/client/documents/Documents.ts | 6 ++--- src/client/views/nodes/FormattedTextBox.tsx | 38 +++++++++++++++++++++++------ src/client/views/nodes/PDFBox.tsx | 18 ++++++++------ src/client/views/pdf/PDFViewer.tsx | 29 +++++++++++++++++++--- 4 files changed, 70 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e6fe1b8b3..ee1b9fd0d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -582,12 +582,12 @@ export namespace Docs { export namespace DocUtils { export function MakeLink(source: Doc, target: Doc, targetContext?: Doc, title: string = "", description: string = "", tags: string = "Default", sourceContext?: Doc) { - if (LinkManager.Instance.doesLinkExist(source, target)) return; + if (LinkManager.Instance.doesLinkExist(source, target)) return undefined; let sv = DocumentManager.Instance.getDocumentView(source); if (sv && sv.props.ContainingCollectionView && sv.props.ContainingCollectionView.props.Document === target) return; - if (target === CurrentUserUtils.UserDocument) return; + if (target === CurrentUserUtils.UserDocument) return undefined; - let linkDoc; + let linkDoc: Doc | undefined; UndoManager.RunInBatch(() => { linkDoc = Docs.Create.TextDocument({ width: 100, height: 30, borderRounding: "100%" }); linkDoc.type = DocumentType.LINK; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index e982cdfdd..364dc1c83 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -15,7 +15,7 @@ import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, listSpec, makeInterface } from "../../../new_fields/Schema"; import { BoolCast, Cast, NumCast, StrCast, DateCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; -import { Docs } from '../../documents/Documents'; +import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorExampleTransfer"; @@ -300,7 +300,34 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => { - return false; + let cbe = event as ClipboardEvent; + let docId: string; + if (!cbe.clipboardData) { + return false; + } + let linkId: string; + docId = cbe.clipboardData.getData("dash/pdfOrigin"); + if (!docId) { + return false; + } + + DocServer.GetRefField(docId).then(doc => { + if (!(doc instanceof Doc)) { + return; + } + let link = DocUtils.MakeLink(this.props.Document, doc); + if (link) { + cbe.clipboardData!.setData("dash/linkDoc", link[Id]); + linkId = link[Id]; + let frag = addMarkToFrag(slice.content); + slice = new Slice(frag, slice.openStart, slice.openEnd); + var tr = view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + } + }); + + return true; + function addMarkToFrag(frag: Fragment) { const nodes: Node[] = []; frag.forEach(node => nodes.push(addLinkMark(node))); @@ -313,7 +340,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type.name === "link"); - const link = view.state.schema.mark(view.state.schema.marks.link, { href: "http://localhost:1050/doc/[link document id]", location: "onRight" }); + const link = view.state.schema.mark(view.state.schema.marks.link, { href: `http://localhost:1050/doc/${linkId}`, location: "onRight" }); if (linkIndex !== -1) { marks.splice(linkIndex, 1, link); } else { @@ -321,11 +348,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } return node.mark(marks); } - let frag = addMarkToFrag(slice.content); - slice = new Slice(frag, slice.openStart, slice.openEnd); - var tr = view.state.tr.replaceSelection(slice); - view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); - return true; } private setupEditor(config: any, doc: Doc, fieldKey: string) { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 282312dca..72d835fce 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -66,23 +66,28 @@ export class PDFBox extends DocComponent(PdfDocumen this._keyRef = React.createRef(); this._valueRef = React.createRef(); this._scriptRef = React.createRef(); - - document.addEventListener("keydown", this.onKeyDown); } componentDidMount() { if (this.props.setPdfBox) this.props.setPdfBox(this); + + document.removeEventListener("copy", this.copy); + document.addEventListener("copy", this.copy); } componentWillUnmount() { this._reactionDisposer && this._reactionDisposer(); + document.removeEventListener("copy", this.copy); } - onKeyDown = (e: KeyboardEvent) => { - if (e.ctrlKey && e.keyCode === KeyCodes.C) { + private copy = (e: ClipboardEvent) => { + if (this.props.active()) { let text = this.selectionText; - text += `${Utils.GenerateDeterministicGuid("pdf paste")}/${this.props.Document[Id]}`; - navigator.clipboard.writeText(text); + if (e.clipboardData) { + e.clipboardData.setData("text/plain", text); + e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]); + e.preventDefault(); + } } } @@ -254,7 +259,6 @@ export class PDFBox extends DocComponent(PdfDocumen let classname = "pdfBox-cont" + (this.props.active() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : ""); return (
{ if (this._mainCont.current) { this._dropDisposer = this._mainCont.current && DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }); } + + document.removeEventListener("paste", this.paste); + document.addEventListener("paste", this.paste); } componentWillUnmount = () => { @@ -163,6 +167,25 @@ export class Viewer extends React.Component { this._annotationReactionDisposer && this._annotationReactionDisposer(); this._filterReactionDisposer && this._filterReactionDisposer(); this._dropDisposer && this._dropDisposer(); + document.removeEventListener("paste", this.paste); + } + + paste = (e: ClipboardEvent) => { + if (e.clipboardData) { + if (e.clipboardData.getData("dash/pdfOrigin") === this.props.parent.props.Document[Id]) { + let linkDocId = e.clipboardData.getData("dash/linkDoc"); + if (linkDocId) { + DocServer.GetRefField(linkDocId).then(async (link) => { + if (!(link instanceof Doc)) { + return; + } + let proto = Doc.GetProto(link); + let source = await Cast(proto.anchor1, Doc); + proto.anchor2 = this.makeAnnotationDocument(source, 0, "#0390fc", false); + }); + } + } + } } scrollTo(y: number) { @@ -213,7 +236,7 @@ export class Viewer extends React.Component { } @action - makeAnnotationDocument = (sourceDoc: Doc | undefined, s: number, color: string): Doc => { + makeAnnotationDocument = (sourceDoc: Doc | undefined, s: number, color: string, createLink: boolean = true): Doc => { let annoDocs: Doc[] = []; let mainAnnoDoc = Docs.Create.InstanceFromProto(new Doc(), "", {}); @@ -242,7 +265,7 @@ export class Viewer extends React.Component { mainAnnoDoc.y = Math.max(minY, 0); mainAnnoDoc.annotations = new List(annoDocs); - if (sourceDoc) { + if (sourceDoc && createLink) { DocUtils.MakeLink(sourceDoc, mainAnnoDoc, undefined, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); } this._savedAnnotations.clear(); @@ -611,7 +634,7 @@ export class Viewer extends React.Component {
{this._visibleElements}
-
+
console.log("gello world")} style={{ transform: "scale(1.5)", transformOrigin: "top left" }} />
Date: Sat, 27 Jul 2019 22:58:01 -0400 Subject: finisheddd --- src/client/views/nodes/FormattedTextBox.tsx | 42 +++++++++++++++++++---------- src/client/views/nodes/PDFBox.tsx | 2 -- src/client/views/pdf/PDFViewer.tsx | 30 ++++++++++++++++++--- src/client/views/pdf/Page.tsx | 3 ++- 4 files changed, 56 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 364dc1c83..f019868aa 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -8,7 +8,7 @@ import { keymap } from "prosemirror-keymap"; import { EditorState, Plugin, Transaction, Selection } from "prosemirror-state"; import { NodeType, Slice, Node, Fragment } from 'prosemirror-model'; import { EditorView } from "prosemirror-view"; -import { Doc, Opt } from "../../../new_fields/Doc"; +import { Doc, Opt, DocListCast } from "../../../new_fields/Doc"; import { Id, Copy } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; import { RichTextField } from "../../../new_fields/RichTextField"; @@ -302,28 +302,42 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => { let cbe = event as ClipboardEvent; let docId: string; + let regionId: string; if (!cbe.clipboardData) { return false; } let linkId: string; docId = cbe.clipboardData.getData("dash/pdfOrigin"); - if (!docId) { + regionId = cbe.clipboardData.getData("dash/pdfRegion"); + if (!docId || !regionId) { return false; } DocServer.GetRefField(docId).then(doc => { - if (!(doc instanceof Doc)) { - return; - } - let link = DocUtils.MakeLink(this.props.Document, doc); - if (link) { - cbe.clipboardData!.setData("dash/linkDoc", link[Id]); - linkId = link[Id]; - let frag = addMarkToFrag(slice.content); - slice = new Slice(frag, slice.openStart, slice.openEnd); - var tr = view.state.tr.replaceSelection(slice); - view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); - } + DocServer.GetRefField(regionId).then(region => { + if (!(doc instanceof Doc) || !(region instanceof Doc)) { + return; + } + + let annotations = DocListCast(region.annotations); + annotations.forEach(anno => anno.target = this.props.Document); + let fieldExtDoc = Doc.resolvedFieldDataDoc(doc, "data", "true"); + let targetAnnotations = DocListCast(fieldExtDoc.annotations); + if (targetAnnotations) { + targetAnnotations.push(region); + fieldExtDoc.annotations = new List(targetAnnotations); + } + + let link = DocUtils.MakeLink(this.props.Document, region); + if (link) { + cbe.clipboardData!.setData("dash/linkDoc", link[Id]); + linkId = link[Id]; + let frag = addMarkToFrag(slice.content); + slice = new Slice(frag, slice.openStart, slice.openEnd); + var tr = view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + } + }); }); return true; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 72d835fce..f527c0595 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -34,7 +34,6 @@ export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === K @observer export class PDFBox extends DocComponent(PdfDocument) { public static LayoutString() { return FieldView.LayoutString(PDFBox); } - public selectionText: string = ""; @observable private _alt = false; @observable private _scrollY: number = 0; @@ -82,7 +81,6 @@ export class PDFBox extends DocComponent(PdfDocumen private copy = (e: ClipboardEvent) => { if (this.props.active()) { - let text = this.selectionText; if (e.clipboardData) { e.clipboardData.setData("text/plain", text); e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index db2d49f0f..6fef8a4de 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -92,6 +92,7 @@ export class Viewer extends React.Component { // private _textContent: Pdfjs.TextContent[] = []; private _pdfFindController: any; private _searchString: string = ""; + private _selectionText: string = ""; constructor(props: IViewerProps) { super(props); @@ -102,6 +103,10 @@ export class Viewer extends React.Component { this._mainCont = React.createRef(); } + setSelectionText = (text: string) => { + this._selectionText = text; + } + componentDidUpdate = (prevProps: IViewerProps) => { if (this.scrollY !== prevProps.scrollY) { this.renderPages(); @@ -158,8 +163,8 @@ export class Viewer extends React.Component { this._dropDisposer = this._mainCont.current && DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }); } - document.removeEventListener("paste", this.paste); - document.addEventListener("paste", this.paste); + document.removeEventListener("copy", this.copy); + document.addEventListener("copy", this.copy); } componentWillUnmount = () => { @@ -167,7 +172,24 @@ export class Viewer extends React.Component { this._annotationReactionDisposer && this._annotationReactionDisposer(); this._filterReactionDisposer && this._filterReactionDisposer(); this._dropDisposer && this._dropDisposer(); - document.removeEventListener("paste", this.paste); + document.removeEventListener("copy", this.copy); + } + + private copy = (e: ClipboardEvent) => { + if (this.props.parent.props.active()) { + let text = this._selectionText; + if (e.clipboardData) { + e.clipboardData.setData("text/plain", text); + e.clipboardData.setData("dash/pdfOrigin", this.props.parent.props.Document[Id]); + let annoDoc = this.makeAnnotationDocument(undefined, 0, "#0390fc"); + e.clipboardData.setData("dash/pdfRegion", annoDoc[Id]); + e.preventDefault(); + } + } + // let targetAnnotations = DocListCast(this.props.parent.fieldExtensionDoc.annotations); + // if (targetAnnotations) { + // targetAnnotations.push(destDoc); + // } } paste = (e: ClipboardEvent) => { @@ -281,7 +303,6 @@ export class Viewer extends React.Component { let targetAnnotations = DocListCast(this.props.parent.fieldExtensionDoc.annotations); if (targetAnnotations) { targetAnnotations.push(destDoc); - this.props.parent.fieldExtensionDoc.annotations = new List(targetAnnotations); } else { this.props.parent.fieldExtensionDoc.annotations = new List([destDoc]); @@ -315,6 +336,7 @@ export class Viewer extends React.Component { this._isPage[page] = "page"; this._visibleElements[page] = ( void; makeAnnotationDocuments: (doc: Doc | undefined, scale: number, color: string, linkTo: boolean) => Doc; getScrollFromPage: (page: number) => number; + setSelectionText: (text: string) => void; } @observer @@ -392,7 +393,7 @@ export default class Page extends React.Component { } let text = selRange.extractContents().textContent; if (text) { - this.props.parent.selectionText = text; + this.props.setSelectionText(text); } // clear selection if (sel.empty) { // Chrome -- cgit v1.2.3-70-g09d2 From 5fd48d3d10e86cea834f0238ec5d648febb62c81 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 28 Jul 2019 00:20:16 -0400 Subject: Added PrefetchProxy class --- src/new_fields/Proxy.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts index 14f08814e..b3e8d6467 100644 --- a/src/new_fields/Proxy.ts +++ b/src/new_fields/Proxy.ts @@ -6,6 +6,7 @@ import { DocServer } from "../client/DocServer"; import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; import { Id, Copy, ToScriptString } from "./FieldSymbols"; +import { scriptingGlobal } from "../client/util/Scripting"; @Deserializable("proxy") export class ProxyField extends ObjectField { @@ -66,3 +67,12 @@ export class ProxyField extends ObjectField { return this.promise as any; } } + +function prefetchValue(proxy: PrefetchProxy) { + return proxy.value() as any; +} + +@scriptingGlobal +@Deserializable("prefetch_proxy", prefetchValue) +export class PrefetchProxy extends ProxyField { +} -- cgit v1.2.3-70-g09d2 From 239e8b0a354b68a700181af3c4e9deb77fc8c009 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 14:22:41 -0400 Subject: schema view now uses child docs --- src/client/views/collections/CollectionSchemaView.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 42843ad30..7da5665f3 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -202,7 +202,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { Document={this.props.Document} // child doc PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth} - // childDocs={this.childDocs} + childDocs={this.childDocs} CollectionView={this.props.CollectionView} ContainingCollectionView={this.props.ContainingCollectionView} fieldKey={this.props.fieldKey} // might just be this. @@ -252,7 +252,7 @@ export interface SchemaTableProps { dataDoc?: Doc; PanelHeight: () => number; PanelWidth: () => number; - // childDocs: Doc[]; + childDocs: Doc[]; CollectionView: CollectionView | CollectionPDFView | CollectionVideoView; ContainingCollectionView: Opt; fieldKey: string; @@ -299,8 +299,9 @@ export class SchemaTable extends React.Component { let focusedCol = this._focusedCell.col; let isEditable = !this._headerIsEditing;// && this.props.isSelected(); - let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = DocListCast(cdoc[this.props.fieldKey]); + // let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; + // let children = DocListCast(cdoc[this.props.fieldKey]); + let children = this.props.childDocs; if (children.reduce((found, doc) => found || doc.type === "collection", false)) { columns.push( -- cgit v1.2.3-70-g09d2 From 6b50ec0f33c30b6100165d50811f4fa72657b66e Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 14:41:45 -0400 Subject: schemas now actually use view specs --- .../views/collections/CollectionSchemaView.tsx | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 7da5665f3..77ed2d8dc 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -425,7 +425,8 @@ export class SchemaTable extends React.Component { tableRemoveDoc = (document: Doc): boolean => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + let children = this.props.childDocs; if (children.indexOf(document) !== -1) { children.splice(children.indexOf(document), 1); return true; @@ -520,7 +521,8 @@ export class SchemaTable extends React.Component { this.changeFocusedCellByDirection(direction); let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + let children = this.props.childDocs; const pdoc = FieldValue(children[this._focusedCell.row]); pdoc && this.props.setPreviewDoc(pdoc); } @@ -529,7 +531,8 @@ export class SchemaTable extends React.Component { @action changeFocusedCellByDirection = (direction: string): void => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + let children = this.props.childDocs; switch (direction) { case "tab": if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === children.length) { @@ -560,7 +563,7 @@ export class SchemaTable extends React.Component { @action changeFocusedCellByIndex = (row: number, col: number): void => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); this._focusedCell = { row: row, col: col }; this.props.setFocused(this.props.Document); @@ -571,7 +574,8 @@ export class SchemaTable extends React.Component { createRow = () => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + let children = this.props.childDocs; let newDoc = Docs.Create.TextDocument({ width: 100, height: 30 }); let proto = Doc.GetProto(newDoc); @@ -683,7 +687,8 @@ export class SchemaTable extends React.Component { } get documentKeys() { - const docs = DocListCast(this.props.Document[this.props.fieldKey]); + // const docs = DocListCast(this.props.Document[this.props.fieldKey]); + let docs = this.props.childDocs; let keys: { [key: string]: boolean } = {}; // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be @@ -712,7 +717,8 @@ export class SchemaTable extends React.Component { get reactTable() { let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - let children = DocListCast(cdoc[this.props.fieldKey]); + // let children = DocListCast(cdoc[this.props.fieldKey]); + let children = this.props.childDocs; let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; let hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false); @@ -758,7 +764,7 @@ export class SchemaTable extends React.Component { let csv: string = this.columns.reduce((val, col) => val + col + ",", ""); csv = csv.substr(0, csv.length - 1) + "\n"; let self = this; - DocListCast(this.props.Document.data).map(doc => { + this.props.childDocs.map(doc => { csv += self.columns.reduce((val, col) => val + (doc[col.heading] ? doc[col.heading]!.toString() : "0") + ",", ""); csv = csv.substr(0, csv.length - 1) + "\n"; }); @@ -778,7 +784,8 @@ export class SchemaTable extends React.Component { // const docs = DocListCast(this.props.Document[this.props.fieldKey]); let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - const docs = DocListCast(cdoc[this.props.fieldKey]); + // const docs = DocListCast(cdoc[this.props.fieldKey]); + let docs = this.props.childDocs; row = row % docs.length; while (row < 0) row += docs.length; -- cgit v1.2.3-70-g09d2 From 902709d953fd00deb124862519fa00215cadc26f Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 15:12:59 -0400 Subject: view specs now correctly handles (not) contains --- src/client/views/collections/KeyRestrictionRow.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx index f292557b5..4f3d82114 100644 --- a/src/client/views/collections/KeyRestrictionRow.tsx +++ b/src/client/views/collections/KeyRestrictionRow.tsx @@ -18,10 +18,12 @@ export default class KeyRestrictionRow extends React.Component - {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)} -
; - } else { - let dref = React.createRef(); - let dxf = () => this.getDocTransform(layoutDoc, dref.current!); - this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height }); - let rowHgtPcnt = height(); - let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); - let divStyle = parent.singleColumn ? { width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` }; - return
- {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)} -
; - } + let dref = React.createRef(); + // if (uniqueHeadings.length > 0) { + let dxf = () => this.getDocTransform(pair.layout, dref.current!); + this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height }); + // } + // else { + // //have to add the height of all previous single column sections or the doc decorations will be in the wrong place. + // let dxf = () => this.getDocTransform(layoutDoc, i, width()); + // this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height }); + // } + let rowHgtPcnt = height(); + let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); + let style = parent.singleColumn ? { width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` }; + return
+ {this.props.parent.getDisplayDoc(pair.layout, pair.data, dxf, width)} +
; + // } else { + // let dref = React.createRef(); + // let dxf = () => this.getDocTransform(layoutDoc, dref.current!); + // this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height }); + // let rowHgtPcnt = height(); + // let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); + // let divStyle = parent.singleColumn ? { width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` }; + // return
+ // {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)} + //
; + // } }); } - getSingleDocTransform(doc: Doc, ind: number, width: number) { - let localY = this.props.parent.filteredChildren.reduce((height, d, i) => - height + (i < ind ? this.props.parent.getDocHeight(Doc.expandTemplateLayout(d, this.props.parent.props.DataDoc)) + this.props.parent.gridGap : 0), this.props.parent.yMargin); - let translate = this.props.parent.props.ScreenToLocalTransform().inverse().transformPoint((this.props.parent.props.PanelWidth() - width) / 2, localY); - return this.offsetTransform(doc, translate[0], translate[1]); - } - - offsetTransform(doc: Doc, translateX: number, translateY: number) { - let outerXf = Utils.GetScreenTransform(this.props.parent._masonryGridRef!); - let offset = this.props.parent.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); - return this.props.parent.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.props.parent.columnWidth); - } - getDocTransform(doc: Doc, dref: HTMLDivElement) { let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); let outerXf = Utils.GetScreenTransform(this.props.parent._masonryGridRef!); let offset = this.props.parent.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); - return this.props.parent.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.props.parent.columnWidth); + return this.props.parent.props.ScreenToLocalTransform(). + translate(offset[0], offset[1] - (this.props.parent.chromeCollapsed ? 0 : 100)). + scale(NumCast(doc.width, 1) / this.props.parent.columnWidth); } getValue = (value: string): any => { -- cgit v1.2.3-70-g09d2 From cb2347347c8d9d2a0f1531479c73ecbcb3008128 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 16:51:07 -0400 Subject: padding on text boxes --- src/client/views/nodes/FormattedTextBox.scss | 70 ++++++++++++++++------------ 1 file changed, 39 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index d3045ae2f..a24abb32e 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -1,34 +1,37 @@ @import "../globalCssVariables"; + .ProseMirror { - width: 100%; - height: 100%; - min-height: 100%; - font-family: $serif; + width: 100%; + height: 100%; + min-height: 100%; + font-family: $serif; } .ProseMirror:focus { - outline: none !important; + outline: none !important; } -.formattedTextBox-cont-scroll, .formattedTextBox-cont-hidden { - background: inherit; - padding: 0; - border-width: 0px; - border-radius: inherit; - border-color: $intermediate-color; - box-sizing: border-box; - background-color: inherit; - border-style: solid; - overflow-y: auto; - overflow-x: hidden; - color: initial; - height: 100%; - pointer-events: all; +.formattedTextBox-cont-scroll, +.formattedTextBox-cont-hidden { + background: inherit; + padding: 0; + border-width: 0px; + border-radius: inherit; + border-color: $intermediate-color; + box-sizing: border-box; + background-color: inherit; + border-style: solid; + overflow-y: auto; + overflow-x: hidden; + color: initial; + height: 100%; + pointer-events: all; } .formattedTextBox-cont-hidden { pointer-events: none; } + .formattedTextBox-inner-rounded { height: calc(100% - 25px); width: calc(100% - 40px); @@ -38,23 +41,28 @@ left: 20; } +.formattedTextBox-inner-rounded div, +.formattedTextBox-inner div { + padding: 10px; +} + .menuicon { - display: inline-block; - border-right: 1px solid rgba(0, 0, 0, 0.2); - color: #888; - line-height: 1; - padding: 0 7px; - margin: 1px; - cursor: pointer; - text-align: center; - min-width: 1.4em; + display: inline-block; + border-right: 1px solid rgba(0, 0, 0, 0.2); + color: #888; + line-height: 1; + padding: 0 7px; + margin: 1px; + cursor: pointer; + text-align: center; + min-width: 1.4em; } .strong, .heading { - font-weight: bold; + font-weight: bold; } .em { - font-style: italic; -} + font-style: italic; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From be1e6e967a60f49eec1cb1d404912b0736812323 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 28 Jul 2019 17:59:00 -0400 Subject: Added ability to capture documents in button scripts --- src/client/views/ScriptBox.tsx | 23 +++++++- src/client/views/ScriptingRepl.tsx | 31 +---------- .../views/collections/CollectionDockingView.tsx | 1 - src/client/views/nodes/ButtonBox.tsx | 6 +- src/client/views/nodes/DocumentIcon.tsx | 65 ++++++++++++++++++++++ 5 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 src/client/views/nodes/DocumentIcon.tsx (limited to 'src') diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index fa236c2da..d073945e5 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -3,11 +3,15 @@ import { observer } from "mobx-react"; import { observable, action } from "mobx"; import "./ScriptBox.scss"; +import { OverlayView } from "./OverlayView"; +import { DocumentIconContainer } from "./nodes/DocumentIcon"; +import { Opt } from "../../new_fields/Doc"; export interface ScriptBoxProps { onSave: (text: string, onError: (error: string) => void) => void; onCancel?: () => void; initialText?: string; + showDocumentIcons?: boolean; } @observer @@ -30,14 +34,31 @@ export class ScriptBox extends React.Component { console.log(error); } + overlayDisposer?: () => void; + onFocus = () => { + if (this.overlayDisposer) { + this.overlayDisposer(); + } + this.overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); + } + + onBlur = () => { + this.overlayDisposer && this.overlayDisposer(); + } + render() { + let onFocus: Opt<() => void> = undefined, onBlur: Opt<() => void> = undefined; + if (this.props.showDocumentIcons) { + onFocus = this.onFocus; + onBlur = this.onBlur; + } return (
- +
); } diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index 0cff145b6..e05195ca0 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -4,40 +4,15 @@ import { observable, action } from 'mobx'; import './ScriptingRepl.scss'; import { Scripting, CompileScript, ts, Transformer } from '../util/Scripting'; import { DocumentManager } from '../util/DocumentManager'; -import { DocumentView } from './nodes/DocumentView'; import { OverlayView } from './OverlayView'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretDown, faCaretRight } from '@fortawesome/free-solid-svg-icons'; +import { DocumentIconContainer } from './nodes/DocumentIcon'; library.add(faCaretDown); library.add(faCaretRight); -@observer -export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> { - render() { - const view = this.props.view; - const transform = view.props.ScreenToLocalTransform().scale(view.props.ContentScaling()).inverse(); - const { x, y, width, height } = transform.transformBounds(0, 0, view.props.PanelWidth(), view.props.PanelHeight()); - - return ( -
-

${this.props.index}

-
- ); - } -} - -@observer -export class DocumentIconContainer extends React.Component { - render() { - return DocumentManager.Instance.DocumentViews.map((dv, i) => ); - } -} - @observer export class ScriptingObjectDisplay extends React.Component<{ scrollToBottom: () => void, value: { [key: string]: any }, name?: string }> { @observable collapsed = true; @@ -129,7 +104,7 @@ export class ScriptingRepl extends React.Component { if (ts.isParameter(node.parent)) { // delete knownVars[node.text]; } else if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) { - const match = node.text.match(/\$([0-9]+)/); + const match = node.text.match(/\d([0-9]+)/); if (match) { const m = parseInt(match[1]); usedDocuments.push(m); @@ -153,7 +128,7 @@ export class ScriptingRepl extends React.Component { switch (e.key) { case "Enter": { const docGlobals: { [name: string]: any } = {}; - DocumentManager.Instance.DocumentViews.forEach((dv, i) => docGlobals[`$${i}`] = dv.props.Document); + DocumentManager.Instance.DocumentViews.forEach((dv, i) => docGlobals[`d${i}`] = dv.props.Document); const globals = Scripting.makeMutableGlobalsCopy(docGlobals); const script = CompileScript(this.commandString, { typecheck: false, addReturn: true, editable: true, params: { args: "any" }, transformer: this.getTransformer(), globals }); if (!script.compiled) { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 0865058be..1859ebee7 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -577,7 +577,6 @@ export class DockedFrameRenderer extends React.Component { return (null); } let resolvedDataDoc = this._document.layout instanceof Doc ? this._document : this._dataDoc; - console.log("pw = " + this.panelWidth() + "," + this.panelHeight() + " " + this.contentScaling()); return (Butt const script = CompileScript(text, { params: { this: Doc.name }, typecheck: false, - editable: true + editable: true, + transformer: DocumentIconContainer.getTransformer() }); if (!script.compiled) { onError(script.errors.map(error => error.messageText).join("\n")); @@ -59,7 +61,7 @@ export class ButtonBox extends DocComponent(Butt } this.Document.onClick = new ScriptField(script); overlayDisposer(); - }} />; + }} showDocumentIcons />; overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, { x: 400, y: 200, width: 500, height: 400, title: `${this.Document.title || ""} OnClick` }); } }); diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx new file mode 100644 index 000000000..f56f5e829 --- /dev/null +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -0,0 +1,65 @@ +import { observer } from "mobx-react"; +import * as React from "react"; +import { DocumentView } from "./DocumentView"; +import { DocumentManager } from "../../util/DocumentManager"; +import { Transformer, Scripting, ts } from "../../util/Scripting"; +import { Field } from "../../../new_fields/Doc"; + +@observer +export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> { + render() { + const view = this.props.view; + const transform = view.props.ScreenToLocalTransform().scale(view.props.ContentScaling()).inverse(); + const { x, y, width, height } = transform.transformBounds(0, 0, view.props.PanelWidth(), view.props.PanelHeight()); + + return ( +
+

d{this.props.index}

+
+ ); + } +} + +@observer +export class DocumentIconContainer extends React.Component { + public static getTransformer(): Transformer { + const usedDocuments = new Set(); + return { + transformer: context => { + return root => { + function visit(node: ts.Node) { + node = ts.visitEachChild(node, visit, context); + + if (ts.isIdentifier(node)) { + const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node; + const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node; + const isntParameter = !ts.isParameter(node.parent); + if (isntPropAccess && isntPropAssign && isntParameter && !(node.text in globalThis)) { + const match = node.text.match(/d([0-9]+)/); + if (match) { + const m = parseInt(match[1]); + usedDocuments.add(m); + } + } + } + + return node; + } + return ts.visitNode(root, visit); + }; + }, + getVars() { + const docs = DocumentManager.Instance.DocumentViews; + const capturedVariables: { [name: string]: Field } = {}; + usedDocuments.forEach(index => capturedVariables[`d${index}`] = docs[index].props.Document); + return { capturedVariables }; + } + }; + } + render() { + return DocumentManager.Instance.DocumentViews.map((dv, i) => ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3f54bd76fd806ac3e7b2380fe45e71549ea65955 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 18:02:58 -0400 Subject: only enter wlil trigger the editable view in schema cells --- src/client/views/collections/CollectionSchemaCells.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index f1e013edd..194765880 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -25,6 +25,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faExpand } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; +import { KeyCodes } from "../../northstar/utils/KeyCodes"; library.add(faExpand); @@ -66,7 +67,7 @@ export class CollectionSchemaCell extends React.Component { @action onKeyDown = (e: KeyboardEvent): void => { - if (this.props.isFocused && this.props.isEditable) { + if (this.props.isFocused && this.props.isEditable && e.keyCode === KeyCodes.ENTER) { document.removeEventListener("keydown", this.onKeyDown); this._isEditing = true; this.props.setIsEditing(true); -- cgit v1.2.3-70-g09d2 From 6d6ceb1f0c0ebc18fd52783baca6da28b3f75ec0 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 18:20:28 -0400 Subject: ctrl backpsace now works when editing text --- src/client/views/GlobalKeyHandler.ts | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index d52c05b2f..e31b44514 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -133,6 +133,13 @@ export default class KeyManager { } MainView.Instance.mainFreeform && CollectionDockingView.Instance.CloseRightSplit(MainView.Instance.mainFreeform); break; + case "backspace": + if (document.activeElement) { + if (document.activeElement.tagName === "INPUT" || document.activeElement.tagName === "TEXTAREA") { + return { stopPropagation: false, preventDefault: false }; + } + } + break; case "f": MainView.Instance.isSearchVisible = !MainView.Instance.isSearchVisible; break; -- cgit v1.2.3-70-g09d2 From 22955412de5b0c5634343cfc45bbe09a91bbbdde Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 18:20:44 -0400 Subject: improvements to view specs box --- .../views/collections/CollectionViewChromes.tsx | 27 +++++++++++++++++----- src/client/views/collections/KeyRestrictionRow.tsx | 3 +++ 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 044d5336a..9c751c4df 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -31,7 +31,7 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); export class CollectionViewBaseChrome extends React.Component { @observable private _viewSpecsOpen: boolean = false; @observable private _dateWithinValue: string = ""; - @observable private _dateValue: Date = new Date(); + @observable private _dateValue: Date | string = ""; @observable private _keyRestrictions: [JSX.Element, string][] = []; @observable private _collapsed: boolean = false; @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); } @@ -124,10 +124,24 @@ export class CollectionViewBaseChrome extends React.Component= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; - let fullScript = `return ${dateRestrictionScript} && ${keyRestrictionScript}`; + let dateRestrictionScript = ""; + if (this._dateValue instanceof Date) { + let lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset); + let upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1); + dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; + } + else { + let createdDate = new Date(this._dateValue); + if (!isNaN(createdDate.getTime())) { + let lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset); + let upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1); + dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; + } + } + let fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ? + `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} ${keyRestrictionScript}` : + `return ${keyRestrictionScript} ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` : + "return true"; let compiled = CompileScript(fullScript, { params: { doc: Doc.name } }); if (compiled.compiled) { this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled); @@ -221,7 +235,8 @@ export class CollectionViewBaseChrome extends React.Component runInAction(() => this._dateValue = e.target.value)} onPointerDown={this.openDatePicker} placeholder="Value" />
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx index 4f3d82114..9c3c9c07c 100644 --- a/src/client/views/collections/KeyRestrictionRow.tsx +++ b/src/client/views/collections/KeyRestrictionRow.tsx @@ -26,6 +26,9 @@ export default class KeyRestrictionRow extends React.Component Date: Sun, 28 Jul 2019 18:27:52 -0400 Subject: fixed moving and deleting documents --- .../views/collections/CollectionSchemaView.tsx | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 77ed2d8dc..8436b22a4 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -289,6 +289,7 @@ export class SchemaTable extends React.Component { @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []); } + @computed get childDocs() { return this.props.childDocs; } set columns(columns: SchemaHeaderField[]) { this.props.Document.schemaColumns = new List(columns); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { @@ -301,7 +302,7 @@ export class SchemaTable extends React.Component { // let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // let children = DocListCast(cdoc[this.props.fieldKey]); - let children = this.props.childDocs; + let children = this.childDocs; if (children.reduce((found, doc) => found || doc.type === "collection", false)) { columns.push( @@ -425,8 +426,8 @@ export class SchemaTable extends React.Component { tableRemoveDoc = (document: Doc): boolean => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; - // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); - let children = this.props.childDocs; + let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + // let children = this.childDocs; if (children.indexOf(document) !== -1) { children.splice(children.indexOf(document), 1); return true; @@ -522,7 +523,7 @@ export class SchemaTable extends React.Component { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); - let children = this.props.childDocs; + let children = this.childDocs; const pdoc = FieldValue(children[this._focusedCell.row]); pdoc && this.props.setPreviewDoc(pdoc); } @@ -532,7 +533,7 @@ export class SchemaTable extends React.Component { changeFocusedCellByDirection = (direction: string): void => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); - let children = this.props.childDocs; + let children = this.childDocs; switch (direction) { case "tab": if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === children.length) { @@ -575,7 +576,7 @@ export class SchemaTable extends React.Component { createRow = () => { let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); - let children = this.props.childDocs; + let children = this.childDocs; let newDoc = Docs.Create.TextDocument({ width: 100, height: 30 }); let proto = Doc.GetProto(newDoc); @@ -688,7 +689,7 @@ export class SchemaTable extends React.Component { get documentKeys() { // const docs = DocListCast(this.props.Document[this.props.fieldKey]); - let docs = this.props.childDocs; + let docs = this.childDocs; let keys: { [key: string]: boolean } = {}; // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be @@ -718,7 +719,7 @@ export class SchemaTable extends React.Component { let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // let children = DocListCast(cdoc[this.props.fieldKey]); - let children = this.props.childDocs; + let children = this.childDocs; let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; let hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false); @@ -730,7 +731,7 @@ export class SchemaTable extends React.Component { return { let csv: string = this.columns.reduce((val, col) => val + col + ",", ""); csv = csv.substr(0, csv.length - 1) + "\n"; let self = this; - this.props.childDocs.map(doc => { + this.childDocs.map(doc => { csv += self.columns.reduce((val, col) => val + (doc[col.heading] ? doc[col.heading]!.toString() : "0") + ",", ""); csv = csv.substr(0, csv.length - 1) + "\n"; }); @@ -785,7 +786,7 @@ export class SchemaTable extends React.Component { let cdoc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; // const docs = DocListCast(cdoc[this.props.fieldKey]); - let docs = this.props.childDocs; + let docs = this.childDocs; row = row % docs.length; while (row < 0) row += docs.length; -- cgit v1.2.3-70-g09d2 From 99ab639f4de270eb1f7b497b6386cb8d5a1f7e5f Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 28 Jul 2019 20:31:11 -0400 Subject: fixed next and prev annotation scorlling --- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index f527c0595..4973340df 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -167,7 +167,7 @@ export class PDFBox extends DocComponent(PdfDocumen scrollTo(y: number) { if (this._mainCont.current) { - this._mainCont.current.scrollTo({ top: y, behavior: "auto" }); + this._mainCont.current.scrollTo({ top: Math.max(y - (this._mainCont.current!.offsetHeight / 2), 0), behavior: "auto" }); } } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 6fef8a4de..5eb02a6da 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -212,7 +212,7 @@ export class Viewer extends React.Component { scrollTo(y: number) { if (this.props.mainCont.current) { - this.props.parent.scrollTo(y - this.props.mainCont.current.clientHeight); + this.props.parent.scrollTo(y); } } -- cgit v1.2.3-70-g09d2 From e7ea2028f54787d6c92fb22b789f17b7268d3793 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 08:37:53 -0400 Subject: some layout adjustments for stacking views --- src/client/views/collections/CollectionStackingView.tsx | 4 ++-- .../views/collections/CollectionStackingViewFieldColumn.tsx | 10 +++++----- src/client/views/nodes/DocumentView.tsx | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index b96b1f8c8..f647da8f0 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -140,12 +140,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { previewScript={undefined}> ; } - getDocHeight(d: Doc) { + getDocHeight(d: Doc, columnScale: number = 1) { let nw = NumCast(d.nativeWidth); let nh = NumCast(d.nativeHeight); if (!BoolCast(d.ignoreAspect) && nw && nh) { let aspect = nw && nh ? nh / nw : 1; - let wid = Math.min(d[WidthSym](), this.columnWidth); + let wid = Math.min(d[WidthSym](), this.columnWidth / columnScale); return wid * aspect; } return d[HeightSym](); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index cf5bc451a..387e189e7 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -74,8 +74,8 @@ export class CollectionStackingViewFieldColumn extends React.Component headings.indexOf(i) === idx); let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d); - let width = () => (d.nativeWidth && !BoolCast(d.ignoreAspect) ? Math.min(pair.layout[WidthSym](), parent.columnWidth) : parent.columnWidth) / (uniqueHeadings.length + 1); - let height = () => parent.getDocHeight(pair.layout); + let width = () => (d.nativeWidth && !BoolCast(d.ignoreAspect) ? Math.min(pair.layout[WidthSym](), parent.columnWidth / (uniqueHeadings.length + 1)) : parent.columnWidth / (uniqueHeadings.length + 1));/// (uniqueHeadings.length + 1); + let height = () => parent.getDocHeight(pair.layout, uniqueHeadings.length + 1);// / (d.nativeWidth && !BoolCast(d.ignoreAspect) ? uniqueHeadings.length + 1 : 1); let dref = React.createRef(); // if (uniqueHeadings.length > 0) { let dxf = () => this.getDocTransform(pair.layout, dref.current!); @@ -88,7 +88,7 @@ export class CollectionStackingViewFieldColumn extends React.Component {this.props.parent.getDisplayDoc(pair.layout, pair.data, dxf, width)}
; @@ -267,8 +267,8 @@ export class CollectionStackingViewFieldColumn extends React.Component(Docu transformOrigin: "top left", transform: `scale(${1 / this.props.ContentScaling()})` }}>