From 9fb7008b5cce6fd8973ec48cf6b067f3c4cfd363 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 23 Aug 2019 17:41:11 -0400 Subject: fixed documents disappearing without an x/y, fixed dropping something onto textbox making it a template, fixed treeview to show minimized documents. --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/collections/CollectionTreeView.tsx | 1 + .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 10 ++++++---- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2c5940467..ee2a57bd3 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,7 +1,7 @@ import { library, IconProp } from '@fortawesome/fontawesome-svg-core'; import { faLink, faTag, faTimes, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faStopCircle, faCloudUploadAlt, faSyncAlt, faShare } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, reaction, runInAction } from "mobx"; +import { action, computed, observable, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../new_fields/Doc"; import { List } from "../../new_fields/List"; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 7e1aacd5d..6e284a76f 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -373,6 +373,7 @@ class TreeView extends React.Component { return <>
, - bounds: (pos.x !== undefined && pos.y !== undefined) ? { x: pos.x, y: pos.y, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) } : undefined + bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) } }); } } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 91596e825..876d4c428 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -36,6 +36,7 @@ import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/Goog import { DocumentDecorations } from '../DocumentDecorations'; import { DictationManager } from '../../util/DictationManager'; import { ReplaceStep } from 'prosemirror-transform'; +import { DocumentType } from '../../documents/DocumentTypes'; library.add(faEdit); library.add(faSmile, faTextHeight, faUpload); @@ -256,10 +257,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let model: NodeType = (url.includes(".mov") || url.includes(".mp4")) ? schema.nodes.video : schema.nodes.image; this._editorView!.dispatch(this._editorView!.state.tr.insert(0, model.create({ src: url }))); e.stopPropagation(); - } else { - if (de.data instanceof DragManager.DocumentDragData) { - this.props.Document.layout = de.data.draggedDocuments[0]; - de.data.draggedDocuments[0].isTemplate = true; + } else if (de.data instanceof DragManager.DocumentDragData) { + const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0]; + if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) != "") { + this.props.Document.layout = draggedDoc; + draggedDoc.isTemplate = true; e.stopPropagation(); } } -- cgit v1.2.3-70-g09d2 From db44339760b07afeb0d383b44783ec96860bf51e Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 23 Aug 2019 17:53:15 -0400 Subject: fixed imagebox overflow. --- src/client/views/nodes/ImageBox.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index b1afa3f7d..00c069e1f 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -65,6 +65,7 @@ display:flex; align-items: center; height:100%; + overflow:hidden; .imageBox-fadeBlocker { width:100%; height:100%; -- cgit v1.2.3-70-g09d2 From dee6904f0fd4d54862bfd1c86611be294517951c Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 23 Aug 2019 18:03:47 -0400 Subject: fixed toggleDetail layout. --- src/new_fields/Doc.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 1d529ac84..6f1ef38d1 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -589,7 +589,8 @@ export namespace Doc { let miniLayout = await PromiseValue(d.miniLayout); let detailLayout = await PromiseValue(d.detailedLayout); d.layout !== miniLayout ? miniLayout && (d.layout = d.miniLayout) : detailLayout && (d.layout = detailLayout); - if (d.layout === detailLayout) Doc.GetProto(d).nativeWidth = Doc.GetProto(d).nativeHeight = undefined; + if (d.layout === detailLayout) d.nativeWidth = d.nativeHeight = 0; + if (StrCast(d.layout) !== "") d.nativeWidth = d.nativeHeight = undefined; }); } export function UseDetailLayout(d: Doc) { -- cgit v1.2.3-70-g09d2 From 91336f66d30c6a8830d9b69d7263ac72ecca3141 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 23 Aug 2019 18:40:42 -0400 Subject: removed autoheight --- src/client/views/DocumentDecorations.tsx | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index a28088032..bd510c3c5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -694,9 +694,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let canPush = this.targetDoc.data && this.targetDoc.data instanceof RichTextField; if (!canPush) return (null); let published = Doc.GetProto(this.targetDoc)[GoogleRef] !== undefined; - if (!published) { - this.targetDoc.autoHeight = true; - } let icon: IconProp = published ? (this.pushIcon as any) : cloud; return (
-- cgit v1.2.3-70-g09d2 From d237c67b236ce66e9bc711931e4c283a8c1e95f2 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 23 Aug 2019 18:46:35 -0400 Subject: linter --- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 876d4c428..d6ba1700a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -259,7 +259,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe e.stopPropagation(); } else if (de.data instanceof DragManager.DocumentDragData) { const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0]; - if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) != "") { + if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) !== "") { this.props.Document.layout = draggedDoc; draggedDoc.isTemplate = true; e.stopPropagation(); -- cgit v1.2.3-70-g09d2 From 4ab81702c2c78ae20c1984985aaef880d21aef9e Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Sat, 24 Aug 2019 10:05:09 -0400 Subject: removed duplicate search box class --- src/client/views/SearchBox.tsx | 183 ----------------------------------------- 1 file changed, 183 deletions(-) delete mode 100644 src/client/views/SearchBox.tsx (limited to 'src') diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx deleted file mode 100644 index 33cb63df5..000000000 --- a/src/client/views/SearchBox.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faObjectGroup, faSearch } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import * as rp from 'request-promise'; -import { Doc } from '../../new_fields/Doc'; -import { Id } from '../../new_fields/FieldSymbols'; -import { NumCast } from '../../new_fields/Types'; -import { DocServer } from '../DocServer'; -import { Docs } from '../documents/Documents'; -import { SetupDrag } from '../util/DragManager'; -import { SearchItem } from './search/SearchItem'; -import "./SearchBox.scss"; -import { Utils } from '../../Utils'; - -library.add(faSearch); -library.add(faObjectGroup); - -@observer -export class SearchBox extends React.Component { - @observable - searchString: string = ""; - - @observable private _open: boolean = false; - @observable private _resultsOpen: boolean = false; - - @observable - private _results: Doc[] = []; - - @action.bound - onChange(e: React.ChangeEvent) { - this.searchString = e.target.value; - } - - @action - submitSearch = async () => { - let query = this.searchString; - //gets json result into a list of documents that can be used - const results = await this.getResults(query); - - runInAction(() => { - this._resultsOpen = true; - this._results = results; - }); - } - - @action - getResults = async (query: string) => { - let response = await rp.get(Utils.prepend('/search'), { - qs: { - query - } - }); - let res: string[] = JSON.parse(response); - const fields = await DocServer.GetRefFields(res); - const docs: Doc[] = []; - for (const id of res) { - const field = fields[id]; - if (field instanceof Doc) { - docs.push(field); - } - } - return docs; - } - - @action - handleClickFilter = (e: Event): void => { - var className = (e.target as any).className; - var id = (e.target as any).id; - if (className !== "filter-button" && className !== "filter-form") { - this._open = false; - } - - } - - @action - handleClickResults = (e: Event): void => { - var className = (e.target as any).className; - var id = (e.target as any).id; - if (id !== "result") { - this._resultsOpen = false; - this._results = []; - } - - } - - componentWillMount() { - document.addEventListener('mousedown', this.handleClickFilter, false); - document.addEventListener('mousedown', this.handleClickResults, false); - } - - componentWillUnmount() { - document.removeEventListener('mousedown', this.handleClickFilter, false); - document.removeEventListener('mousedown', this.handleClickResults, false); - } - - @action - toggleFilterDisplay = () => { - this._open = !this._open; - } - - enter = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - this.submitSearch(); - } - } - - collectionRef = React.createRef(); - startDragCollection = async () => { - const results = await this.getResults(this.searchString); - const docs = results.map(doc => { - const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { - return Doc.MakeDelegate(doc); - } else { - return Doc.MakeAlias(doc); - } - }); - let x = 0; - let y = 0; - for (const doc of docs) { - doc.x = x; - doc.y = y; - const size = 200; - const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1); - if (aspect > 1) { - doc.height = size; - doc.width = size / aspect; - } else if (aspect > 0) { - doc.width = size; - doc.height = size * aspect; - } else { - doc.width = size; - doc.height = size; - } - doc.zoomBasis = 1; - x += 250; - if (x > 1000) { - x = 0; - y += 300; - } - } - return Docs.Create.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this.searchString}"` }); - } - - // Useful queries: - // Delegates of a document: {!join from=id to=proto_i}id:{protoId} - // Documents in a collection: {!join from=data_l to=id}id:{collectionProtoId} - render() { - return ( -
-
-
- - - - - {/* */} - {/* */} -
- {this._resultsOpen ? ( -
- {this._results.map(result => )} -
- ) : null} -
- {this._open ? ( -
- -
- filter by collection, key, type of node -
- -
- ) : null} -
- ); - } -} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 58226f1fa296c17b260e309c2880bf72e10f6da9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 25 Aug 2019 10:01:49 -0400 Subject: open on right always shows up in tree view now. added tooltips and cleaned up css. --- src/client/views/collections/CollectionTreeView.scss | 13 ++++++++----- src/client/views/collections/CollectionTreeView.tsx | 12 +++++------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 990979109..197e57808 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -31,7 +31,7 @@ position: relative; width: 15px; color: $intermediate-color; - margin-top: 4px; + margin-top: 3px; transform: scale(1.3, 1.3); } @@ -81,6 +81,9 @@ .treeViewItem-openRight { display: none; + height: 17px; + background: gray; + width: 15px; } .treeViewItem-border { @@ -95,15 +98,15 @@ .treeViewItem-openRight { display: inline-block; - height: 13px; - margin-top: 2px; - margin-left: 5px; + height: 17px; + background: #a8a7a7; + width: 15px; // display: inline; svg { display: block; padding: 0px; - margin: 0px; + margin-left: 3px; } } } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 6e284a76f..380054eb6 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -340,7 +340,7 @@ class TreeView extends React.Component { @computed get renderBullet() { - return
this.treeViewOpen = !this.treeViewOpen)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> + return
this.treeViewOpen = !this.treeViewOpen)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> {}
; } @@ -365,13 +365,11 @@ class TreeView extends React.Component { })}> {this.treeViewExpandedView} ); - let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document[this.fieldKey], listSpec(Doc), []) : []; - let openRight = dataDocs && dataDocs.indexOf(this.dataDoc) !== -1 ? (null) : ( -
- -
); + let openRight = (
+ +
); return <> -
Date: Sun, 25 Aug 2019 10:21:53 -0400 Subject: fixed sync of doc decorations with scrolled stacking/masonry views --- src/client/views/collections/CollectionStackingView.tsx | 8 +++++++- .../collections/CollectionStackingViewFieldColumn.tsx | 15 +++------------ 2 files changed, 10 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 4ab656744..a70743030 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -34,6 +34,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { _docXfs: any[] = []; _columnStart: number = 0; @observable private cursor: CursorProperty = "grab"; + @observable _scroll = 0; // used to force the document decoration to update when scrolling @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); } @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); } @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); } @@ -277,6 +278,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDocTransform(doc: Doc, dref: HTMLDivElement) { + let y = this._scroll; let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); let outerXf = Utils.GetScreenTransform(this._masonryGridRef!); let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); @@ -371,7 +373,11 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { let sections = (this.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc) : [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]); return (
e.stopPropagation()} > + ref={this.createRef} + onScroll={action((e: React.UIEvent) => this._scroll = e.currentTarget.scrollTop)} + onDrop={this.onDrop.bind(this)} + onContextMenu={this.onContextMenu} + onWheel={(e: React.WheelEvent) => e.stopPropagation()} > {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))} {!this.showAddAGroup ? (null) :
Math.min(d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, parent.columnWidth / parent.numGroupColumns); let height = () => parent.getDocHeight(pair.layout); let dref = React.createRef(); - let dxf = () => this.getDocTransform(pair.layout!, dref.current!); - this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height }); + let dxf = () => parent.getDocTransform(pair.layout!, dref.current!); + parent._docXfs.push({ dxf: dxf, width: width, height: height }); let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); let style = parent.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : parent.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` }; return
- {this.props.parent.getDisplayDoc(pair.layout, pair.data, dxf, width)} + {parent.getDisplayDoc(pair.layout, pair.data, dxf, width)}
; }); } - 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); - } - getValue = (value: string): any => { let parsed = parseInt(value); if (!isNaN(parsed)) { -- cgit v1.2.3-70-g09d2 From 6e7473a555df2631c917db3350d75986fa95b046 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 25 Aug 2019 12:49:15 -0400 Subject: fixed sorting for treeviews. fixed adding text items to stacking views. fixed how commands are added to collection view sub types. --- src/client/documents/Documents.ts | 1 + .../views/collections/CollectionStackingView.tsx | 7 +- .../CollectionStackingViewFieldColumn.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 22 +++--- src/client/views/collections/CollectionView.tsx | 10 +-- .../views/collections/CollectionViewChromes.tsx | 85 ++++++++-------------- 6 files changed, 54 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 47df17329..1e9d1687f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -77,6 +77,7 @@ export interface DocumentOptions { borderRounding?: string; schemaColumns?: List; dockingConfig?: string; + autoHeight?: boolean; dbDoc?: Doc; // [key: string]: Opt; } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index a70743030..6f22f2d2a 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -369,8 +369,11 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { contents: "+ ADD A GROUP" }; Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); - - let sections = (this.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc) : [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]); + let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]; + if (this.sectionFilter) { + let entries = Array.from(this.Sections.entries()); + sections = entries.sort(this.sortFunc); + } return (
{ let key = StrCast(this.props.parent.props.Document.sectionFilter); - let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value }); + let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, documentText: "@@@" + value, title: value, autoHeight: true }); newDoc[key] = this.getValue(this.props.heading); return this.props.parent.props.addDocument(newDoc); } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 380054eb6..04133fb5b 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -271,7 +271,7 @@ class TreeView extends React.Component { if (contents instanceof Doc || Cast(contents, listSpec(Doc))) { let remDoc = (doc: Doc) => this.remove(doc, key); - let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, !BoolCast(this.props.document.stackingHeadersSortDescending, true)); + let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen); @@ -299,7 +299,7 @@ class TreeView extends React.Component { const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined; if (expandKey !== undefined) { let remDoc = (doc: Doc) => this.remove(doc, expandKey); - let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, !BoolCast(this.props.document.stackingHeadersSortDescending, true)); + let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true); let docs = expandKey === "links" ? this.childLinks : this.childDocs; return
    {!docs ? (null) : @@ -431,12 +431,12 @@ class TreeView extends React.Component { }); } - let descending = BoolCast(containingCollection.stackingHeadersSortDescending, true); - docs.slice().sort(function (a, b): 1 | -1 { - let descA = descending ? b : a; - let descB = descending ? a : b; - let first = descA[String(containingCollection.sectionFilter)]; - let second = descB[String(containingCollection.sectionFilter)]; + let ascending = Cast(containingCollection.sortAscending, "boolean", null); + if (ascending !== undefined) docs.sort(function (a, b): 1 | -1 { + let descA = ascending ? b : a; + let descB = ascending ? a : b; + let first = descA.title; + let second = descB.title; // TODO find better way to sort how to sort.................. if (typeof first === 'number' && typeof second === 'number') { return (first - second) > 0 ? 1 : -1; @@ -450,7 +450,7 @@ class TreeView extends React.Component { // } return first > second ? 1 : -1; } - return descending ? 1 : -1; + return ascending ? 1 : -1; }); let rowWidth = () => panelWidth() - 20; @@ -583,7 +583,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { render() { Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); let dropAction = StrCast(this.props.Document.dropAction) as dropActionType; - let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, !BoolCast(this.props.Document.stackingHeadersSortDescending, true)); + let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false); let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); return !this.childDocs ? (null) : (
    ([Templates.Title.Layout]) }); TreeView.loadId = doc[Id]; - Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, !BoolCast(this.props.Document.stackingHeadersSortDescending, true)); + Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false); })} /> {this.props.Document.workspaceLibrary ? this.renderNotifsButton : (null)} {this.props.Document.allowClear ? this.renderClearButton : (null)} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 3a8253720..6182e82f4 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -77,12 +77,10 @@ export class CollectionView extends React.Component { if (this.isAnnotationOverlay || this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking) { return [(null), this.SubViewHelper(type, renderProps)]; } - else { - return [ - (), - this.SubViewHelper(type, renderProps) - ]; - } + return [ + , + this.SubViewHelper(type, renderProps) + ]; } get isAnnotationOverlay() { return this.props.fieldExt ? true : false; } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 1156d8fa7..b2df0e747 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -20,7 +20,6 @@ import { CollectionView } from "./CollectionView"; import "./CollectionViewChromes.scss"; import * as Autosuggest from 'react-autosuggest'; import KeyRestrictionRow from "./KeyRestrictionRow"; -import { Docs } from "../../documents/Documents"; const datepicker = require('js-datepicker'); interface CollectionViewChromeProps { @@ -41,20 +40,33 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); export class CollectionViewBaseChrome extends React.Component { //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) - private _buttonizableCommands = [{ + _templateCommand = { + title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"], + immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined + }; + _contentCommand = { // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting... title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"], immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List(draggedDocs.map((d: any) => Doc.MakeAlias(d))) - }, - { - title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"], - immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined - }, - { + }; + _viewCommand = { title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"], immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1 }, initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; } - }]; + }; + _freeform_commands = [this._contentCommand, this._templateCommand, this._viewCommand]; + _stacking_commands = [this._contentCommand, this._templateCommand]; + _masonry_commands = [this._contentCommand, this._templateCommand]; + _tree_commands = []; + private get _buttonizableCommands() { + switch (this.props.type) { + case CollectionViewType.Tree: return this._tree_commands; + case CollectionViewType.Stacking: return this._stacking_commands; + case CollectionViewType.Masonry: return this._stacking_commands; + case CollectionViewType.Freeform: return this._freeform_commands; + } + return []; + } private _picker: any; private _commandRef = React.createRef(); private _autosuggestRef = React.createRef(); @@ -520,18 +532,13 @@ export class CollectionStackingViewChrome extends React.Component -
    GROUP ITEMS BY: -
    +
    +
    + +
    this.sectionFilter} @@ -637,7 +644,7 @@ export class CollectionTreeViewChrome extends React.Component => { @@ -685,7 +692,11 @@ export class CollectionTreeViewChrome extends React.Component { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; }; + @action toggleSort = () => { + if (this.props.CollectionView.props.Document.sortAscending) this.props.CollectionView.props.Document.sortAscending = undefined; + else if (this.props.CollectionView.props.Document.sortAscending === undefined) this.props.CollectionView.props.Document.sortAscending = false; + else this.props.CollectionView.props.Document.sortAscending = true; + } @action resetValue = () => { this._currentKey = this.sectionFilter; }; render() { @@ -695,42 +706,10 @@ export class CollectionTreeViewChrome extends React.Component Sort
    -
    +
    -
    -
    - GROUP ITEMS BY: -
    -
    - this.sectionFilter} - autosuggestProps={ - { - resetValue: this.resetValue, - value: this._currentKey, - onChange: this.onKeyChange, - autosuggestProps: { - inputProps: - { - value: this._currentKey, - onChange: this.onKeyChange - }, - getSuggestionValue: this.getSuggestionValue, - suggestions: this.suggestions, - alwaysRenderSuggestions: true, - renderSuggestion: this.renderSuggestion, - onSuggestionsFetchRequested: this.onSuggestionFetch, - onSuggestionsClearRequested: this.onSuggestionClear - } - }} - oneLine - SetValue={this.setValue} - contents={this.sectionFilter ? this.sectionFilter : "N/A"} - /> -
    -
    ); } -- cgit v1.2.3-70-g09d2 From 3531339719a70f73b3cc2312aeeafdc64c8574c4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 25 Aug 2019 17:39:39 -0400 Subject: cleaned up text input to simplify list interactions and preserve styles across carriage returns. --- src/client/util/ProsemirrorExampleTransfer.ts | 146 +++++++++++++++----------- 1 file changed, 84 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index c38f84551..709b84765 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -1,7 +1,7 @@ import { Schema, NodeType } from "prosemirror-model"; import { wrapIn, setBlockType, chainCommands, toggleMark, exitCode, - joinUp, joinDown, lift, selectParentNode + joinUp, joinDown, lift, selectParentNode, splitBlockKeepMarks, splitBlock, createParagraphNear, liftEmptyBlock } from "prosemirror-commands"; import { wrapInList, splitListItem, liftListItem, sinkListItem } from "prosemirror-schema-list"; import { undo, redo } from "prosemirror-history"; @@ -30,79 +30,101 @@ export default function buildKeymap>(schema: S, mapKeys?: bind("Shift-Mod-z", redo); bind("Backspace", undoInputRule); - if (!mac) { - bind("Mod-y", redo); - } + !mac && bind("Mod-y", redo); bind("Alt-ArrowUp", joinUp); bind("Alt-ArrowDown", joinDown); bind("Mod-BracketLeft", lift); bind("Escape", selectParentNode); - if (type = schema.marks.strong) { - bind("Mod-b", toggleMark(type)); - bind("Mod-B", toggleMark(type)); - } - if (type = schema.marks.em) { - bind("Mod-i", toggleMark(type)); - bind("Mod-I", toggleMark(type)); - } - if (type = schema.marks.underline) { - bind("Mod-u", toggleMark(type)); - bind("Mod-U", toggleMark(type)); - } - if (type = schema.marks.code) { - bind("Mod-`", toggleMark(type)); - } + bind("Mod-b", toggleMark(schema.marks.strong)); + bind("Mod-B", toggleMark(schema.marks.strong)); - if (type = schema.nodes.bullet_list) { - bind("Ctrl-.", wrapInList(type)); - } - if (type = schema.nodes.ordered_list) { - bind("Ctrl-n", wrapInList(type)); - } - if (type = schema.nodes.blockquote) { - bind("Ctrl->", wrapIn(type)); + bind("Mod-i", toggleMark(schema.marks.em)); + bind("Mod-I", toggleMark(schema.marks.em)); + + bind("Mod-u", toggleMark(schema.marks.underline)); + bind("Mod-U", toggleMark(schema.marks.underline)); + + bind("Mod-`", toggleMark(schema.marks.code)); + + bind("Ctrl-.", wrapInList(schema.nodes.bullet_list)); + + bind("Ctrl-n", wrapInList(schema.nodes.ordered_lis)); + + bind("Ctrl->", wrapIn(schema.nodes.blockquote)); + + + let cmd = chainCommands(exitCode, (state, dispatch) => { + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(schema.nodes.hard_break.create()).scrollIntoView()); + return true; + } + return false; + }); + bind("Mod-Enter", cmd); + bind("Shift-Enter", cmd); + mac && bind("Ctrl-Enter", cmd); + + + bind("Shift-Ctrl-0", setBlockType(schema.nodes.paragraph)); + + bind("Shift-Ctrl-\\", setBlockType(schema.nodes.code_block)); + + for (let i = 1; i <= 6; i++) { + bind("Shift-Ctrl-" + i, setBlockType(schema.nodes.heading, { level: i })); } - if (type = schema.nodes.hard_break) { - let br = type, cmd = chainCommands(exitCode, (state, dispatch) => { - if (dispatch) { - dispatch(state.tr.replaceSelectionWith(br.create()).scrollIntoView()); - return true; - } - return false; + + let hr = schema.nodes.horizontal_rule; + bind("Mod-_", (state: EditorState, dispatch: (tx: Transaction) => void) => { + dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); + return true; + }); + + bind("Mod-s", TooltipTextMenu.insertStar); + + bind("Shift-Tab", (state: EditorState, dispatch: (tx: Transaction) => void) => { + var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + liftListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { + marks && tx2.ensureMarks(marks); + marks && tx2.setStoredMarks(marks); + dispatch(tx2); }); - bind("Mod-Enter", cmd); - bind("Shift-Enter", cmd); - if (mac) { - bind("Ctrl-Enter", cmd); + }); + bind("Tab", (state: EditorState, dispatch: (tx: Transaction) => void) => { + var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { + marks && tx2.ensureMarks(marks); + marks && tx2.setStoredMarks(marks); + dispatch(tx2); + })) { + wrapInList(schema.nodes.bullet_list)(state, (tx2: Transaction) => { + marks && tx2.ensureMarks(marks); + marks && tx2.setStoredMarks(marks); + dispatch(tx2); + }); } - } - if (type = schema.nodes.list_item) { - bind("Enter", splitListItem(type)); - bind("Shift-Tab", liftListItem(type)); - bind("Tab", sinkListItem(type)); - } - if (type = schema.nodes.paragraph) { - bind("Shift-Ctrl-0", setBlockType(type)); - } - if (type = schema.nodes.code_block) { - bind("Shift-Ctrl-\\", setBlockType(type)); - } - if (type = schema.nodes.heading) { - for (let i = 1; i <= 6; i++) { - bind("Shift-Ctrl-" + i, setBlockType(type, { level: i })); + }); + bind("Enter", (state: EditorState, dispatch: (tx: Transaction) => void) => { + var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + if (!splitListItem(schema.nodes.list_item)(state, (tx3: Transaction) => { + marks && tx3.ensureMarks(marks); + marks && tx3.setStoredMarks(marks); + dispatch(tx3); + })) { + if (!splitBlockKeepMarks(state, (tx3: Transaction) => { + marks && tx3.ensureMarks(marks); + marks && tx3.setStoredMarks(marks); + if (!liftListItem(schema.nodes.list_item)(state, (tx4: Transaction) => dispatch(tx4))) { + dispatch(tx3); + } + })) { + return false; + } } - } - if (type = schema.nodes.horizontal_rule) { - let hr = type; - bind("Mod-_", (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); - return true; - }); - } + return true; + }); - bind("Mod-s", TooltipTextMenu.insertStar); return keys; } -- cgit v1.2.3-70-g09d2 From 939074601016a674d6a01922bab1383684fce63f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 25 Aug 2019 22:55:51 -0400 Subject: added sub-bullet types to prosemirror --- src/client/util/ProsemirrorExampleTransfer.ts | 40 ++++++++++++------------ src/client/util/RichTextRules.ts | 8 +++++ src/client/util/RichTextSchema.tsx | 45 +++++++++++++++++++++++++-- src/client/util/TooltipTextMenu.tsx | 3 ++ 4 files changed, 74 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 709b84765..b928532d6 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -1,14 +1,10 @@ -import { Schema, NodeType } from "prosemirror-model"; -import { - wrapIn, setBlockType, chainCommands, toggleMark, exitCode, - joinUp, joinDown, lift, selectParentNode, splitBlockKeepMarks, splitBlock, createParagraphNear, liftEmptyBlock -} from "prosemirror-commands"; -import { wrapInList, splitListItem, liftListItem, sinkListItem } from "prosemirror-schema-list"; -import { undo, redo } from "prosemirror-history"; +import { chainCommands, exitCode, joinDown, joinUp, lift, selectParentNode, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn } from "prosemirror-commands"; +import { redo, undo } from "prosemirror-history"; import { undoInputRule } from "prosemirror-inputrules"; -import { Transaction, EditorState } from "prosemirror-state"; +import { Schema } from "prosemirror-model"; +import { liftListItem, splitListItem, wrapInList } from "prosemirror-schema-list"; +import { EditorState, Transaction } from "prosemirror-state"; import { TooltipTextMenu } from "./TooltipTextMenu"; -import { Statement } from "../northstar/model/idea/idea"; const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; @@ -40,8 +36,8 @@ export default function buildKeymap>(schema: S, mapKeys?: bind("Mod-b", toggleMark(schema.marks.strong)); bind("Mod-B", toggleMark(schema.marks.strong)); - bind("Mod-i", toggleMark(schema.marks.em)); - bind("Mod-I", toggleMark(schema.marks.em)); + bind("Mod-e", toggleMark(schema.marks.em)); + bind("Mod-E", toggleMark(schema.marks.em)); bind("Mod-u", toggleMark(schema.marks.underline)); bind("Mod-U", toggleMark(schema.marks.underline)); @@ -50,7 +46,7 @@ export default function buildKeymap>(schema: S, mapKeys?: bind("Ctrl-.", wrapInList(schema.nodes.bullet_list)); - bind("Ctrl-n", wrapInList(schema.nodes.ordered_lis)); + bind("Ctrl-n", wrapInList(schema.nodes.ordered_list)); bind("Ctrl->", wrapIn(schema.nodes.blockquote)); @@ -91,20 +87,24 @@ export default function buildKeymap>(schema: S, mapKeys?: dispatch(tx2); }); }); - bind("Tab", (state: EditorState, dispatch: (tx: Transaction) => void) => { + + let bulletFunc = (state: EditorState, dispatch: (tx: Transaction) => void) => { + var ref = state.selection; + var range = ref.$from.blockRange(ref.$to); var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { + let depth = range && range.depth ? range.depth : 0; + let nodeType = depth == 2 ? schema.nodes.cap_alphabet_list : depth == 4 ? schema.nodes.roman_list : depth == 6 ? schema.nodes.alphabet_list : schema.nodes.ordered_list; + + if (!wrapInList(nodeType)(state, (tx2: Transaction) => { marks && tx2.ensureMarks(marks); marks && tx2.setStoredMarks(marks); dispatch(tx2); })) { - wrapInList(schema.nodes.bullet_list)(state, (tx2: Transaction) => { - marks && tx2.ensureMarks(marks); - marks && tx2.setStoredMarks(marks); - dispatch(tx2); - }); + console.log("bullet fail"); } - }); + } + bind("Tab", (state: EditorState, dispatch: (tx: Transaction) => void) => bulletFunc(state, dispatch)); + bind("Enter", (state: EditorState, dispatch: (tx: Transaction) => void) => { var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); if (!splitListItem(schema.nodes.list_item)(state, (tx3: Transaction) => { diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index 3b8396510..89933650b 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -26,6 +26,14 @@ export const inpRules = { match => ({ order: +match[1] }), (match, node) => node.childCount + node.attrs.order === +match[1] ), + // 1. ordered list + wrappingInputRule( + /^([a-z]+)\.\s$/, + schema.nodes.alphabet_list, + match => ({ order: +match[1] }), + (match, node) => node.childCount + node.attrs.order === +match[1] + ), + // * bullet list wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 9fdda4845..a8ce4731c 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -173,7 +173,46 @@ export const nodes: { [index: string]: NodeSpec } = { ordered_list: { ...orderedList, content: 'list_item+', - group: 'block' + group: 'block', + attrs: { + bulletStyle: { default: "decimal" }, + }, + toDOM(node: Node) { + return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0] + } + }, + alphabet_list: { + ...orderedList, + content: 'list_item+', + group: 'block', + attrs: { + bulletStyle: { default: "lower-alpha" }, + }, + toDOM(node: Node) { + return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0] + } + }, + cap_alphabet_list: { + ...orderedList, + content: 'list_item+', + group: 'block', + attrs: { + bulletStyle: { default: "upper-alpha" }, + }, + toDOM(node: Node) { + return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0] + } + }, + roman_list: { + ...orderedList, + content: 'list_item+', + group: 'block', + attrs: { + bulletStyle: { default: "lower-roman" }, + }, + toDOM(node: Node) { + return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0] + } }, //this doesn't currently work for some reason bullet_list: { @@ -181,7 +220,9 @@ export const nodes: { [index: string]: NodeSpec } = { content: 'list_item+', group: 'block', // parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }], - // toDOM() { return ulDOM } + // toDOM() { return ['ol', { + // style: 'list-type: hebrew' + // }] } }, //bullet_list: { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 4672dd246..7a0c6f8c5 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -172,6 +172,9 @@ export class TooltipTextMenu { this.listTypeToIcon = new Map(); this.listTypeToIcon.set(schema.nodes.bullet_list, ":"); this.listTypeToIcon.set(schema.nodes.ordered_list, "1)"); + this.listTypeToIcon.set(schema.nodes.alphabet_list, "a)"); + this.listTypeToIcon.set(schema.nodes.cap_alphabet_list, "A)"); + this.listTypeToIcon.set(schema.nodes.roman_list, "i."); // this.listTypeToIcon.set(schema.nodes.bullet_list, "⬜"); this.listTypes = Array.from(this.listTypeToIcon.keys()); -- cgit v1.2.3-70-g09d2