From 821bd7bb1b2a59459c63ecfbe9c513e5f36a7e43 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 20 Apr 2020 01:39:15 -0400 Subject: fixed runtime errors for AntimodeMenu and from current_user_utils not initializing properly --- src/client/util/RichTextMenu.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 3f0ec7aa5..4a9a4c10f 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -445,8 +445,8 @@ export default class RichTextMenu extends AntimodeMenu { } const button = - ; const dropdownContent = @@ -790,11 +790,11 @@ export default class RichTextMenu extends AntimodeMenu {
{this.getDragger()}
-- cgit v1.2.3-70-g09d2 From 49ebcb56488669c1f416c583a9b8c7914e5b6d34 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 20 Apr 2020 16:23:39 -0400 Subject: fixed moving documents in tree views --- src/client/util/DragManager.ts | 2 +- src/client/views/collections/CollectionTreeView.tsx | 13 +++++++------ src/server/authentication/models/current_user_utils.ts | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 3e9a5b63a..3ea030171 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -19,7 +19,7 @@ import { DateField } from "../../new_fields/DateField"; import { DocumentView } from "../views/nodes/DocumentView"; import { UndoManager } from "./UndoManager"; -export type dropActionType = "place" | "alias" | "copy" | undefined; +export type dropActionType = "alias" | "copy" | "move" | undefined; // undefined = move export function SetupDrag( _reference: React.RefObject, docFunc: () => Doc | Promise | undefined, diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 34f0f2313..d8e2c8841 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -228,7 +228,8 @@ class TreeView extends React.Component { addDoc = (doc: Doc) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) || addDoc(doc); } const movedDocs = (de.complete.docDragData.treeViewId === this.props.treeViewId[Id] ? de.complete.docDragData.draggedDocuments : de.complete.docDragData.droppedDocuments); - return ((de.complete.docDragData.dropAction && (de.complete.docDragData.treeViewId !== this.props.treeViewId[Id])) || de.complete.docDragData.userDropAction) ? + const move = de.complete.docDragData.dropAction === "move" || de.complete.docDragData.dropAction; + return ((!move && (de.complete.docDragData.treeViewId !== this.props.treeViewId[Id])) || de.complete.docDragData.userDropAction) ? de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d) || added, false) : de.complete.docDragData.moveDocument ? movedDocs.reduce((added, d) => de.complete.docDragData?.moveDocument?.(d, undefined, addDoc) || added, false) @@ -335,7 +336,7 @@ class TreeView extends React.Component { {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document), this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, + StrCast(this.props.document.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath, this.props.onCheckedClick, this.props.onChildClick, this.props.ignoreFields)} ; @@ -456,7 +457,7 @@ class TreeView extends React.Component { pinToPres={emptyFunction} onClick={this.props.onChildClick || editTitle} dropAction={this.props.dropAction} - moveDocument={this.props.moveDocument} + moveDocument={this.move} removeDocument={this.removeDoc} ScreenToLocalTransform={this.getTransform} ContentScaling={returnOne} @@ -472,7 +473,7 @@ class TreeView extends React.Component { bringToFront={emptyFunction} dontRegisterView={BoolCast(this.props.treeViewId.dontRegisterChildren)} ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} + ContainingCollectionDoc={this.props.containingCollection} />} {this.props.treeViewHideHeaderFields() ? (null) : headerElements} @@ -657,7 +658,7 @@ export class CollectionTreeView extends CollectionSubView { - this.treedropDisposer && this.treedropDisposer(); + this.treedropDisposer?.(); if (this._mainEle = ele) { this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); } @@ -665,7 +666,7 @@ export class CollectionTreeView extends CollectionSubView Date: Mon, 20 Apr 2020 22:34:29 -0400 Subject: fixed search to avoid server crashes by stripping off initial ?*+ characters. made search parameters persistent on queryBox --- src/client/documents/Documents.ts | 1 + src/client/util/SearchUtil.ts | 2 +- src/client/views/nodes/QueryBox.tsx | 13 +++++-- src/client/views/search/IconBar.tsx | 4 +-- src/client/views/search/SearchBox.tsx | 40 +++++++++++----------- src/server/ApiManagers/SearchManager.ts | 17 ++++----- .../authentication/models/current_user_utils.ts | 1 + 7 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/client/util') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e3cc8ccfe..5ff8f29ec 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -140,6 +140,7 @@ export interface DocumentOptions { icon?: string; sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script + searchFileTypes?: List; // file types allowed in a search query strokeWidth?: number; treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view treeViewHideTitle?: boolean; // whether to hide the title of a tree view diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 2026bf940..6501da34a 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -44,7 +44,7 @@ export namespace SearchUtil { const { ids, highlighting } = result; const txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), { - qs: { ...options, q: query }, + qs: { ...options, q: query.replace(/^[ \+\?\*\|]*/, "") }, // a leading '+' leads to a server crash since findInFiles doesn't handle regex failures })); const fileids = txtresult ? txtresult.ids : []; diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index 947167200..76885eada 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -3,13 +3,14 @@ import { IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from '../../../new_fields/FieldSymbols'; -import { makeInterface } from "../../../new_fields/Schema"; -import { StrCast } from "../../../new_fields/Types"; +import { makeInterface, listSpec } from "../../../new_fields/Schema"; +import { StrCast, Cast } from "../../../new_fields/Types"; import { SelectionManager } from "../../util/SelectionManager"; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./QueryBox.scss"; +import { List } from "../../../new_fields/List"; type QueryDocument = makeInterface<[typeof documentSchema]>; const QueryDocument = makeInterface(documentSchema); @@ -28,7 +29,13 @@ export class QueryBox extends ViewBoxAnnotatableComponent e.stopPropagation()} > - + this.dataDoc.searchQuery = q} + searchQuery={StrCast(this.dataDoc.searchQuery)} + setSearchFileTypes={q => this.dataDoc.searchFileTypes = new List(q)} + searchFileTypes={Cast(this.dataDoc.searchFileTypes, listSpec("string"), [])} + filterQquery={StrCast(this.dataDoc.filterQuery)} /> ; } } \ No newline at end of file diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx index 9cf5a9c87..9b7cf2fc6 100644 --- a/src/client/views/search/IconBar.tsx +++ b/src/client/views/search/IconBar.tsx @@ -25,7 +25,7 @@ library.add(faGlobeAsia); library.add(faBan); export interface IconBarProps { - setIcons: (icons: string[]) => {}; + setIcons: (icons: string[]) => void; } @@ -44,7 +44,7 @@ export class IconBar extends React.Component { @action.bound updateIcon(newArray: string[]) { - this._icons = newArray; + this._icons = newArray; this.props.setIcons?.(this._icons); } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index f332104fc..b0a49f750 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -19,13 +19,17 @@ import { FieldView } from '../nodes/FieldView'; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentView } from '../nodes/DocumentView'; import { SelectionManager } from '../../util/SelectionManager'; +import { listSpec } from '../../../new_fields/Schema'; library.add(faTimes); export interface SearchProps { id: string; - searchQuery?: string; + searchQuery: string; filterQquery?: string; + setSearchQuery: (q: string) => {}; + searchFileTypes: string[]; + setSearchFileTypes: (types: string[]) => {} } export enum Keys { @@ -37,7 +41,8 @@ export enum Keys { @observer export class SearchBox extends React.Component { - @observable private _searchString: string = ""; + private get _searchString() { return this.props.searchQuery; } + private set _searchString(value) { this.props.setSearchQuery(value); } @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; @observable private _results: [Doc, string[], string[]][] = []; @@ -72,20 +77,16 @@ export class SearchBox extends React.Component { this.resultsScrolled = this.resultsScrolled.bind(this); } - componentDidMount = () => { + componentDidMount = action(() => { if (this.inputRef.current) { this.inputRef.current.focus(); - runInAction(() => this._searchbarOpen = true); + this._searchbarOpen = true; } - if (this.props.searchQuery && this.props.filterQquery) { - console.log(this.props.searchQuery); - const sq = this.props.searchQuery; - runInAction(() => { - this._searchString = sq; - this.submitSearch(); - }); + if (this.props.searchQuery) { // bcz: why was this here? } && this.props.filterQquery) { + this._searchString = this.props.searchQuery; + this.submitSearch(); } - } + }) @action @@ -133,7 +134,10 @@ export class SearchBox extends React.Component { //this also serves as an indicator if the word status filter is applied @observable private _filterOpen: boolean = false; //if icons = all icons, then no icon filter is applied - @observable private _icons: string[] = this._allIcons; + get _icons() { return this.props.searchFileTypes; } + set _icons(value) { + this.props.setSearchFileTypes(value); + } //if all of these are true, no key filter is applied @observable private _titleFieldStatus: boolean = true; @observable private _authorFieldStatus: boolean = true; @@ -206,12 +210,6 @@ export class SearchBox extends React.Component { return this._icons.length === this._allIcons.length ? undefined : this._icons; } - @action.bound - updateIcon(newArray: string[]) { this._icons = newArray; } - - @action.bound - getIcons(): string[] { return this._icons; } - //TODO: basically all of this //gets all of the collections of all the docviews that are selected //if a collection is the only thing selected, search only in that collection (not its container) @@ -648,7 +646,9 @@ export class SearchBox extends React.Component {
- this._icons = icons} /> + { + this._icons = icons; + }} />
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts index 9e1cc120d..753c31fcf 100644 --- a/src/server/ApiManagers/SearchManager.ts +++ b/src/server/ApiManagers/SearchManager.ts @@ -45,16 +45,13 @@ export class SearchManager extends ApiManager { return; } const resObj: { ids: string[], numFound: number, lines: string[] } = { ids: [], numFound: 0, lines: [] }; - try { - const results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, pathToDirectory(Directory.text), ".txt$"); - for (const result in results) { - resObj.ids.push(path.basename(result, ".txt").replace(/upload_/, "")); - resObj.lines.push(results[result].line); - resObj.numFound++; - } - } - catch (e) { - console.error(e); + let results: any; + const dir = pathToDirectory(Directory.text); + results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, dir, ".txt$"); + for (const result in results) { + resObj.ids.push(path.basename(result, ".txt").replace(/upload_/, "")); + resObj.lines.push(results[result].line); + resObj.numFound++; } res.send(resObj); } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index e0ca5a468..3955f64fc 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -413,6 +413,7 @@ export class CurrentUserUtils { _width: 50, _height: 25, title: "Search", fontSize: 10, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc, + searchFileTypes: new List([DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.VID, DocumentType.WEB, DocumentType.SCRIPTING]), targetContainer: new PrefetchProxy(sidebarContainer) as any as Doc, lockedPosition: true, onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel") -- cgit v1.2.3-70-g09d2 From e091a465b860f0b205fbfa5ac6feedaf4f98e1dd Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 21 Apr 2020 01:15:17 -0400 Subject: added MakeClone to alias documents in a collection. fixed embedded custom templates. --- src/client/util/DragManager.ts | 2 +- src/client/util/RichTextSchema.tsx | 10 ++++---- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/search/SearchBox.scss | 3 ++- src/new_fields/Doc.ts | 43 +++++++++++++++++++++++++++++++-- 5 files changed, 50 insertions(+), 10 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 3ea030171..42a78a4bf 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -205,7 +205,7 @@ export namespace DragManager { e.docDragData && (e.docDragData.droppedDocuments = dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) : - dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d) + dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeClone(d) : d) ); e.docDragData?.droppedDocuments.forEach((drop: Doc, i: number) => (dragData?.removeDropProperties || []).concat(Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), [])).map(prop => drop[prop] = undefined) diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 0599b3ebe..1522f5e21 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -27,11 +27,11 @@ import ParagraphNodeSpec from "./ParagraphNodeSpec"; import { Transform } from "./Transform"; import React = require("react"); -const - blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], +const + blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], - preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], - brDOM: DOMOutputSpecArray = ["br"], + preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], + brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]; // :: Object @@ -853,7 +853,7 @@ export class DashDocView { this._renderDisposer?.(); this._renderDisposer = reaction(() => { if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { - finalLayout.rootDocument = dashDoc.aliasOf; + finalLayout.rootDocument = dashDoc.aliasOf; // bcz: check on this ... why is it here? } const layoutKey = StrCast(finalLayout.layoutKey); const finalKey = layoutKey && StrCast(finalLayout[layoutKey]).split("'")?.[1]; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8a05cfb0d..286044ab2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -561,7 +561,7 @@ export class DocumentView extends DocComponent(Docu static findTemplate(templateName: string, type: string, signature: string) { let docLayoutTemplate: Opt; const iconViews = DocListCast(Cast(Doc.UserDoc()["template-icons"], Doc, null)?.data); - const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data); + const templBtns = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data); const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data); const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data); const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index f0223ca76..bb62113a1 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -9,7 +9,8 @@ position: absolute; font-size: 10px; line-height: 1; - overflow: auto; + overflow-y: auto; + overflow-x: visible; background: lightgrey, } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 8e8f0928c..5f790f886 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -565,8 +565,9 @@ export namespace Doc { } else if (cfield instanceof ComputedField) { copy[key] = ComputedField.MakeFunction(cfield.script.originalScript); } else if (field instanceof ObjectField) { - copy[key] = key.includes("layout[") && doc[key] instanceof Doc ? Doc.MakeCopy(doc[key] as Doc, false) : - doc[key] instanceof Doc ? doc[key] : ObjectField.MakeCopy(field); + copy[key] = doc[key] instanceof Doc ? + key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields + ObjectField.MakeCopy(field); } else if (field instanceof Promise) { debugger; //This shouldn't happend... } else { @@ -578,6 +579,44 @@ export namespace Doc { return copy; } + export function MakeClone(doc: Doc, cloneProto: boolean = true): Doc { + const copy = new Doc(undefined, true); + const exclude = Cast(doc.excludeFields, listSpec("string"), []); + Object.keys(doc).forEach(key => { + if (exclude.includes(key)) return; + const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); + const field = ProxyField.WithoutProxy(() => doc[key]); + if (key === "proto" && cloneProto) { + if (doc[key] instanceof Doc) { + copy[key] = Doc.MakeClone(doc[key]!, false); + } + } else { + if (field instanceof RefField) { + copy[key] = field; + } else if (cfield instanceof ComputedField) { + copy[key] = ComputedField.MakeFunction(cfield.script.originalScript); + } else if (field instanceof ObjectField) { + const list = Cast(doc[key], listSpec(Doc)); + if (list !== undefined && !(list instanceof Promise)) { + copy[key] = new List(list.filter(d => d instanceof Doc).map(d => Doc.MakeCopy(d as Doc, false))); + } else { + copy[key] = doc[key] instanceof Doc ? + key.includes("layout[") ? + Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields + ObjectField.MakeCopy(field); + } + } else if (field instanceof Promise) { + debugger; //This shouldn't happend... + } else { + copy[key] = field; + } + } + }); + Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true); + copy.cloneOf = doc; + return copy; + } + export function MakeDelegate(doc: Doc, id?: string, title?: string): Doc; export function MakeDelegate(doc: Opt, id?: string, title?: string): Opt; export function MakeDelegate(doc: Opt, id?: string, title?: string): Opt { -- cgit v1.2.3-70-g09d2 From 3d629495644631e6b614b1b48f1d32d6c7aeefc6 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 21 Apr 2020 17:25:17 -0400 Subject: added parameterization capability to layout strings. added Div's that can take Dash field values --- src/client/util/RichTextSchema.tsx | 6 ++-- src/client/views/DocumentDecorations.tsx | 4 +-- src/client/views/collections/CollectionView.tsx | 7 ++-- src/client/views/nodes/DocumentContentsView.tsx | 45 +++++++++++++++++++++---- 4 files changed, 46 insertions(+), 16 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 1522f5e21..d23962d5c 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -852,9 +852,9 @@ export class DashDocView { }; this._renderDisposer?.(); this._renderDisposer = reaction(() => { - if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { - finalLayout.rootDocument = dashDoc.aliasOf; // bcz: check on this ... why is it here? - } + // if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { + // finalLayout.rootDocument = dashDoc.aliasOf; // bcz: check on this ... why is it here? + // } const layoutKey = StrCast(finalLayout.layoutKey); const finalKey = layoutKey && StrCast(finalLayout[layoutKey]).split("'")?.[1]; if (finalLayout !== dashDoc && finalKey) { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index c8766a6b3..bd41788d4 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -3,7 +3,7 @@ import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faT import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DataSym } from "../../new_fields/Doc"; +import { Doc, DataSym, Field } from "../../new_fields/Doc"; import { PositionDocument } from '../../new_fields/documentSchemas'; import { ScriptField } from '../../new_fields/ScriptField'; import { Cast, StrCast, NumCast } from "../../new_fields/Types"; @@ -366,7 +366,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ self: selected.rootDoc, this: selected.layoutDoc }, console.log).result?.toString() || ""; } if (this._titleControlString.startsWith("#")) { - return selected.props.Document[this._titleControlString.substring(1)]?.toString() || "-unset-"; + return Field.toString(selected.props.Document[this._titleControlString.substring(1)] as Field) || "-unset-"; } return this._accumulatedTitle; } else if (SelectionManager.SelectedDocuments().length > 1) { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 178c3189b..4448fcf21 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -211,11 +211,8 @@ export class CollectionView extends Touchable { subItems.push({ description: "Carousel", event: () => func(CollectionViewType.Carousel), icon: "columns" }); subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" }); subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" }); - if (addExtras) switch (this.props.Document._viewType) { - case CollectionViewType.Freeform: { - subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) }); - break; - } + if (addExtras && this.props.Document._viewType === CollectionViewType.Freeform) { + subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) }); } addExtras && subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" }); !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: subItems, icon: "eye" }); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 7522af3a3..765416658 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -1,8 +1,8 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; -import { Doc, Opt } from "../../../new_fields/Doc"; -import { Cast, StrCast } from "../../../new_fields/Types"; -import { OmitKeys, Without } from "../../../Utils"; +import { Doc, Opt, Field } from "../../../new_fields/Doc"; +import { Cast, StrCast, NumCast } from "../../../new_fields/Types"; +import { OmitKeys, Without, emptyPath } from "../../../Utils"; import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; @@ -53,6 +53,31 @@ class ObserverJsxParser1 extends JsxParser { const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any; + +interface DivProps { + Document: Doc; +} + +@observer +export class Div extends React.Component { + render() { + const style: { [key: string]: any } = {}; + const divKeys = OmitKeys(this.props, ["children", "Document", "key", "__proto__"]).omit; + Object.keys(divKeys).map((prop: string) => { + let p = (this.props as any)[prop] as string; + if (p?.startsWith("@")) { // bcz: extend this to support expression -- is this really a script? + const key = p.substring(1); + const n = Cast(this.props.Document[key], "number", null); + p = n ? n.toString() : StrCast(this.props.Document[key], p); + } + style[prop] = p; + }); + return
+ {this.props.children} +
; + } +} + @observer export class DocumentContentsView extends React.Component boolean, @@ -102,21 +127,29 @@ export class DocumentContentsView extends React.Component 12 || !this.layout || !this.layoutDoc) ? (null) : + let layoutFrame = this.layout; + const replacer = (match: any, p1: string, offset: any, string: any) => { + const n = Cast(this.props.Document[p1], "number", null); + return n !== undefined ? n.toString() : StrCast(this.props.Document[p1], p1); + }; + layoutFrame = layoutFrame.replace(/\{([a-zA-Z0-9_-]+)\}/g, replacer); + return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) : this.props.forceLayout === "FormattedTextBox" && this.props.forceFieldKey ? : { console.log(test); }} -- cgit v1.2.3-70-g09d2