diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/TooltipTextMenu.scss | 26 | ||||
-rw-r--r-- | src/client/views/PreviewCursor.tsx | 9 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.scss | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 32 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 5 | ||||
-rw-r--r-- | src/client/views/collections/CollectionVideoView.scss | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 48 | ||||
-rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/FieldView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 3 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/IconBox.scss | 4 | ||||
-rw-r--r-- | src/client/views/nodes/KeyValuePair.scss | 8 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 8 |
14 files changed, 115 insertions, 50 deletions
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index 70d9ad772..437da0d63 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -162,19 +162,6 @@ .ProseMirror-icon span { vertical-align: text-top; } -.ProseMirror-example-setup-style hr { - padding: 2px 10px; - border: none; - margin: 1em 0; - } - - .ProseMirror-example-setup-style hr:after { - content: ""; - display: block; - height: 1px; - background-color: silver; - line-height: 2px; - } .ProseMirror ul, .ProseMirror ol { padding-left: 30px; @@ -255,6 +242,19 @@ -webkit-transform: translateX(-50%); transform: translateX(-50%); pointer-events: all; + .ProseMirror-example-setup-style hr { + padding: 2px 10px; + border: none; + margin: 1em 0; + } + + .ProseMirror-example-setup-style hr:after { + content: ""; + display: block; + height: 1px; + background-color: silver; + line-height: 2px; + } } .tooltipMenu:before { diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 78024a58c..4218ea7c9 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -18,6 +18,13 @@ export class PreviewCursor extends React.Component<{}> { constructor(props: any) { super(props); document.addEventListener("keydown", this.onKeyPress); + document.addEventListener("paste", this.paste); + } + paste = (e: ClipboardEvent) => { + console.log(e.clipboardData); + console.log(e.clipboardData.getData("text/html")); + console.log(e.clipboardData.getData("text/csv")); + console.log(e.clipboardData.getData("text/plain")); } @action @@ -28,7 +35,7 @@ export class PreviewCursor extends React.Component<{}> { //if not these keys, make a textbox if preview cursor is active! if (e.key.startsWith("F") && !e.key.endsWith("F")) { } else if (e.key !== "Escape" && e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { - if ((!e.ctrlKey && !e.metaKey) || e.key === "v" || e.key === "q") { + if ((!e.ctrlKey && !e.metaKey) || (e.key >= "a" && e.key <= "z")) { PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e); PreviewCursor.Visible = false; } diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index cfdb3ab22..b9ed99155 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -14,6 +14,10 @@ .collectionSchemaView-cellContents { height: $MAX_ROW_HEIGHT; + img { + width:auto; + max-height: $MAX_ROW_HEIGHT; + } } .collectionSchemaView-previewRegion { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 506e60a65..4984e26d1 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -24,6 +24,7 @@ import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; import { List } from "../../../new_fields/List"; import { Id } from "../../../new_fields/RefField"; +import { isUndefined } from "typescript-collections/dist/lib/util"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @@ -77,23 +78,22 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { PanelHeight: returnZero, PanelWidth: returnZero, }; - let contents = ( - <FieldView {...props} /> - ); + let fieldContentView = <FieldView {...props} />; let reference = React.createRef<HTMLDivElement>(); - let onItemDown = SetupDrag(reference, () => props.Document, this.props.moveDocument); + let onItemDown = (e: React.PointerEvent) => + (this.props.CollectionView!.props.isSelected() ? + SetupDrag(reference, () => props.Document, this.props.moveDocument)(e) : undefined); let applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => { const res = run({ this: doc }); if (!res.success) return false; - const field = res.result; - doc[props.fieldKey] = field; + doc[props.fieldKey] = res.result; return true; }; return ( <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} key={props.Document[Id]} ref={reference}> <EditableView display={"inline"} - contents={contents} + contents={fieldContentView} height={Number(MAX_ROW_HEIGHT)} GetValue={() => { let field = props.Document[props.fieldKey]; @@ -224,10 +224,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this.previewScript = e.currentTarget.value; } + @computed get previewDocument(): Doc | undefined { - const children = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []); + const children = DocListCast(this.props.Document[this.props.fieldKey]); const selected = children.length > this._selectedIndex ? FieldValue(children[this._selectedIndex]) : undefined; - return selected ? (this.previewScript ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; + return selected ? (this.previewScript && this.previewScript != "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; } get tableWidth() { return (this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH) * (1 - this.splitPercentage / 100); } get previewRegionHeight() { return this.props.PanelHeight() - 2 * this.borderWidth; } @@ -253,8 +254,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { get previewPanel() { // let doc = CompileScript(this.previewScript, { this: selected }, true)(); const previewDoc = this.previewDocument; - return !previewDoc ? (null) : ( - <div className="collectionSchemaView-previewRegion" style={{ width: `${this.previewRegionWidth}px` }}> + return (<div className="collectionSchemaView-previewRegion" style={{ width: `${this.previewRegionWidth}px` }}> + {!previewDoc || !this.previewRegionWidth ? (null) : ( <div className="collectionSchemaView-previewDoc" style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px)` }}> <DocumentView Document={previewDoc} isTopMost={false} selectOnLoad={false} toggleMinimized={emptyFunction} @@ -268,11 +269,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { whenActiveChanged={this.props.whenActiveChanged} bringToFront={emptyFunction} /> - </div> - <input className="collectionSchemaView-input" value={this.previewScript} onChange={this.onPreviewScriptChange} - style={{ left: `calc(50% - ${Math.min(75, this.previewPanelWidth() / 2)}px)` }} /> - </div> - ); + </div>)} + <input className="collectionSchemaView-input" value={this.previewScript} onChange={this.onPreviewScriptChange} + style={{ left: `calc(50% - ${Math.min(75, (previewDoc ? this.previewPanelWidth() / 2 : 75))}px)` }} /> + </div>); } get documentKeysCheckList() { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 9bd32a89f..d22418b2c 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -19,6 +19,7 @@ import { CurrentUserUtils } from '../../../server/authentication/models/current_ import { CollectionDockingView } from './CollectionDockingView'; import { DocumentManager } from '../../util/DocumentManager'; import { List } from '../../../new_fields/List'; +import { Docs } from '../../documents/Documents'; export interface TreeViewProps { @@ -141,6 +142,10 @@ class TreeView extends React.Component<TreeViewProps> { if (!e.isPropagationStopped() && this.props.document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Open as Workspace", event: undoBatch(() => Main.Instance.openWorkspace(this.props.document)) }); ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.document) }); + ContextMenu.Instance.addItem({ + description: "Open Fields", event: () => CollectionDockingView.Instance.AddRightSplit(Docs.KVPDocument(this.props.document, + { title: this.props.document.title + ".kvp", width: 300, height: 300 })) + }); if (DocumentManager.Instance.getDocumentViews(this.props.document).length) { ContextMenu.Instance.addItem({ description: "Focus", event: () => DocumentManager.Instance.getDocumentViews(this.props.document).map(view => view.props.focus(this.props.document)) }); } diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss index ed56ad268..db8b84832 100644 --- a/src/client/views/collections/CollectionVideoView.scss +++ b/src/client/views/collections/CollectionVideoView.scss @@ -2,7 +2,7 @@ .collectionVideoView-cont{ width: 100%; height: 100%; - position: absolute; + position: inherit; top: 0; left:0; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 718a75770..080c484f4 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -79,6 +79,46 @@ export class MarqueeView extends React.Component<MarqueeViewProps> y += 40 * this.props.getTransform().Scale; }) })(); + } else if (e.key === "t" && e.ctrlKey) { + //heuristically converts pasted text into a table. + // assumes each entry is separated by a tab + // skips all rows until it gets to a row with more than one entry + // assumes that 1st row has header entry for each column + // assumes subsequent rows have entries for each column header OR + // any row that has only one column is a section header-- this header is then added as a column to subsequent rows until the next header + // assumes each cell is a string or a number + e.preventDefault(); + (async () => { + let text: string = await navigator.clipboard.readText(); + let ns = text.split("\n").filter(t => t.trim() != "\r" && t.trim() != ""); + while (ns.length > 0 && ns[0].split("\t").length < 2) + ns.splice(0, 1); + if (ns.length > 0) { + let columns = ns[0].split("\t"); + let docList: Doc[] = []; + let groupAttr: string | number = ""; + for (let i = 1; i < ns.length - 1; i++) { + let values = ns[i].split("\t"); + if (values.length === 1 && columns.length > 1) { + groupAttr = values[0]; + continue; + } + let doc = new Doc(); + columns.forEach((col, i) => { + console.log(values[i] + " " + Number(values[i]).toString()); + doc[columns[i]] = (values.length > i ? ((values[i].indexOf(Number(values[i]).toString()) !== -1) ? Number(values[i]) : values[i]) : undefined); + }); + if (groupAttr) { + doc["_group"] = groupAttr; + } + doc.title = i.toString(); + docList.push(doc); + } + let newCol = Docs.SchemaDocument(docList, { x: x, y: y, title: "-dropped table-", width: 300, height: 100 }); + newCol.proto!.schemaColumns = new List<string>([...(groupAttr ? ["_group"] : []), ...columns.filter(c => c)]); + this.props.addDocument(newCol, false); + } + })(); } else { let newBox = Docs.TextDocument({ width: 200, height: 100, x: x, y: y, title: "-typed text-" }); this.props.addLiveTextDocument(newBox); @@ -318,7 +358,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps> @computed get marqueeDiv() { let v = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); - return <div className="marquee" style={{ width: `${Math.abs(v[0])}`, height: `${Math.abs(v[1])}` }} > + return <div className="marquee" style={{ width: `${Math.abs(v[0])}`, height: `${Math.abs(v[1])}`, zIndex: 2000 }} > <span className="marquee-legend" /> </div>; } @@ -326,11 +366,11 @@ export class MarqueeView extends React.Component<MarqueeViewProps> render() { let p = this.props.getContainerTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); return <div className="marqueeView" style={{ borderRadius: "inherit" }} onClick={this.onClick} onPointerDown={this.onPointerDown}> - <div style={{ position: "absolute", transform: `translate(${p[0]}px, ${p[1]}px)` }} > - <div ref={this._mainCont} style={{ position: "absolute", transform: `translate(${-p[0]}px, ${-p[1]}px)` }} > + <div style={{ position: "relative", transform: `translate(${p[0]}px, ${p[1]}px)` }} > + {!this._visible ? null : this.marqueeDiv} + <div ref={this._mainCont} style={{ transform: `translate(${-p[0]}px, ${-p[1]}px)` }} > {this.props.children} </div> - {!this._visible ? null : this.marqueeDiv} </div> </div>; } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 39d216da0..817a23ce8 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -228,7 +228,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF const screenWidth = Math.min(50 * NumCast(this.props.Document.nativeWidth, 0), 1800); let fadeUp = .75 * screenWidth; let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth; - zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; + zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? Math.sqrt(Math.sqrt(fadeDown / w)) : w / fadeUp))) : 1; return ( <div className="collectionFreeFormDocumentView-container" ref={this._mainCont} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 8bdf34181..34b6c5e70 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -7,7 +7,7 @@ import { VideoBox } from "./VideoBox"; import { AudioBox } from "./AudioBox"; import { DocumentContentsView } from "./DocumentContentsView"; import { Transform } from "../../util/Transform"; -import { returnFalse, emptyFunction } from "../../../Utils"; +import { returnFalse, emptyFunction, returnOne } from "../../../Utils"; import { CollectionView } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; @@ -18,6 +18,7 @@ import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField import { IconField } from "../../../new_fields/IconField"; import { RichTextField } from "../../../new_fields/RichTextField"; import { DateField } from "../../../new_fields/DateField"; +import { NumCast } from "../../../new_fields/Types"; // @@ -82,14 +83,15 @@ export class FieldView extends React.Component<FieldViewProps> { return <p>{field.date.toLocaleString()}</p>; } else if (field instanceof Doc) { + let returnHundred = () => 100; return ( <DocumentContentsView Document={field} addDocument={undefined} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={() => 1} - PanelWidth={() => 100} - PanelHeight={() => 100} + ContentScaling={returnOne} + PanelWidth={returnHundred} + PanelHeight={returnHundred} isTopMost={true} //TODO Why is this top most? selectOnLoad={false} focus={emptyFunction} diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 458a62c5b..4a29c1949 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -19,7 +19,7 @@ box-sizing: border-box; background-color: inherit; border-style: solid; - overflow-y: scroll; + overflow-y: auto; overflow-x: hidden; color: initial; height: 100%; @@ -27,7 +27,6 @@ } .formattedTextBox-cont-hidden { - overflow: hidden; pointer-events: none; } .formattedTextBox-inner-rounded { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 37dc05ca5..7ebc31b0a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -262,8 +262,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (!this.props.isOverlay) { FormattedTextBox.InputBoxOverlay = this; } else { - if (this._proseRef.current) { - this._proseRef.current.scrollTop = FormattedTextBox.InputBoxOverlayScroll; + if (this._ref.current) { + this._ref.current.scrollTop = FormattedTextBox.InputBoxOverlayScroll; } } } diff --git a/src/client/views/nodes/IconBox.scss b/src/client/views/nodes/IconBox.scss index 85bbdeb59..f6d9860a3 100644 --- a/src/client/views/nodes/IconBox.scss +++ b/src/client/views/nodes/IconBox.scss @@ -1,7 +1,7 @@ @import "../globalCssVariables"; .iconBox-container { - position: absolute; + position: inherit; left:0; top:0; height: 100%; @@ -14,7 +14,7 @@ background: white; } .iconBox-label { - position: inherit; + position: absolute; width:max-content; font-size: 14px; margin-top: 3px; diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss index ff6885965..4f305dc91 100644 --- a/src/client/views/nodes/KeyValuePair.scss +++ b/src/client/views/nodes/KeyValuePair.scss @@ -26,4 +26,12 @@ .keyValuePair-td-value { display:inline-block; overflow: scroll; + img { + max-height: 36px; + width: auto; + } + .videobox-cont{ + width: auto; + max-height: 36px; + } }
\ No newline at end of file diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index c08049a39..625ba0d6a 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -198,11 +198,11 @@ export namespace Doc { let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 }); //let linkDoc = new Doc; linkDoc.proto!.title = "-link name-"; - linkDoc.linkDescription = ""; - linkDoc.linkTags = "Default"; + linkDoc.proto!.linkDescription = ""; + linkDoc.proto!.linkTags = "Default"; - linkDoc.linkedTo = target; - linkDoc.linkedFrom = source; + linkDoc.proto!.linkedTo = target; + linkDoc.proto!.linkedFrom = source; let linkedFrom = Cast(target.linkedFromDocs, listSpec(Doc)); if (!linkedFrom) { |