From 525766cd02ec38174334e62709c36a3b0caa208a Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 22 Feb 2020 14:06:39 -0500 Subject: new file --- src/client/views/SearchDocBox.tsx | 198 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/client/views/SearchDocBox.tsx (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx new file mode 100644 index 000000000..596129c73 --- /dev/null +++ b/src/client/views/SearchDocBox.tsx @@ -0,0 +1,198 @@ +import { observer } from "mobx-react"; +import React = require("react"); +import { observable, action, computed, runInAction } from "mobx"; +import Measure from "react-measure"; +import "./RecommendationsBox.scss"; +import { Doc, DocListCast, WidthSym, HeightSym } from "../../new_fields/Doc"; +import { DocumentIcon } from "./nodes/DocumentIcon"; +import { StrCast, NumCast } from "../../new_fields/Types"; +import { returnFalse, emptyFunction, returnEmptyString, returnOne } from "../../Utils"; +import { Transform } from "../util/Transform"; +import { ObjectField } from "../../new_fields/ObjectField"; +import { DocumentView } from "./nodes/DocumentView"; +import { DocumentType } from '../documents/DocumentTypes'; +import { ClientRecommender } from "../ClientRecommender"; +import { DocServer } from "../DocServer"; +import { Id } from "../../new_fields/FieldSymbols"; +import { FieldView, FieldViewProps } from "./nodes/FieldView"; +import { DocumentManager } from "../util/DocumentManager"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { library } from "@fortawesome/fontawesome-svg-core"; +import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; +import { DocUtils } from "../documents/Documents"; + +export interface RecProps { + documents: { preview: Doc, similarity: number }[]; + node: Doc; +} + +library.add(faBullseye, faLink); + +@observer +export class SearchDocBox extends React.Component { + + public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(SearchDocBox, fieldKey); } + + // @observable private _display: boolean = false; + @observable private _pageX: number = 0; + @observable private _pageY: number = 0; + @observable private _width: number = 0; + @observable private _height: number = 0; + @observable.shallow private _docViews: JSX.Element[] = []; + // @observable private _documents: { preview: Doc, score: number }[] = []; + private previewDocs: Doc[] = []; + + constructor(props: FieldViewProps) { + super(props); + } + + @action + private DocumentIcon(doc: Doc) { + let layoutresult = StrCast(doc.type); + let renderDoc = doc; + //let box: number[] = []; + if (layoutresult.indexOf(DocumentType.COL) !== -1) { + renderDoc = Doc.MakeDelegate(renderDoc); + } + let returnXDimension = () => 150; + let returnYDimension = () => 150; + let scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension()); + //let scale = () => 1; + let newRenderDoc = Doc.MakeAlias(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt + newRenderDoc.height = NumCast(this.props.Document.documentIconHeight); + newRenderDoc.autoHeight = false; + const docview =
+ +
; + return docview; + + } + + // @action + // closeMenu = () => { + // this._display = false; + // this.previewDocs.forEach(doc => DocServer.DeleteDocument(doc[Id])); + // this.previewDocs = []; + // } + + // @action + // resetDocuments = () => { + // this._documents = []; + // } + + // @action + // displayRecommendations(x: number, y: number) { + // this._pageX = x; + // this._pageY = y; + // this._display = true; + // } + + static readonly buffer = 20; + + // get pageX() { + // const x = this._pageX; + // if (x < 0) { + // return 0; + // } + // const width = this._width; + // if (x + width > window.innerWidth - RecommendationsBox.buffer) { + // return window.innerWidth - RecommendationsBox.buffer - width; + // } + // return x; + // } + + // get pageY() { + // const y = this._pageY; + // if (y < 0) { + // return 0; + // } + // const height = this._height; + // if (y + height > window.innerHeight - RecommendationsBox.buffer) { + // return window.innerHeight - RecommendationsBox.buffer - height; + // } + // return y; + // } + + // get createDocViews() { + // return DocListCast(this.props.Document.data).map(doc => { + // return ( + //
+ // + // {this.DocumentIcon(doc)} + // + // {NumCast(doc.score).toFixed(4)} + //
DocumentManager.Instance.jumpToDocument(doc, false)}> + // + //
+ //
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> + // + //
+ //
+ // ); + // }); + // } + + componentDidMount() { //TODO: invoking a computedFn from outside an reactive context won't be memoized, unless keepAlive is set + runInAction(() => { + if (this._docViews.length === 0) { + this._docViews = DocListCast(this.props.Document.data).map(doc => { + return ( +
+ + {this.DocumentIcon(doc)} + + {NumCast(doc.score).toFixed(4)} +
DocumentManager.Instance.jumpToDocument(doc, false)}> + +
+
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> + +
+
+ ); + }); + } + }); + } + + render() { //TODO: Invariant violation: max depth exceeded error. Occurs when images are rendered. + // if (!this._display) { + // return null; + // } + // let style = { left: this.pageX, top: this.pageY }; + //const transform = "translate(" + (NumCast(this.props.node.x) + 350) + "px, " + NumCast(this.props.node.y) + "px" + // let title = StrCast((this.props.Document.sourceDoc as Doc).title); + // if (title.length > 15) { + // title = title.substring(0, 15) + "..."; + // } + return ( +
+ {this._docViews} +
+ ); + } + // + // +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From ad83dfcfaea5a6b525351b022158ebf5ff1f8c2f Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 22 Feb 2020 15:00:52 -0500 Subject: replacing search drag functionality --- solr-8.3.1/bin/solr-8983.pid | 2 +- src/client/documents/DocumentTypes.ts | 2 +- src/client/documents/Documents.ts | 7 +-- src/client/views/SearchDocBox.tsx | 54 +++++++++++++--------- src/client/views/search/SearchBox.scss | 2 +- src/client/views/search/SearchBox.tsx | 3 +- .../authentication/models/current_user_utils.ts | 2 +- 7 files changed, 42 insertions(+), 30 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/solr-8.3.1/bin/solr-8983.pid b/solr-8.3.1/bin/solr-8983.pid index d1b546ea3..2dfa22ed7 100644 --- a/solr-8.3.1/bin/solr-8983.pid +++ b/solr-8.3.1/bin/solr-8983.pid @@ -1 +1 @@ -7100 +13872 diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index e02382661..adc61aa80 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -28,5 +28,5 @@ export enum DocumentType { PDFANNO = "pdfanno", INK = "ink", DOCUMENT = "document", - SEARCH = "search", + SEARCHBOX = "searchbox", } \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 144554cbc..86e459561 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -46,6 +46,7 @@ import { DocumentType } from "./DocumentTypes"; import { RecommendationsBox } from "../views/RecommendationsBox"; import { SearchDocBox } from "../views/SearchDocBox"; + //import { PresBox } from "../views/nodes/PresBox"; //import { PresField } from "../../new_fields/PresField"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; @@ -258,7 +259,7 @@ export namespace Docs { layout: { view: InkingStroke, dataField: data }, options: { backgroundColor: "transparent" } }], - [DocumentType.SEARCH, { + [DocumentType.SEARCHBOX, { layout: { view: SearchDocBox }, options: { width: 200, height: 200 }, }] @@ -594,8 +595,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.RECOMMENDATION), new List(data), options); } - export function SearchDocument(options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.SEARCH), new List(), options); + export function SearchDocument(documents: Array, options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.SEARCHBOX), new List(documents), options); } export type DocConfig = { diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index 596129c73..c64b7285a 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -19,7 +19,8 @@ import { DocumentManager } from "../util/DocumentManager"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { library } from "@fortawesome/fontawesome-svg-core"; import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; -import { DocUtils } from "../documents/Documents"; +import { DocUtils, Docs } from "../documents/Documents"; +import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; export interface RecProps { documents: { preview: Doc, similarity: number }[]; @@ -156,27 +157,33 @@ export class SearchDocBox extends React.Component { componentDidMount() { //TODO: invoking a computedFn from outside an reactive context won't be memoized, unless keepAlive is set runInAction(() => { - if (this._docViews.length === 0) { - this._docViews = DocListCast(this.props.Document.data).map(doc => { - return ( -
- - {this.DocumentIcon(doc)} - - {NumCast(doc.score).toFixed(4)} -
DocumentManager.Instance.jumpToDocument(doc, false)}> - -
-
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> - -
-
- ); - }); - } + //if (this._docViews.length === 0) { + //this._docViews = + this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "Results"` })); + + // this._docViews = DocListCast(this.props.Document.data).map(doc => { + // return ( + //
+ // + // {this.DocumentIcon(doc)} + // + // {NumCast(doc.score).toFixed(4)} + //
DocumentManager.Instance.jumpToDocument(doc, false)}> + // + //
+ //
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> + // + //
+ //
+ // ); + // }); + //} }); } + @observable + private content: Doc | undefined; + render() { //TODO: Invariant violation: max depth exceeded error. Occurs when images are rendered. // if (!this._display) { // return null; @@ -188,9 +195,12 @@ export class SearchDocBox extends React.Component { // title = title.substring(0, 15) + "..."; // } return ( -
- {this._docViews} -
+ //
+ + + //
); } // diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index f492ea773..11714748a 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -19,7 +19,7 @@ padding-left: 2px; padding-right: 2px; - .searchBox-barChild { +.searchBox-barChild { &.searchBox-collection { flex: 0 1 auto; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index be13dae03..7628297c0 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -234,7 +234,8 @@ export class SearchBox extends React.Component { y += 300; } } - return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); } @action.bound diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index ec6fdc021..58958f1fc 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -64,7 +64,7 @@ export class CurrentUserUtils { { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "pink", activePen: doc }, { title: "use scrubber", icon: "eraser", click: 'activateScrubber(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "green", activePen: doc }, { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "white", activePen: doc }, - { title: "searc", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.SearchDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' }, + { title: "search", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.SearchDocument({ _width: 200, title: "an image of a cat" })' }, ]; -- cgit v1.2.3-70-g09d2 From ac59127b264386bdfbf6443822984d002afb7da9 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 23 Feb 2020 16:47:40 -0500 Subject: css menu --- src/client/documents/Documents.ts | 2 + src/client/views/SearchDocBox.tsx | 213 +++++++++++----------------------- src/client/views/search/SearchBox.tsx | 2 +- 3 files changed, 72 insertions(+), 145 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 86e459561..8ade14251 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -146,6 +146,8 @@ export interface DocumentOptions { flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; selectedIndex?: number; syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text + searchText?: string, //for searchbox + } class EmptyBox { diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index c64b7285a..da0872c43 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -2,10 +2,10 @@ import { observer } from "mobx-react"; import React = require("react"); import { observable, action, computed, runInAction } from "mobx"; import Measure from "react-measure"; -import "./RecommendationsBox.scss"; +import "./SearchBoxDoc.scss"; import { Doc, DocListCast, WidthSym, HeightSym } from "../../new_fields/Doc"; import { DocumentIcon } from "./nodes/DocumentIcon"; -import { StrCast, NumCast } from "../../new_fields/Types"; +import { StrCast, NumCast, BoolCast } from "../../new_fields/Types"; import { returnFalse, emptyFunction, returnEmptyString, returnOne } from "../../Utils"; import { Transform } from "../util/Transform"; import { ObjectField } from "../../new_fields/ObjectField"; @@ -21,13 +21,16 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; import { DocUtils, Docs } from "../documents/Documents"; import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; +import { EditableView } from "./EditableView"; export interface RecProps { documents: { preview: Doc, similarity: number }[]; node: Doc; + } library.add(faBullseye, faLink); +export const keyPlaceholder = "Query"; @observer export class SearchDocBox extends React.Component { @@ -45,164 +48,86 @@ export class SearchDocBox extends React.Component { constructor(props: FieldViewProps) { super(props); + this.editingMetadata = this.editingMetadata || false; } - @action - private DocumentIcon(doc: Doc) { - let layoutresult = StrCast(doc.type); - let renderDoc = doc; - //let box: number[] = []; - if (layoutresult.indexOf(DocumentType.COL) !== -1) { - renderDoc = Doc.MakeDelegate(renderDoc); - } - let returnXDimension = () => 150; - let returnYDimension = () => 150; - let scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension()); - //let scale = () => 1; - let newRenderDoc = Doc.MakeAlias(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt - newRenderDoc.height = NumCast(this.props.Document.documentIconHeight); - newRenderDoc.autoHeight = false; - const docview =
- -
; - return docview; + @computed + private get editingMetadata() { + return BoolCast(this.props.Document.editingMetadata); } - // @action - // closeMenu = () => { - // this._display = false; - // this.previewDocs.forEach(doc => DocServer.DeleteDocument(doc[Id])); - // this.previewDocs = []; - // } - - // @action - // resetDocuments = () => { - // this._documents = []; - // } - - // @action - // displayRecommendations(x: number, y: number) { - // this._pageX = x; - // this._pageY = y; - // this._display = true; - // } + @computed + private set editingMetadata(value: boolean) { + this.props.Document.editingMetadata = value; + } static readonly buffer = 20; - // get pageX() { - // const x = this._pageX; - // if (x < 0) { - // return 0; - // } - // const width = this._width; - // if (x + width > window.innerWidth - RecommendationsBox.buffer) { - // return window.innerWidth - RecommendationsBox.buffer - width; - // } - // return x; - // } - - // get pageY() { - // const y = this._pageY; - // if (y < 0) { - // return 0; - // } - // const height = this._height; - // if (y + height > window.innerHeight - RecommendationsBox.buffer) { - // return window.innerHeight - RecommendationsBox.buffer - height; - // } - // return y; - // } - - // get createDocViews() { - // return DocListCast(this.props.Document.data).map(doc => { - // return ( - //
- // - // {this.DocumentIcon(doc)} - // - // {NumCast(doc.score).toFixed(4)} - //
DocumentManager.Instance.jumpToDocument(doc, false)}> - // - //
- //
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> - // - //
- //
- // ); - // }); - // } - - componentDidMount() { //TODO: invoking a computedFn from outside an reactive context won't be memoized, unless keepAlive is set + componentDidMount() { runInAction(() => { - //if (this._docViews.length === 0) { - //this._docViews = - this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "Results"` })); - - // this._docViews = DocListCast(this.props.Document.data).map(doc => { - // return ( - //
- // - // {this.DocumentIcon(doc)} - // - // {NumCast(doc.score).toFixed(4)} - //
DocumentManager.Instance.jumpToDocument(doc, false)}> - // - //
- //
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}> - // - //
- //
- // ); - // }); - //} + this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` })); + this.query = StrCast(this.props.Document.searchText); }); } @observable private content: Doc | undefined; - render() { //TODO: Invariant violation: max depth exceeded error. Occurs when images are rendered. - // if (!this._display) { - // return null; - // } - // let style = { left: this.pageX, top: this.pageY }; - //const transform = "translate(" + (NumCast(this.props.node.x) + 350) + "px, " + NumCast(this.props.node.y) + "px" - // let title = StrCast((this.props.Document.sourceDoc as Doc).title); - // if (title.length > 15) { - // title = title.substring(0, 15) + "..."; - // } + @action + updateKey = (newKey: string) => { + this.query = newKey; + //this.keyRef.current && this.keyRef.current.setIsFocused(false); + //this.query.length === 0 && (this.query = keyPlaceholder); + return true; + } + + @computed + public get query() { + return StrCast(this.props.Document.query); + } + + public set query(value: string) { + this.props.Document.query = value; + } + + render() { + const isEditing = this.editingMetadata; + console.log(isEditing); return ( - //
- - - //
+
+
this.editingMetadata = !this.editingMetadata)} + /> +
+ ""} + /> +
+
+ + +
+
); } - // - // + } \ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 7628297c0..9af8829fa 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -235,7 +235,7 @@ export class SearchBox extends React.Component { } } //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); } @action.bound -- cgit v1.2.3-70-g09d2 From 6c389c764c39c9b446996cc1a4aa777a9302f677 Mon Sep 17 00:00:00 2001 From: Andy Rickert Date: Mon, 24 Feb 2020 21:58:12 -0500 Subject: researching tentatively works --- package-lock.json | 92 ----------- package.json | 1 - src/client/views/SearchDocBox.tsx | 324 ++++++++++++++++++++++++++++++++++++-- src/server/Recommender.ts | 2 +- 4 files changed, 316 insertions(+), 103 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/package-lock.json b/package-lock.json index 833710fe7..f6b1e80da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -287,17 +287,6 @@ "resolved": "https://registry.npmjs.org/@tensorflow-models/universal-sentence-encoder/-/universal-sentence-encoder-1.2.2.tgz", "integrity": "sha512-fGCl/gwB7jmKCRI2FhgIBeIa/LCSUcjlEcckH2Bc2dIjhJ+2nspp+22lubxcseN6jjrmP42kkXt/reAPe+KJkQ==" }, - "@tensorflow/tfjs": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-1.5.2.tgz", - "integrity": "sha512-BCvcbnkE/zMdORIGE7TFAiJU3zLLVUaRv/HyWucVVyHU40oU4L5mGyRXK6RwqU38KmeK3HSI5rUHop4cLNUaRQ==", - "requires": { - "@tensorflow/tfjs-converter": "1.5.2", - "@tensorflow/tfjs-core": "1.5.2", - "@tensorflow/tfjs-data": "1.5.2", - "@tensorflow/tfjs-layers": "1.5.2" - } - }, "@tensorflow/tfjs-converter": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-1.5.2.tgz", @@ -323,69 +312,6 @@ } } }, - "@tensorflow/tfjs-data": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-1.5.2.tgz", - "integrity": "sha512-ruCsTSyH67CADWthgLQlWKh8u8YGEXD+4vsW8uOGdFNcDFLcL0ffy4jsSzIV/X6NdPIWYsvSHmiz57LtgfCFew==", - "requires": { - "@types/node-fetch": "^2.1.2", - "node-fetch": "~2.1.2" - }, - "dependencies": { - "node-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" - } - } - }, - "@tensorflow/tfjs-layers": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-1.5.2.tgz", - "integrity": "sha512-fn2hi5D1sOKGEgiBCuoU/hTHO87znODweGivIn6x2HMtF1EC39QWroYQBWzJyrWWMOUZZ4nOFR6coA0Fkhc+nA==" - }, - "@tensorflow/tfjs-node": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-1.5.2.tgz", - "integrity": "sha512-qihOkKbCLTDcqe3TTDbA9v00PacMzPwhspV8MEHWpohVb7itqQ8cMSE8w38b2oA+FE38c1RI7KOd2qAl5bCNHA==", - "requires": { - "@tensorflow/tfjs": "1.5.2", - "adm-zip": "^0.4.11", - "google-protobuf": "^3.9.2", - "https-proxy-agent": "^2.2.1", - "node-pre-gyp": "0.14.0", - "progress": "^2.0.0", - "rimraf": "^2.6.2", - "tar": "^4.4.6" - }, - "dependencies": { - "node-pre-gyp": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, "@trendmicro/react-buttons": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@trendmicro/react-buttons/-/react-buttons-1.3.1.tgz", @@ -781,14 +707,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==" }, - "@types/node-fetch": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.4.tgz", - "integrity": "sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==", - "requires": { - "@types/node": "*" - } - }, "@types/nodemailer": { "version": "4.6.8", "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.8.tgz", @@ -6445,11 +6363,6 @@ } } }, - "google-protobuf": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.11.3.tgz", - "integrity": "sha512-Sp8E+0AJLxmiPwAk9VH3MkYAmYYheNUhywIyXOS7wvRkqbIYcHtGzJzIYicNqYsqgKmY35F9hxRkI+ZTqTB4Tg==" - }, "googleapis": { "version": "40.0.1", "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-40.0.1.tgz", @@ -13423,11 +13336,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", diff --git a/package.json b/package.json index 7e0adfba6..cd97e590c 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "@tensorflow-models/universal-sentence-encoder": "^1.2.2", "@tensorflow/tfjs-converter": "^1.3.2", "@tensorflow/tfjs-core": "^1.5.2", - "@tensorflow/tfjs-node": "^1.5.2", "@trendmicro/react-dropdown": "^1.3.0", "@types/adm-zip": "^0.4.32", "@types/animejs": "^2.0.2", diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index da0872c43..06d434789 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -2,10 +2,10 @@ import { observer } from "mobx-react"; import React = require("react"); import { observable, action, computed, runInAction } from "mobx"; import Measure from "react-measure"; -import "./SearchBoxDoc.scss"; +//import "./SearchBoxDoc.scss"; import { Doc, DocListCast, WidthSym, HeightSym } from "../../new_fields/Doc"; import { DocumentIcon } from "./nodes/DocumentIcon"; -import { StrCast, NumCast, BoolCast } from "../../new_fields/Types"; +import { StrCast, NumCast, BoolCast, Cast } from "../../new_fields/Types"; import { returnFalse, emptyFunction, returnEmptyString, returnOne } from "../../Utils"; import { Transform } from "../util/Transform"; import { ObjectField } from "../../new_fields/ObjectField"; @@ -22,6 +22,10 @@ import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; import { DocUtils, Docs } from "../documents/Documents"; import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; import { EditableView } from "./EditableView"; +import { SearchUtil } from "../util/SearchUtil"; +import { SearchItem } from "./search/SearchItem"; +import { FilterBox } from "./search/FilterBox"; +import { SearchBox } from "./search/SearchBox"; export interface RecProps { documents: { preview: Doc, similarity: number }[]; @@ -35,8 +39,6 @@ export const keyPlaceholder = "Query"; @observer export class SearchDocBox extends React.Component { - public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(SearchDocBox, fieldKey); } - // @observable private _display: boolean = false; @observable private _pageX: number = 0; @observable private _pageY: number = 0; @@ -49,6 +51,8 @@ export class SearchDocBox extends React.Component { constructor(props: FieldViewProps) { super(props); this.editingMetadata = this.editingMetadata || false; + //SearchBox.Instance = this; + this.resultsScrolled = this.resultsScrolled.bind(this); } @@ -57,7 +61,6 @@ export class SearchDocBox extends React.Component { return BoolCast(this.props.Document.editingMetadata); } - @computed private set editingMetadata(value: boolean) { this.props.Document.editingMetadata = value; } @@ -66,16 +69,32 @@ export class SearchDocBox extends React.Component { componentDidMount() { runInAction(() => { - this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` })); this.query = StrCast(this.props.Document.searchText); + this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query})); + }); + if (this.inputRef.current) { + this.inputRef.current.focus(); + runInAction(() => { + this._searchbarOpen = true; + }); + } } @observable private content: Doc | undefined; @action - updateKey = (newKey: string) => { + updateKey = async (newKey: string) => { + if (newKey.length >1){ + let newdocs= await this.getAllResults(this.query) + let things = newdocs.docs + console.log(things); + await runInAction(() => { + this.content=Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); + }); + } + this.query = newKey; //this.keyRef.current && this.keyRef.current.setIsFocused(false); //this.query.length === 0 && (this.query = keyPlaceholder); @@ -91,6 +110,293 @@ export class SearchDocBox extends React.Component { this.props.Document.query = value; } + @observable private _searchString: string = ""; + @observable private _resultsOpen: boolean = false; + @observable private _searchbarOpen: boolean = false; + @observable private _results: [Doc, string[], string[]][] = []; + private _resultsSet = new Map(); + @observable private _openNoResults: boolean = false; + @observable private _visibleElements: JSX.Element[] = []; + + private resultsRef = React.createRef(); + public inputRef = React.createRef(); + + private _isSearch: ("search" | "placeholder" | undefined)[] = []; + private _numTotalResults = -1; + private _endIndex = -1; + + + private _maxSearchIndex: number = 0; + private _curRequest?: Promise = undefined; + + @action + getViews = async (doc: Doc) => { + const results = await SearchUtil.GetViewsOfDocument(doc); + let toReturn: Doc[] = []; + await runInAction(() => { + toReturn = results; + }); + return toReturn; + } + + @action.bound + onChange(e: React.ChangeEvent) { + this._searchString = e.target.value; + + this._openNoResults = false; + this._results = []; + this._resultsSet.clear(); + this._visibleElements = []; + this._numTotalResults = -1; + this._endIndex = -1; + this._curRequest = undefined; + this._maxSearchIndex = 0; + } + + enter = async (e: React.KeyboardEvent) => { + console.log(e.key); + if (e.key === "Enter") { + let newdocs= await this.getAllResults(this.query) + let things = newdocs.docs + console.log(things); + this.content=Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); + + } + } + + + @action + submitSearch = async () => { + let query = this._searchString; + query = FilterBox.Instance.getFinalQuery(query); + this._results = []; + this._resultsSet.clear(); + this._isSearch = []; + this._visibleElements = []; + FilterBox.Instance.closeFilter(); + + //if there is no query there should be no result + if (query === "") { + return; + } + else { + this._endIndex = 12; + this._maxSearchIndex = 0; + this._numTotalResults = -1; + await this.getResults(query); + } + + runInAction(() => { + this._resultsOpen = true; + this._searchbarOpen = true; + this._openNoResults = true; + this.resultsScrolled(); + }); + } + + getAllResults = async (query: string) => { + return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 }); + } + + private get filterQuery() { + const types = FilterBox.Instance.filterTypes; + const includeDeleted = FilterBox.Instance.getDataStatus(); + return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted_b:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}" OR type_t:"extension"`).join(" ")})` : ""); + } + + + private NumResults = 25; + private lockPromise?: Promise; + getResults = async (query: string) => { + if (this.lockPromise) { + await this.lockPromise; + } + this.lockPromise = new Promise(async res => { + while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { + this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { + + // happens at the beginning + if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { + this._numTotalResults = res.numFound; + } + + const highlighting = res.highlighting || {}; + const highlightList = res.docs.map(doc => highlighting[doc[Id]]); + const lines = new Map(); + res.docs.map((doc, i) => lines.set(doc[Id], res.lines[i])); + const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); + const highlights: typeof res.highlighting = {}; + docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); + const filteredDocs = FilterBox.Instance.filterDocsByType(docs); + runInAction(() => { + // this._results.push(...filteredDocs); + filteredDocs.forEach(doc => { + const index = this._resultsSet.get(doc); + const highlight = highlights[doc[Id]]; + const line = lines.get(doc[Id]) || []; + const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []; + if (index === undefined) { + this._resultsSet.set(doc, this._results.length); + this._results.push([doc, hlights, line]); + } else { + this._results[index][1].push(...hlights); + this._results[index][2].push(...line); + } + }); + }); + + this._curRequest = undefined; + })); + this._maxSearchIndex += this.NumResults; + + await this._curRequest; + } + this.resultsScrolled(); + res(); + }); + return this.lockPromise; + } + + collectionRef = React.createRef(); + startDragCollection = async () => { + const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); + const filtered = FilterBox.Instance.filterDocsByType(res.docs); + // console.log(this._results) + const docs = filtered.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.map(d => Doc.Layout(d))) { + 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; + } + x += 250; + if (x > 1000) { + x = 0; + y += 300; + } + } + //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); + } + + @action.bound + openSearch(e: React.SyntheticEvent) { + e.stopPropagation(); + this._openNoResults = false; + FilterBox.Instance.closeFilter(); + this._resultsOpen = true; + this._searchbarOpen = true; + FilterBox.Instance._pointerTime = e.timeStamp; + } + + @action.bound + closeSearch = () => { + FilterBox.Instance.closeFilter(); + this.closeResults(); + this._searchbarOpen = false; + } + + @action.bound + closeResults() { + this._resultsOpen = false; + this._results = []; + this._resultsSet.clear(); + this._visibleElements = []; + this._numTotalResults = -1; + this._endIndex = -1; + this._curRequest = undefined; + } + + @action + resultsScrolled = (e?: React.UIEvent) => { + if (!this.resultsRef.current) return; + const scrollY = e ? e.currentTarget.scrollTop : this.resultsRef.current ? this.resultsRef.current.scrollTop : 0; + const itemHght = 53; + const startIndex = Math.floor(Math.max(0, scrollY / itemHght)); + const endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this.resultsRef.current.getBoundingClientRect().height / itemHght))); + + this._endIndex = endIndex === -1 ? 12 : endIndex; + + if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) { + this._visibleElements = [
No Search Results
]; + return; + } + + if (this._numTotalResults <= this._maxSearchIndex) { + this._numTotalResults = this._results.length; + } + + // only hit right at the beginning + // visibleElements is all of the elements (even the ones you can't see) + else if (this._visibleElements.length !== this._numTotalResults) { + // undefined until a searchitem is put in there + this._visibleElements = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); + // indicates if things are placeholders + this._isSearch = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); + } + + for (let i = 0; i < this._numTotalResults; i++) { + //if the index is out of the window then put a placeholder in + //should ones that have already been found get set to placeholders? + if (i < startIndex || i > endIndex) { + if (this._isSearch[i] !== "placeholder") { + this._isSearch[i] = "placeholder"; + this._visibleElements[i] =
Loading...
; + } + } + else { + if (this._isSearch[i] !== "search") { + let result: [Doc, string[], string[]] | undefined = undefined; + if (i >= this._results.length) { + this.getResults(this._searchString); + if (i < this._results.length) result = this._results[i]; + if (result) { + const highlights = Array.from([...Array.from(new Set(result[1]).values())]); + this._visibleElements[i] = ; + this._isSearch[i] = "search"; + } + } + else { + result = this._results[i]; + if (result) { + const highlights = Array.from([...Array.from(new Set(result[1]).values())]); + this._visibleElements[i] = ; + this._isSearch[i] = "search"; + } + } + } + } + } + if (this._maxSearchIndex >= this._numTotalResults) { + this._visibleElements.length = this._results.length; + this._isSearch.length = this._results.length; + } + } + + @computed + get resFull() { return this._numTotalResults <= 8; } + + @computed + get resultHeight() { return this._numTotalResults * 70; } + render() { const isEditing = this.editingMetadata; console.log(isEditing); @@ -109,9 +415,9 @@ export class SearchDocBox extends React.Component { zIndex: 99, }} title={"Add Metadata"} - onClick={action(() => this.editingMetadata = !this.editingMetadata)} + onDoubleClick={action(() => {this.editingMetadata = !this.editingMetadata })} /> -
+
Date: Wed, 26 Feb 2020 17:52:51 -0500 Subject: fixing css and ui --- src/client/views/SearchDocBox.tsx | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index 06d434789..5f308ff71 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -69,6 +69,8 @@ export class SearchDocBox extends React.Component { componentDidMount() { runInAction(() => { + console.log("didit" + ); this.query = StrCast(this.props.Document.searchText); this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query})); @@ -86,16 +88,19 @@ export class SearchDocBox extends React.Component { @action updateKey = async (newKey: string) => { + this.query = newKey; if (newKey.length >1){ let newdocs= await this.getAllResults(this.query) let things = newdocs.docs console.log(things); - await runInAction(() => { - this.content=Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); - }); + console.log(this.content); + runInAction(() => { + this.content= Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); + }); + console.log(this.content); } - this.query = newKey; + //this.keyRef.current && this.keyRef.current.setIsFocused(false); //this.query.length === 0 && (this.query = keyPlaceholder); return true; @@ -399,9 +404,12 @@ export class SearchDocBox extends React.Component { render() { const isEditing = this.editingMetadata; - console.log(isEditing); return (
+ + s
{ opacity: 1, transition: "0.4s opacity ease", zIndex: 99, + top:0, }} title={"Add Metadata"} - onDoubleClick={action(() => {this.editingMetadata = !this.editingMetadata })} + onClick={action(() => {this.editingMetadata = !this.editingMetadata })} /> -
+
""} />
-
- - -
); } -- cgit v1.2.3-70-g09d2 From 14a2f361c73e468547d48792478e5e7e7e78f4d6 Mon Sep 17 00:00:00 2001 From: vellichora Date: Sat, 29 Feb 2020 13:52:53 -0500 Subject: filter UI --- package-lock.json | 41 +-- src/client/views/SearchDocBox.tsx | 34 +-- src/client/views/search/CheckBox.tsx | 146 +++++----- src/client/views/search/SearchBox.tsx | 47 +++ src/server/ApiManagers/SessionManager.ts | 20 +- src/server/DashSession/DashSessionAgent.ts | 446 ++++++++++++++--------------- src/server/index.ts | 4 +- 7 files changed, 384 insertions(+), 354 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/package-lock.json b/package-lock.json index f6b1e80da..e60950308 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5600,8 +5600,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -5619,13 +5618,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5638,18 +5635,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -5752,8 +5746,7 @@ }, "inherits": { "version": "2.0.4", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -5763,7 +5756,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5776,20 +5768,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.9.0", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5806,7 +5795,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5887,8 +5875,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -5898,7 +5885,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5974,8 +5960,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -6005,7 +5990,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6023,7 +6007,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6062,13 +6045,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.1.1", - "bundled": true, - "optional": true + "bundled": true } } }, diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index 5f308ff71..5a76a882f 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -39,6 +39,8 @@ export const keyPlaceholder = "Query"; @observer export class SearchDocBox extends React.Component { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchDocBox, fieldKey); } + // @observable private _display: boolean = false; @observable private _pageX: number = 0; @observable private _pageY: number = 0; @@ -72,7 +74,7 @@ export class SearchDocBox extends React.Component { console.log("didit" ); this.query = StrCast(this.props.Document.searchText); - this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query})); + this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query })); }); if (this.inputRef.current) { @@ -89,16 +91,16 @@ export class SearchDocBox extends React.Component { @action updateKey = async (newKey: string) => { this.query = newKey; - if (newKey.length >1){ - let newdocs= await this.getAllResults(this.query) + if (newKey.length > 1) { + let newdocs = await this.getAllResults(this.query); let things = newdocs.docs console.log(things); console.log(this.content); runInAction(() => { - this.content= Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); - }); - console.log(this.content); - } + this.content = Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); + }); + console.log(this.content); + } //this.keyRef.current && this.keyRef.current.setIsFocused(false); @@ -161,11 +163,11 @@ export class SearchDocBox extends React.Component { enter = async (e: React.KeyboardEvent) => { console.log(e.key); if (e.key === "Enter") { - let newdocs= await this.getAllResults(this.query) + let newdocs = await this.getAllResults(this.query) let things = newdocs.docs console.log(things); - this.content=Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); - + this.content = Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); + } } @@ -407,9 +409,9 @@ export class SearchDocBox extends React.Component { return (
- s + Document={this.content} + getTransform={this.props.ScreenToLocalTransform}> + s
{ opacity: 1, transition: "0.4s opacity ease", zIndex: 99, - top:0, + top: 0, }} title={"Add Metadata"} - onClick={action(() => {this.editingMetadata = !this.editingMetadata })} + onClick={action(() => { this.editingMetadata = !this.editingMetadata })} /> -
+
{ // true = checked, false = unchecked @observable private _status: boolean; - @observable private uncheckTimeline: anime.AnimeTimelineInstance; - @observable private checkTimeline: anime.AnimeTimelineInstance; + // @observable private uncheckTimeline: anime.AnimeTimelineInstance; + // @observable private checkTimeline: anime.AnimeTimelineInstance; @observable private checkRef: any; @observable private _resetReaction?: IReactionDisposer; @@ -28,87 +28,87 @@ export class CheckBox extends React.Component{ this._status = this.props.originalStatus; this.checkRef = React.createRef(); - this.checkTimeline = anime.timeline({ - loop: false, - autoplay: false, - direction: "normal", - }); this.uncheckTimeline = anime.timeline({ - loop: false, - autoplay: false, - direction: "normal", - }); + // this.checkTimeline = anime.timeline({ + // loop: false, + // autoplay: false, + // direction: "normal", + // }); this.uncheckTimeline = anime.timeline({ + // loop: false, + // autoplay: false, + // direction: "normal", + // }); } - componentDidMount = () => { - this.uncheckTimeline.add({ - targets: this.checkRef.current, - easing: "easeInOutQuad", - duration: 500, - opacity: 0, - }); - this.checkTimeline.add({ - targets: this.checkRef.current, - easing: "easeInOutQuad", - duration: 500, - strokeDashoffset: [anime.setDashoffset, 0], - opacity: 1 - }); + // componentDidMount = () => { + // this.uncheckTimeline.add({ + // targets: this.checkRef.current, + // easing: "easeInOutQuad", + // duration: 500, + // opacity: 0, + // }); + // this.checkTimeline.add({ + // targets: this.checkRef.current, + // easing: "easeInOutQuad", + // duration: 500, + // strokeDashoffset: [anime.setDashoffset, 0], + // opacity: 1 + // }); - if (this.props.originalStatus) { - this.checkTimeline.play(); - this.checkTimeline.restart(); - } + // if (this.props.originalStatus) { + // this.checkTimeline.play(); + // this.checkTimeline.restart(); + // } - this._resetReaction = reaction( - () => this.props.parent._resetBoolean, - () => { - if (this.props.parent._resetBoolean) { - runInAction(() => { - this.reset(); - this.props.parent._resetCounter++; - if (this.props.parent._resetCounter === this.props.numCount) { - this.props.parent._resetCounter = 0; - this.props.parent._resetBoolean = false; - } - }); - } - }, - ); - } + // this._resetReaction = reaction( + // () => this.props.parent._resetBoolean, + // () => { + // if (this.props.parent._resetBoolean) { + // runInAction(() => { + // this.reset(); + // this.props.parent._resetCounter++; + // if (this.props.parent._resetCounter === this.props.numCount) { + // this.props.parent._resetCounter = 0; + // this.props.parent._resetBoolean = false; + // } + // }); + // } + // }, + // ); + // } - @action.bound - reset() { - if (this.props.default) { - if (!this._status) { - this._status = true; - this.checkTimeline.play(); - this.checkTimeline.restart(); - } - } - else { - if (this._status) { - this._status = false; - this.uncheckTimeline.play(); - this.uncheckTimeline.restart(); - } - } + // @action.bound + // reset() { + // if (this.props.default) { + // if (!this._status) { + // this._status = true; + // this.checkTimeline.play(); + // this.checkTimeline.restart(); + // } + // } + // else { + // if (this._status) { + // this._status = false; + // this.uncheckTimeline.play(); + // this.uncheckTimeline.restart(); + // } + // } - this.props.updateStatus(this.props.default); - } + // this.props.updateStatus(this.props.default); + // } @action.bound onClick = () => { - if (this._status) { - this.uncheckTimeline.play(); - this.uncheckTimeline.restart(); - } - else { - this.checkTimeline.play(); - this.checkTimeline.restart(); + // if (this._status) { + // this.uncheckTimeline.play(); + // this.uncheckTimeline.restart(); + // } + // else { + // this.checkTimeline.play(); + // this.checkTimeline.restart(); - } - this._status = !this._status; - this.props.updateStatus(this._status); + // } + // this._status = !this._status; + // this.props.updateStatus(this._status); } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 9af8829fa..02b41bc70 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -17,6 +17,7 @@ import "./FilterBox.scss"; import "./SearchBox.scss"; import { SearchItem } from './SearchItem'; import { IconBar } from './IconBar'; +import { FieldFilters } from './FieldFilters'; library.add(faTimes); @@ -338,6 +339,9 @@ export class SearchBox extends React.Component { @computed get resultHeight() { return this._numTotalResults * 70; } + @observable private _filterOpen: boolean = false; + + render() { return (
{ e.stopPropagation(); e.preventDefault(); }}> @@ -353,6 +357,49 @@ export class SearchBox extends React.Component {
+
+
+ + {/* {this.getActiveFilters()} */} +
+
+
+ +
+
+ +
+
+
+
+
+
Required words
+
+
+ +
+
+
+
+
Filter by type of node
+
+
+
+
+
+
Filter by Basic Keys
+
+
+
+
+
+ + +
+
+
{ - const to = params.to || DashSessionAgent.notificationRecipient; - const { error } = await sessionAgent.serverWorker.emit("debug", { to }); - res.send(error ? error.message : `Your request was successful: the server captured and compressed (but did not save) a new back up. It was sent to ${to}.`); - }) - }); + // register({ + // method: Method.GET, + // subscription: this.secureSubscriber("debug", "to?"), + // secureHandler: this.authorizedAction(async ({ req: { params }, res }) => { + // const to = params.to || DashSessionAgent.notificationRecipient; + // const { error } = await sessionAgent.serverWorker.emit("debug", { to }); + // res.send(error ? error.message : `Your request was successful: the server captured and compressed (but did not save) a new back up. It was sent to ${to}.`); + // }) + // }); register({ method: Method.GET, diff --git a/src/server/DashSession/DashSessionAgent.ts b/src/server/DashSession/DashSessionAgent.ts index c55e01243..f22d1cbbc 100644 --- a/src/server/DashSession/DashSessionAgent.ts +++ b/src/server/DashSession/DashSessionAgent.ts @@ -1,223 +1,223 @@ -import { Email, pathFromRoot } from "../ActionUtilities"; -import { red, yellow, green, cyan } from "colors"; -import { get } from "request-promise"; -import { Utils } from "../../Utils"; -import { WebSocket } from "../Websocket/Websocket"; -import { MessageStore } from "../Message"; -import { launchServer, onWindows } from ".."; -import { readdirSync, statSync, createWriteStream, readFileSync, unlinkSync } from "fs"; -import * as Archiver from "archiver"; -import { resolve } from "path"; -import { AppliedSessionAgent, MessageHandler, ExitHandler, Monitor, ServerWorker } from "resilient-server-session"; -import rimraf = require("rimraf"); - -/** - * If we're the monitor (master) thread, we should launch the monitor logic for the session. - * Otherwise, we must be on a worker thread that was spawned *by* the monitor (master) thread, and thus - * our job should be to run the server. - */ -export class DashSessionAgent extends AppliedSessionAgent { - - private readonly signature = "-Dash Server Session Manager"; - private readonly releaseDesktop = pathFromRoot("../../Desktop"); - - /** - * The core method invoked when the single master thread is initialized. - * Installs event hooks, repl commands and additional IPC listeners. - */ - protected async initializeMonitor(monitor: Monitor, sessionKey: string): Promise { - await this.dispatchSessionPassword(sessionKey); - monitor.addReplCommand("pull", [], () => monitor.exec("git pull")); - monitor.addReplCommand("solr", [/start|stop|index/], this.executeSolrCommand); - monitor.addReplCommand("backup", [], this.backup); - monitor.addReplCommand("debug", [/\S+\@\S+/], async ([to]) => this.dispatchZippedDebugBackup(to)); - monitor.on("backup", this.backup); - monitor.on("debug", async ({ to }) => this.dispatchZippedDebugBackup(to)); - monitor.coreHooks.onCrashDetected(this.dispatchCrashReport); - } - - /** - * The core method invoked when a server worker thread is initialized. - * Installs logic to be executed when the server worker dies. - */ - protected async initializeServerWorker(): Promise { - const worker = ServerWorker.Create(launchServer); // server initialization delegated to worker - worker.addExitHandler(this.notifyClient); - return worker; - } - - /** - * Prepares the body of the email with instructions on restoring the transmitted remote database backup locally. - */ - private _remoteDebugInstructions: string | undefined; - private generateDebugInstructions = (zipName: string, target: string): string => { - if (!this._remoteDebugInstructions) { - this._remoteDebugInstructions = readFileSync(resolve(__dirname, "./templates/remote_debug_instructions.txt"), { encoding: "utf8" }); - } - return this._remoteDebugInstructions - .replace(/__zipname__/, zipName) - .replace(/__target__/, target) - .replace(/__signature__/, this.signature); - } - - /** - * Prepares the body of the email with information regarding a crash event. - */ - private _crashInstructions: string | undefined; - private generateCrashInstructions({ name, message, stack }: Error): string { - if (!this._crashInstructions) { - this._crashInstructions = readFileSync(resolve(__dirname, "./templates/crash_instructions.txt"), { encoding: "utf8" }); - } - return this._crashInstructions - .replace(/__name__/, name || "[no error name found]") - .replace(/__message__/, message || "[no error message found]") - .replace(/__stack__/, stack || "[no error stack found]") - .replace(/__signature__/, this.signature); - } - - /** - * This sends a pseudorandomly generated guid to the configuration's recipients, allowing them alone - * to kill the server via the /kill/:key route. - */ - private dispatchSessionPassword = async (sessionKey: string): Promise => { - const { mainLog } = this.sessionMonitor; - const { notificationRecipient } = DashSessionAgent; - mainLog(green("dispatching session key...")); - const error = await Email.dispatch({ - to: notificationRecipient, - subject: "Dash Release Session Admin Authentication Key", - content: [ - `Here's the key for this session (started @ ${new Date().toUTCString()}):`, - sessionKey, - this.signature - ].join("\n\n") - }); - if (error) { - this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} (${yellow(error.message)})`)); - mainLog(red("distribution of session key experienced errors")); - } else { - mainLog(green("successfully distributed session key to recipients")); - } - } - - /** - * This sends an email with the generated crash report. - */ - private dispatchCrashReport: MessageHandler<{ error: Error }> = async ({ error: crashCause }) => { - const { mainLog } = this.sessionMonitor; - const { notificationRecipient } = DashSessionAgent; - const error = await Email.dispatch({ - to: notificationRecipient, - subject: "Dash Web Server Crash", - content: this.generateCrashInstructions(crashCause) - }); - if (error) { - this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} ${yellow(`(${error.message})`)}`)); - mainLog(red("distribution of crash notification experienced errors")); - } else { - mainLog(green("successfully distributed crash notification to recipients")); - } - } - - /** - * Logic for interfacing with Solr. Either starts it, - * stops it, or rebuilds its indicies. - */ - private executeSolrCommand = async (args: string[]): Promise => { - const { exec, mainLog } = this.sessionMonitor; - const action = args[0]; - if (action === "index") { - exec("npx ts-node ./updateSearch.ts", { cwd: pathFromRoot("./src/server") }); - } else { - const command = `${onWindows ? "solr.cmd" : "solr"} ${args[0] === "start" ? "start" : "stop -p 8983"}`; - await exec(command, { cwd: "./solr-8.3.1/bin" }); - try { - await get("http://localhost:8983"); - mainLog(green("successfully connected to 8983 after running solr initialization")); - } catch { - mainLog(red("unable to connect at 8983 after running solr initialization")); - } - } - } - - /** - * Broadcast to all clients that their connection - * is no longer valid, and explain why / what to expect. - */ - private notifyClient: ExitHandler = reason => { - const { _socket } = WebSocket; - if (_socket) { - const message = typeof reason === "boolean" ? (reason ? "exit" : "temporary") : "crash"; - Utils.Emit(_socket, MessageStore.ConnectionTerminated, message); - } - } - - /** - * Performs a backup of the database, saved to the desktop subdirectory. - * This should work as is only on our specific release server. - */ - private backup = async (): Promise => this.sessionMonitor.exec("backup.bat", { cwd: this.releaseDesktop }); - - /** - * Compress either a brand new backup or the most recent backup and send it - * as an attachment to an email, dispatched to the requested recipient. - * @param mode specifies whether or not to make a new backup before exporting - * @param to the recipient of the email - */ - private async dispatchZippedDebugBackup(to: string): Promise { - const { mainLog } = this.sessionMonitor; - try { - // if desired, complete an immediate backup to send - await this.backup(); - mainLog("backup complete"); - - const backupsDirectory = `${this.releaseDesktop}/backups`; - - // sort all backups by their modified time, and choose the most recent one - const target = readdirSync(backupsDirectory).map(filename => ({ - modifiedTime: statSync(`${backupsDirectory}/${filename}`).mtimeMs, - filename - })).sort((a, b) => b.modifiedTime - a.modifiedTime)[0].filename; - mainLog(`targeting ${target}...`); - - // create a zip file and to it, write the contents of the backup directory - const zipName = `${target}.zip`; - const zipPath = `${this.releaseDesktop}/${zipName}`; - const targetPath = `${backupsDirectory}/${target}`; - const output = createWriteStream(zipPath); - const zip = Archiver('zip'); - zip.pipe(output); - zip.directory(`${targetPath}/Dash`, false); - await zip.finalize(); - mainLog(`zip finalized with size ${statSync(zipPath).size} bytes, saved to ${zipPath}`); - - // dispatch the email to the recipient, containing the finalized zip file - const error = await Email.dispatch({ - to, - subject: `Remote debug: compressed backup of ${target}...`, - content: this.generateDebugInstructions(zipName, target), - attachments: [{ filename: zipName, path: zipPath }] - }); - - // since this is intended to be a zero-footprint operation, clean up - // by unlinking both the backup generated earlier in the function and the compressed zip file. - // to generate a persistent backup, just run backup. - unlinkSync(zipPath); - rimraf.sync(targetPath); - - // indicate success or failure - mainLog(`${error === null ? green("successfully dispatched") : red("failed to dispatch")} ${zipName} to ${cyan(to)}`); - error && mainLog(red(error.message)); - } catch (error) { - mainLog(red("unable to dispatch zipped backup...")); - mainLog(red(error.message)); - } - } - -} - -export namespace DashSessionAgent { - - export const notificationRecipient = "brownptcdash@gmail.com"; - -} \ No newline at end of file +// import { Email, pathFromRoot } from "../ActionUtilities"; +// import { red, yellow, green, cyan } from "colors"; +// import { get } from "request-promise"; +// import { Utils } from "../../Utils"; +// import { WebSocket } from "../Websocket/Websocket"; +// import { MessageStore } from "../Message"; +// import { launchServer, onWindows } from ".."; +// import { readdirSync, statSync, createWriteStream, readFileSync, unlinkSync } from "fs"; +// import * as Archiver from "archiver"; +// import { resolve } from "path"; +// import { AppliedSessionAgent, MessageHandler, ExitHandler, Monitor, ServerWorker } from "resilient-server-session"; +// import rimraf = require("rimraf"); + +// /** +// * If we're the monitor (master) thread, we should launch the monitor logic for the session. +// * Otherwise, we must be on a worker thread that was spawned *by* the monitor (master) thread, and thus +// * our job should be to run the server. +// */ +// export class DashSessionAgent extends AppliedSessionAgent { + +// private readonly signature = "-Dash Server Session Manager"; +// private readonly releaseDesktop = pathFromRoot("../../Desktop"); + +// /** +// * The core method invoked when the single master thread is initialized. +// * Installs event hooks, repl commands and additional IPC listeners. +// */ +// protected async initializeMonitor(monitor: Monitor, sessionKey: string): Promise { +// await this.dispatchSessionPassword(sessionKey); +// monitor.addReplCommand("pull", [], () => monitor.exec("git pull")); +// monitor.addReplCommand("solr", [/start|stop|index/], this.executeSolrCommand); +// monitor.addReplCommand("backup", [], this.backup); +// monitor.addReplCommand("debug", [/\S+\@\S+/], async ([to]) => this.dispatchZippedDebugBackup(to)); +// monitor.on("backup", this.backup); +// monitor.on("debug", async ({ to }) => this.dispatchZippedDebugBackup(to)); +// monitor.coreHooks.onCrashDetected(this.dispatchCrashReport); +// } + +// /** +// * The core method invoked when a server worker thread is initialized. +// * Installs logic to be executed when the server worker dies. +// */ +// protected async initializeServerWorker(): Promise { +// const worker = ServerWorker.Create(launchServer); // server initialization delegated to worker +// worker.addExitHandler(this.notifyClient); +// return worker; +// } + +// /** +// * Prepares the body of the email with instructions on restoring the transmitted remote database backup locally. +// */ +// private _remoteDebugInstructions: string | undefined; +// private generateDebugInstructions = (zipName: string, target: string): string => { +// if (!this._remoteDebugInstructions) { +// this._remoteDebugInstructions = readFileSync(resolve(__dirname, "./templates/remote_debug_instructions.txt"), { encoding: "utf8" }); +// } +// return this._remoteDebugInstructions +// .replace(/__zipname__/, zipName) +// .replace(/__target__/, target) +// .replace(/__signature__/, this.signature); +// } + +// /** +// * Prepares the body of the email with information regarding a crash event. +// */ +// private _crashInstructions: string | undefined; +// private generateCrashInstructions({ name, message, stack }: Error): string { +// if (!this._crashInstructions) { +// this._crashInstructions = readFileSync(resolve(__dirname, "./templates/crash_instructions.txt"), { encoding: "utf8" }); +// } +// return this._crashInstructions +// .replace(/__name__/, name || "[no error name found]") +// .replace(/__message__/, message || "[no error message found]") +// .replace(/__stack__/, stack || "[no error stack found]") +// .replace(/__signature__/, this.signature); +// } + +// /** +// * This sends a pseudorandomly generated guid to the configuration's recipients, allowing them alone +// * to kill the server via the /kill/:key route. +// */ +// private dispatchSessionPassword = async (sessionKey: string): Promise => { +// const { mainLog } = this.sessionMonitor; +// const { notificationRecipient } = DashSessionAgent; +// mainLog(green("dispatching session key...")); +// const error = await Email.dispatch({ +// to: notificationRecipient, +// subject: "Dash Release Session Admin Authentication Key", +// content: [ +// `Here's the key for this session (started @ ${new Date().toUTCString()}):`, +// sessionKey, +// this.signature +// ].join("\n\n") +// }); +// if (error) { +// this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} (${yellow(error.message)})`)); +// mainLog(red("distribution of session key experienced errors")); +// } else { +// mainLog(green("successfully distributed session key to recipients")); +// } +// } + +// /** +// * This sends an email with the generated crash report. +// */ +// private dispatchCrashReport: MessageHandler<{ error: Error }> = async ({ error: crashCause }) => { +// const { mainLog } = this.sessionMonitor; +// const { notificationRecipient } = DashSessionAgent; +// const error = await Email.dispatch({ +// to: notificationRecipient, +// subject: "Dash Web Server Crash", +// content: this.generateCrashInstructions(crashCause) +// }); +// if (error) { +// this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} ${yellow(`(${error.message})`)}`)); +// mainLog(red("distribution of crash notification experienced errors")); +// } else { +// mainLog(green("successfully distributed crash notification to recipients")); +// } +// } + +// /** +// * Logic for interfacing with Solr. Either starts it, +// * stops it, or rebuilds its indicies. +// */ +// private executeSolrCommand = async (args: string[]): Promise => { +// const { exec, mainLog } = this.sessionMonitor; +// const action = args[0]; +// if (action === "index") { +// exec("npx ts-node ./updateSearch.ts", { cwd: pathFromRoot("./src/server") }); +// } else { +// const command = `${onWindows ? "solr.cmd" : "solr"} ${args[0] === "start" ? "start" : "stop -p 8983"}`; +// await exec(command, { cwd: "./solr-8.3.1/bin" }); +// try { +// await get("http://localhost:8983"); +// mainLog(green("successfully connected to 8983 after running solr initialization")); +// } catch { +// mainLog(red("unable to connect at 8983 after running solr initialization")); +// } +// } +// } + +// /** +// * Broadcast to all clients that their connection +// * is no longer valid, and explain why / what to expect. +// */ +// private notifyClient: ExitHandler = reason => { +// const { _socket } = WebSocket; +// if (_socket) { +// const message = typeof reason === "boolean" ? (reason ? "exit" : "temporary") : "crash"; +// Utils.Emit(_socket, MessageStore.ConnectionTerminated, message); +// } +// } + +// /** +// * Performs a backup of the database, saved to the desktop subdirectory. +// * This should work as is only on our specific release server. +// */ +// private backup = async (): Promise => this.sessionMonitor.exec("backup.bat", { cwd: this.releaseDesktop }); + +// /** +// * Compress either a brand new backup or the most recent backup and send it +// * as an attachment to an email, dispatched to the requested recipient. +// * @param mode specifies whether or not to make a new backup before exporting +// * @param to the recipient of the email +// */ +// private async dispatchZippedDebugBackup(to: string): Promise { +// const { mainLog } = this.sessionMonitor; +// try { +// // if desired, complete an immediate backup to send +// await this.backup(); +// mainLog("backup complete"); + +// const backupsDirectory = `${this.releaseDesktop}/backups`; + +// // sort all backups by their modified time, and choose the most recent one +// const target = readdirSync(backupsDirectory).map(filename => ({ +// modifiedTime: statSync(`${backupsDirectory}/${filename}`).mtimeMs, +// filename +// })).sort((a, b) => b.modifiedTime - a.modifiedTime)[0].filename; +// mainLog(`targeting ${target}...`); + +// // create a zip file and to it, write the contents of the backup directory +// const zipName = `${target}.zip`; +// const zipPath = `${this.releaseDesktop}/${zipName}`; +// const targetPath = `${backupsDirectory}/${target}`; +// const output = createWriteStream(zipPath); +// const zip = Archiver('zip'); +// zip.pipe(output); +// zip.directory(`${targetPath}/Dash`, false); +// await zip.finalize(); +// mainLog(`zip finalized with size ${statSync(zipPath).size} bytes, saved to ${zipPath}`); + +// // dispatch the email to the recipient, containing the finalized zip file +// const error = await Email.dispatch({ +// to, +// subject: `Remote debug: compressed backup of ${target}...`, +// content: this.generateDebugInstructions(zipName, target), +// attachments: [{ filename: zipName, path: zipPath }] +// }); + +// // since this is intended to be a zero-footprint operation, clean up +// // by unlinking both the backup generated earlier in the function and the compressed zip file. +// // to generate a persistent backup, just run backup. +// unlinkSync(zipPath); +// rimraf.sync(targetPath); + +// // indicate success or failure +// mainLog(`${error === null ? green("successfully dispatched") : red("failed to dispatch")} ${zipName} to ${cyan(to)}`); +// error && mainLog(red(error.message)); +// } catch (error) { +// mainLog(red("unable to dispatch zipped backup...")); +// mainLog(red(error.message)); +// } +// } + +// } + +// export namespace DashSessionAgent { + +// export const notificationRecipient = "brownptcdash@gmail.com"; + +// } \ No newline at end of file diff --git a/src/server/index.ts b/src/server/index.ts index 313a2f0e2..454d99305 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -22,7 +22,7 @@ import GeneralGoogleManager from "./ApiManagers/GeneralGoogleManager"; import GooglePhotosManager from "./ApiManagers/GooglePhotosManager"; import { Logger } from "./ProcessFactory"; import { yellow } from "colors"; -import { DashSessionAgent } from "./DashSession/DashSessionAgent"; +// import { DashSessionAgent } from "./DashSession/DashSessionAgent"; import SessionManager from "./ApiManagers/SessionManager"; import { AppliedSessionAgent } from "resilient-server-session"; @@ -141,7 +141,7 @@ export async function launchServer() { * So, the 'else' clause is exactly what we've always run when executing npm start. */ if (process.env.RELEASE) { - (sessionAgent = new DashSessionAgent()).launch(); + // (sessionAgent = new DashSessionAgent()).launch(); } else { launchServer(); } -- cgit v1.2.3-70-g09d2 From 13e6b075154001ce33845a72454e3cd039a92670 Mon Sep 17 00:00:00 2001 From: Andy Rickert Date: Tue, 24 Mar 2020 19:03:19 -0700 Subject: reaally pretty drop down menu functionality : ) --- src/client/views/SearchDocBox.tsx | 2 +- src/client/views/search/IconBar.scss | 3 +- src/client/views/search/SearchBox.scss | 14 ++++- src/client/views/search/SearchBox.tsx | 109 +++++++++++++++++++++++++++++++-- 4 files changed, 118 insertions(+), 10 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index 5a76a882f..c57f9e737 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -411,7 +411,7 @@ export class SearchDocBox extends React.Component { - s +
document.getElementById("node")?.scrollHeight,()=>{console.log("longer")}) + } + private _reactionDisposer?: IReactionDisposer; + componentDidMount = () => { if (this.inputRef.current) { this.inputRef.current.focus(); runInAction(() => { this._searchbarOpen = true; }); + } } + @action getViews = async (doc: Doc) => { const results = await SearchUtil.GetViewsOfDocument(doc); @@ -369,6 +375,12 @@ export class SearchBox extends React.Component { @action.bound handleNodeChange = () => { this._nodeStatus = !this._nodeStatus; + if (this._nodeStatus){ + this.expandSection("node") + } + else{ + this.collapseSection("node") + } } @action.bound @@ -376,8 +388,95 @@ export class SearchBox extends React.Component { this._keyStatus = !this._keyStatus; } + @action.bound + handleFilterChange=() =>{ + this._filterOpen=!this._filterOpen; + if (this._filterOpen){ + this.expandSection("filterhead"); + document.getElementById("filterhead")!.style.padding="5"; + } + else{ + this.collapseSection("filterhead"); + + + } + } + // @observable + // private menuHeight= 0; + + @computed + get menuHeight(){ + return document.getElementById("hi")?.clientHeight; + } + + + collapseSection(thing:string) { + let element= document.getElementById(thing)!; + // get the height of the element's inner content, regardless of its actual size + var sectionHeight = element.scrollHeight; + + // temporarily disable all css transitions + var elementTransition = element.style.transition; + element.style.transition = ''; + + // on the next frame (as soon as the previous style change has taken effect), + // explicitly set the element's height to its current pixel height, so we + // aren't transitioning out of 'auto' + requestAnimationFrame(function() { + element.style.height = sectionHeight + 'px'; + element.style.transition = elementTransition; + + // on the next frame (as soon as the previous style change has taken effect), + // have the element transition to height: 0 + requestAnimationFrame(function() { + element.style.height = 0 + 'px'; + thing == "filterhead"? document.getElementById("filterhead")!.style.padding="0" : null; + }); + }); + + // mark the section as "currently collapsed" + element.setAttribute('data-collapsed', 'true'); + } + + expandSection(thing:string) { + console.log("expand"); + let element= document.getElementById(thing)!; + // get the height of the element's inner content, regardless of its actual size + var sectionHeight = element.scrollHeight; + + // have the element transition to the height of its inner content + let temp = element.style.height; + element.style.height = sectionHeight + 'px'; + + // when the next css transition finishes (which should be the one we just triggered) + element.addEventListener('transitionend', function handler(e) { + // remove this event listener so it only gets triggered once + console.log("autoset"); + element.removeEventListener('transitionend', handler); + + // remove "height" from the element's inline styles, so it can return to its initial value + element.style.height="auto"; + //element.style.height = undefined; + }); + + // mark the section as "currently not collapsed" + element.setAttribute('data-collapsed', 'false'); + + } + + autoset(thing: string){ + let element= document.getElementById(thing)!; + console.log("autoset"); + element.removeEventListener('transitionend', function(e){}); + + // remove "height" from the element's inline styles, so it can return to its initial value + element.style.height="auto"; + //element.style.height = undefined; + + } render() { + return (
{ e.stopPropagation(); e.preventDefault(); }}>
@@ -387,16 +486,16 @@ export class SearchBox extends React.Component { - +
-
-
+
+
-
+
-- cgit v1.2.3-70-g09d2 From adabfbea2b034beb310530aef9cc8b206e260b67 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 3 Apr 2020 20:23:15 -0400 Subject: added rootSelected() to make forceActive work better --- src/client/documents/Documents.ts | 2 +- src/client/util/RichTextSchema.tsx | 1 + src/client/views/DocComponent.tsx | 6 +++-- src/client/views/GestureOverlay.tsx | 1 + src/client/views/MainView.tsx | 4 ++++ src/client/views/OverlayView.tsx | 1 + src/client/views/Palette.tsx | 26 +++++++--------------- src/client/views/RecommendationsBox.tsx | 1 + src/client/views/SearchDocBox.tsx | 3 ++- .../views/collections/CollectionDockingView.tsx | 1 + .../views/collections/CollectionLinearView.tsx | 3 ++- .../views/collections/CollectionSchemaView.tsx | 1 + .../views/collections/CollectionStackingView.tsx | 1 + src/client/views/collections/CollectionSubView.tsx | 5 +++++ .../views/collections/CollectionTreeView.tsx | 2 ++ src/client/views/collections/CollectionView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 + .../collections/collectionFreeForm/MarqueeView.tsx | 1 - src/client/views/nodes/AudioBox.tsx | 12 +++++++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 7 +++--- .../views/nodes/ContentFittingDocumentView.tsx | 1 + src/client/views/nodes/DocumentBox.tsx | 1 + src/client/views/nodes/DocumentContentsView.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 24 +++++++++++++++----- src/client/views/nodes/FieldView.tsx | 1 + src/client/views/nodes/FormattedTextBoxComment.tsx | 1 + src/client/views/pdf/PDFViewer.tsx | 3 +-- .../views/presentationview/PresElementBox.tsx | 3 ++- src/client/views/search/SearchItem.tsx | 3 ++- src/mobile/MobileInterface.tsx | 2 ++ .../authentication/models/current_user_utils.ts | 2 +- 31 files changed, 83 insertions(+), 43 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a69bfae01..0a2269bac 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -435,7 +435,7 @@ export namespace Docs { Scripting.addGlobal(Buxton); const delegateKeys = ["x", "y", "layoutKey", "_width", "_height", "_panX", "_panY", "_viewType", "_nativeWidth", "_nativeHeight", "dropAction", "childDropAction", "_annotationOn", - "_chromeStatus", "_forceActive", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_showSidebar", "_showTitle", "_showCaption", "_showTitleHover", "_backgroundColor", + "_chromeStatus", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_showSidebar", "_showTitle", "_showCaption", "_showTitleHover", "_backgroundColor", "_xMargin", "_yMargin", "_xPadding", "_yPadding", "_singleLine", "_scrollTop", "_color", "isButton", "isBackground", "removeDropProperties", "treeViewOpen"]; diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 094cd58f3..4a930177d 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -818,6 +818,7 @@ export class DashDocView { LibraryPath={this._textBox.props.LibraryPath} fitToBox={BoolCast(dashDoc._fitToBox)} addDocument={returnFalse} + rootSelected={this._textBox.props.isSelected} removeDocument={removeDoc} ScreenToLocalTransform={this.getDocTransform} addDocTab={this._textBox.props.addDocTab} diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index f4e830a48..454c245cc 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -29,6 +29,7 @@ interface DocExtendableProps { fieldKey: string; isSelected: (outsideReaction?: boolean) => boolean; renderDepth: number; + rootSelected: () => boolean; } export function DocExtendableComponent

(schemaCtor: (doc: Doc) => T) { class Component extends Touchable

{ @@ -36,7 +37,7 @@ export function DocExtendableComponent

(schemaCt @computed get Document(): T { return schemaCtor(this.props.Document); } @computed get layoutDoc() { return Doc.Layout(this.props.Document); } @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Cast(this.props.Document.resolvedDataDoc, Doc, null) || Doc.GetProto(this.props.Document)) as Doc; } - active = (outsideReaction?: boolean) => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools + active = (outsideReaction?: boolean) => !this.props.Document.isBackground && ((this.props.Document.forceActive && this.props.rootSelected()) || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools } return Component; } @@ -50,6 +51,7 @@ export interface DocAnnotatableProps { active: () => boolean; whenActiveChanged: (isActive: boolean) => void; isSelected: (outsideReaction?: boolean) => boolean; + rootSelected: () => boolean; renderDepth: number; } export function DocAnnotatableComponent

(schemaCtor: (doc: Doc) => T) { @@ -86,7 +88,7 @@ export function DocAnnotatableComponent

(schema whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); active = (outsideReaction?: boolean) => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) && - (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) + ((this.props.Document.forceActive && this.props.rootSelected()) || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) annotationsActive = (outsideReaction?: boolean) => (InkingControl.Instance.selectedTool !== InkTool.None || (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) } diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index ea60907f6..26bee9a6f 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -705,6 +705,7 @@ export default class GestureOverlay extends Touchable { LibraryPath={emptyPath} addDocument={undefined} addDocTab={returnFalse} + rootSelected={returnTrue} pinToPres={emptyFunction} onClick={undefined} removeDocument={undefined} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 8d9be5980..fae520e40 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -309,6 +309,7 @@ export class MainView extends React.Component { addDocument={undefined} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} + rootSelected={returnTrue} onClick={undefined} backgroundColor={this.defaultBackgroundColors} removeDocument={undefined} @@ -407,6 +408,7 @@ export class MainView extends React.Component { DataDoc={undefined} LibraryPath={emptyPath} addDocument={undefined} + rootSelected={returnTrue} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} removeDocument={undefined} @@ -435,6 +437,7 @@ export class MainView extends React.Component { addDocument={undefined} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} + rootSelected={returnTrue} removeDocument={returnFalse} onClick={undefined} ScreenToLocalTransform={this.mainContainerXf} @@ -523,6 +526,7 @@ export class MainView extends React.Component { fieldKey={"data"} dropAction={"alias"} annotationsKey={""} + rootSelected={returnTrue} bringToFront={emptyFunction} select={emptyFunction} active={returnFalse} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 220efd4a8..7587071db 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -174,6 +174,7 @@ export class OverlayView extends React.Component { Document={d} LibraryPath={emptyPath} ChromeHeight={returnZero} + rootSelected={returnTrue} // isSelected={returnFalse} // select={emptyFunction} // layoutKey={"layout"} diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index e04f814d1..674b27918 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -1,23 +1,12 @@ +import { IReactionDisposer, observable, reaction } from "mobx"; +import { observer } from "mobx-react"; import * as React from "react"; -import "./Palette.scss"; -import { PointData } from "../../new_fields/InkField"; import { Doc } from "../../new_fields/Doc"; -import { Docs } from "../documents/Documents"; -import { ScriptField, ComputedField } from "../../new_fields/ScriptField"; -import { List } from "../../new_fields/List"; -import { DocumentView } from "./nodes/DocumentView"; -import { emptyPath, returnFalse, emptyFunction, returnOne, returnEmptyString, returnTrue } from "../../Utils"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { NumCast } from "../../new_fields/Types"; +import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue } from "../../Utils"; import { Transform } from "../util/Transform"; -import { computed, action, IReactionDisposer, reaction, observable } from "mobx"; -import { FieldValue, Cast, NumCast } from "../../new_fields/Types"; -import { observer } from "mobx-react"; -import { DocumentContentsView } from "./nodes/DocumentContentsView"; -import { CollectionStackingView } from "./collections/CollectionStackingView"; -import { CollectionView } from "./collections/CollectionView"; -import { CollectionSubView, SubCollectionViewProps } from "./collections/CollectionSubView"; -import { makeInterface } from "../../new_fields/Schema"; -import { documentSchema } from "../../new_fields/documentSchemas"; +import { DocumentView } from "./nodes/DocumentView"; +import "./Palette.scss"; export interface PaletteProps { x: number; @@ -40,7 +29,7 @@ export default class Palette extends React.Component { } componentWillUnmount = () => { - this._selectedDisposer && this._selectedDisposer(); + this._selectedDisposer?.(); } render() { @@ -54,6 +43,7 @@ export default class Palette extends React.Component { LibraryPath={emptyPath} addDocument={undefined} addDocTab={returnFalse} + rootSelected={returnTrue} pinToPres={emptyFunction} removeDocument={undefined} onClick={undefined} diff --git a/src/client/views/RecommendationsBox.tsx b/src/client/views/RecommendationsBox.tsx index 5ebba0abb..bf8de36b4 100644 --- a/src/client/views/RecommendationsBox.tsx +++ b/src/client/views/RecommendationsBox.tsx @@ -68,6 +68,7 @@ export class RecommendationsBox extends React.Component { addDocument={returnFalse} LibraryPath={emptyPath} removeDocument={returnFalse} + rootSelected={returnFalse} ScreenToLocalTransform={Transform.Identity} addDocTab={returnFalse} pinToPres={returnFalse} diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index c57f9e737..e66de39d4 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -410,8 +410,9 @@ export class SearchDocBox extends React.Component {

- +
{ Document={document} DataDoc={resolvedDataDoc} bringToFront={emptyFunction} + rootSelected={returnTrue} addDocument={undefined} removeDocument={undefined} ContentScaling={this.contentScaling} diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 344605412..a6ada75b2 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc'; import { makeInterface } from '../../../new_fields/Schema'; import { BoolCast, NumCast, StrCast, Cast } from '../../../new_fields/Types'; -import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../../Utils'; +import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils, returnFalse } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { Transform } from '../../util/Transform'; import "./CollectionLinearView.scss"; @@ -110,6 +110,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { moveDocument={this.props.moveDocument} addDocTab={this.props.addDocTab} pinToPres={emptyFunction} + rootSelected={this.props.isSelected} removeDocument={this.props.removeDocument} onClick={undefined} ScreenToLocalTransform={this.getTransform(dref)} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 981438513..a1b541f74 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -124,6 +124,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { LibraryPath={this.props.LibraryPath} childDocs={this.childDocs} renderDepth={this.props.renderDepth} + rootSelected={this.rootSelected} PanelWidth={this.previewWidth} PanelHeight={this.previewHeight} getTransform={this.getPreviewTransform} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 076dd3629..d21e17bbc 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -176,6 +176,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { LibraryPath={this.props.LibraryPath} renderDepth={this.props.renderDepth + 1} fitToBox={this.props.fitToBox} + rootSelected={this.rootSelected} dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} onClick={layoutDoc.isTemplateDoc ? this.onClickHandler : this.onChildClickHandler} PanelWidth={width} diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 70927cf22..d1d6ae3c1 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -34,6 +34,7 @@ export interface CollectionViewProps extends FieldViewProps { PanelHeight: () => number; VisibleHeight?: () => number; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; + rootSelected: () => boolean; fieldKey: string; } @@ -95,6 +96,10 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document)); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template } + rootSelected = () => { + return this.props.isSelected() || (this.props.Document.rootDocument || this.props.Document.forceActive ? this.props.rootSelected() : false); + } + // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc. // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through // to its children which may be templates. diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 6ee48f11b..fc612c66d 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -373,6 +373,7 @@ class TreeView extends React.Component { DataDocument={this.templateDataDoc} LibraryPath={emptyPath} renderDepth={this.props.renderDepth + 1} + rootSelected={returnTrue} backgroundColor={this.props.backgroundColor} fitToBox={this.boundsOfCollectionDocument !== undefined} PanelWidth={this.docWidth} @@ -454,6 +455,7 @@ class TreeView extends React.Component { LibraryPath={this.props.libraryPath || []} addDocument={undefined} addDocTab={this.props.addDocTab} + rootSelected={returnTrue} pinToPres={emptyFunction} onClick={this.props.onChildClick || editTitle} dropAction={this.props.dropAction} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index df1770ffe..3913ccd88 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -117,7 +117,7 @@ export class CollectionView extends Touchable { return viewField; } - active = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || BoolCast(this.props.Document.forceActive) || this._isChildActive || this.props.renderDepth === 0; + active = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.rootSelected() && BoolCast(this.props.Document.forceActive)) || this._isChildActive || this.props.renderDepth === 0; whenActiveChanged = (isActive: boolean) => { this.props.whenActiveChanged(this._isChildActive = isActive); }; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2871fe192..a164e1794 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -832,6 +832,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { Document: childLayout, LibraryPath: this.libraryPath, layoutKey: undefined, + rootSelected: this.rootSelected, dropAction: StrCast(this.props.Document.childDropAction) as dropActionType, //onClick: undefined, // this.props.onClick, // bcz: check this out -- I don't think we want to inherit click handlers, or we at least need a way to ignore them onClick: this.onChildClickHandler, diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 276a49570..503df10c2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -5,7 +5,6 @@ import { InkField, InkData } from "../../../../new_fields/InkField"; import { List } from "../../../../new_fields/List"; import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField"; import { Cast, NumCast, FieldValue, StrCast } from "../../../../new_fields/Types"; -import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils"; import { Utils } from "../../../../Utils"; import { Docs, DocUtils } from "../../../documents/Documents"; import { SelectionManager } from "../../../util/SelectionManager"; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 03b2a2297..bd54d64ff 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -7,7 +7,7 @@ import { AudioField, nullAudio } from "../../../new_fields/URLField"; import { DocExtendableComponent } from "../DocComponent"; import { makeInterface, createSchema } from "../../../new_fields/Schema"; import { documentSchema } from "../../../new_fields/documentSchemas"; -import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent } from "../../../Utils"; +import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse } from "../../../Utils"; import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx"; import { DateField } from "../../../new_fields/DateField"; import { SelectionManager } from "../../util/SelectionManager"; @@ -258,9 +258,15 @@ export class AudioBox extends DocExtendableComponent
-
Doc.linkFollowHighlight(la1)} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index eaab4086c..356192797 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -89,14 +89,15 @@ export class CollectionFreeFormDocumentView extends DocComponent - {!this.props.fitToBox ? : + : boolean; pinToPres: (document: Doc) => void; dontRegisterView?: boolean; + rootSelected: () => boolean; } @observer diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index debe104d7..47118e758 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -122,6 +122,7 @@ export class DocumentBox extends DocAnnotatableComponent Opt; + makeLink?: () => Opt, // function to call when a link is made }> { @computed get layout(): string { TraceMobx(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 1e02ab44e..42f5fb946 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -60,6 +60,7 @@ export interface DocumentViewProps { LayoutDoc?: () => Opt; LibraryPath: Doc[]; fitToBox?: boolean; + rootSelected: () => boolean; // whether the root of a template has been selected onClick?: ScriptField; onPointerDown?: ScriptField; onPointerUp?: ScriptField; @@ -277,7 +278,7 @@ export class DocumentView extends DocComponent(Docu this.dontDecorateSelection = this.props.Document.dontDecorateSelection && (!e.ctrlKey || e.button < 2); if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { - e.stopPropagation(); + let stopPropagate = true; let preventDefault = true; this.props.bringToFront(this.props.Document); if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click @@ -301,9 +302,14 @@ export class DocumentView extends DocComponent(Docu SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. UndoManager.RunInBatch(() => this.buttonClick(e.altKey, e.ctrlKey), "on link button follow"); } else { - SelectionManager.SelectDoc(this, e.ctrlKey); + if (this.props.Document.isTemplateForField && !(e.ctrlKey || e.button > 0)) { + stopPropagate = false; + } else { + SelectionManager.SelectDoc(this, e.ctrlKey); + } preventDefault = false; } + stopPropagate && e.stopPropagation(); preventDefault && e.preventDefault(); } } @@ -928,6 +934,9 @@ export class DocumentView extends DocComponent(Docu const fallback = Cast(this.props.Document.layoutKey, "string"); return typeof fallback === "string" ? fallback : "layout"; } + rootSelected = () => { + return this.isSelected(false) || (this.props.Document.forceActive && this.props.rootSelected?.() ? true : false); + } childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling()); @computed get contents() { TraceMobx(); @@ -937,6 +946,7 @@ export class DocumentView extends DocComponent(Docu DataDoc={this.props.DataDoc} LayoutDoc={this.props.LayoutDoc} makeLink={this.makeLink} + rootSelected={this.rootSelected} fitToBox={this.props.fitToBox} LibraryPath={this.props.LibraryPath} addDocument={this.props.addDocument} @@ -985,9 +995,13 @@ export class DocumentView extends DocComponent(Docu {StrCast(this.props.Document.title)} {this.Document.links && DocListCast(this.Document.links).filter(d => !d.hidden).filter(this.isNonTemporalLink).map((d, i) =>
- doc.hidden = true)} /> + doc.hidden = true)} />
)}
; } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 0305f43d5..13a1becf7 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -29,6 +29,7 @@ export interface FieldViewProps { dropAction: dropActionType; isSelected: (outsideReaction?: boolean) => boolean; select: (isCtrlPressed: boolean) => void; + rootSelected: () => boolean; renderDepth: number; addDocument?: (document: Doc) => boolean; addDocTab: (document: Doc, where: string) => boolean; diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx index 61df188f8..d1a563494 100644 --- a/src/client/views/nodes/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/FormattedTextBoxComment.tsx @@ -181,6 +181,7 @@ export class FormattedTextBoxComment { LibraryPath={emptyPath} fitToBox={true} moveDocument={returnFalse} + rootSelected={returnFalse} getTransform={Transform.Identity} active={returnFalse} addDocument={returnFalse} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 71495d95f..c032f019d 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -31,8 +31,6 @@ import { InkingControl } from "../InkingControl"; import { InkTool } from "../../../new_fields/InkField"; import { TraceMobx } from "../../../new_fields/util"; import { PdfField } from "../../../new_fields/URLField"; -import { PDFBox } from "../nodes/PDFBox"; -import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { DocumentView } from "../nodes/DocumentView"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); @@ -61,6 +59,7 @@ interface IViewerProps { PanelHeight: () => number; ContentScaling: () => number; select: (isCtrlPressed: boolean) => void; + rootSelected: () => boolean; startupLive: boolean; renderDepth: number; focus: (doc: Doc) => void; diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 758795ed5..7ad3474e8 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -9,7 +9,7 @@ import { documentSchema } from '../../../new_fields/documentSchemas'; import { Id } from "../../../new_fields/FieldSymbols"; import { createSchema, makeInterface } from '../../../new_fields/Schema'; import { Cast, NumCast } from "../../../new_fields/Types"; -import { emptyFunction, emptyPath, returnFalse } from "../../../Utils"; +import { emptyFunction, emptyPath, returnFalse, returnTrue } from "../../../Utils"; import { Transform } from "../../util/Transform"; import { CollectionViewType } from '../collections/CollectionView'; import { DocExtendableComponent } from '../DocComponent'; @@ -175,6 +175,7 @@ export class PresElementBox extends DocExtendableComponent { Date: Fri, 3 Apr 2020 22:04:19 -0400 Subject: cleaning up .. removing Docs.Create.SearchDocument --- src/client/documents/DocumentTypes.ts | 2 +- src/client/documents/Documents.ts | 4 --- src/client/views/SearchDocBox.tsx | 37 ++++++++-------------- src/client/views/nodes/DocumentContentsView.tsx | 1 - src/client/views/search/SearchBox.tsx | 3 -- .../authentication/models/current_user_utils.ts | 2 +- 6 files changed, 15 insertions(+), 34 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 5ec1cfdb4..b98e4d581 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -22,7 +22,7 @@ export enum DocumentType { RECOMMENDATION = "recommendation", LINKFOLLOW = "linkfollow", PRESELEMENT = "preselement", - QUERY = "search", + QUERY = "query", COLOR = "color", DOCULINK = "doculink", PDFANNO = "pdfanno", diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index c5b080ffb..1a2969cf5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -708,10 +708,6 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.RECOMMENDATION), new List(data), options); } - export function SearchDocument(documents: Array, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.SEARCHBOX), new List(documents), options); - } - export type DocConfig = { doc: Doc, initialWidth?: number, diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index e66de39d4..cd9666af8 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -1,31 +1,20 @@ +import { library } from "@fortawesome/fontawesome-svg-core"; +import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; +import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import React = require("react"); -import { observable, action, computed, runInAction } from "mobx"; -import Measure from "react-measure"; //import "./SearchBoxDoc.scss"; -import { Doc, DocListCast, WidthSym, HeightSym } from "../../new_fields/Doc"; -import { DocumentIcon } from "./nodes/DocumentIcon"; -import { StrCast, NumCast, BoolCast, Cast } from "../../new_fields/Types"; -import { returnFalse, emptyFunction, returnEmptyString, returnOne } from "../../Utils"; -import { Transform } from "../util/Transform"; -import { ObjectField } from "../../new_fields/ObjectField"; -import { DocumentView } from "./nodes/DocumentView"; -import { DocumentType } from '../documents/DocumentTypes'; -import { ClientRecommender } from "../ClientRecommender"; -import { DocServer } from "../DocServer"; +import { Doc, DocListCast } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; -import { FieldView, FieldViewProps } from "./nodes/FieldView"; -import { DocumentManager } from "../util/DocumentManager"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { library } from "@fortawesome/fontawesome-svg-core"; -import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; -import { DocUtils, Docs } from "../documents/Documents"; -import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; -import { EditableView } from "./EditableView"; +import { BoolCast, Cast, NumCast, StrCast } from "../../new_fields/Types"; +import { returnFalse } from "../../Utils"; +import { Docs } from "../documents/Documents"; import { SearchUtil } from "../util/SearchUtil"; -import { SearchItem } from "./search/SearchItem"; +import { EditableView } from "./EditableView"; +import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; +import { FieldView, FieldViewProps } from "./nodes/FieldView"; import { FilterBox } from "./search/FilterBox"; -import { SearchBox } from "./search/SearchBox"; +import { SearchItem } from "./search/SearchItem"; +import React = require("react"); export interface RecProps { documents: { preview: Doc, similarity: number }[]; @@ -301,7 +290,7 @@ export class SearchDocBox extends React.Component { } } //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); + return Docs.Create.QueryDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Query Docs: "${this._searchString}"` }); } @action.bound diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 687137adc..dc71ba280 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -35,7 +35,6 @@ import { WebBox } from "./WebBox"; import { InkingStroke } from "../InkingStroke"; import React = require("react"); import { RecommendationsBox } from "../RecommendationsBox"; -import { SearchBox } from "../search/SearchBox"; import { TraceMobx } from "../../../new_fields/util"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index e7941a9ba..49b6b18ca 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -416,9 +416,6 @@ export class SearchBox extends React.Component { y += 300; } } - console.log("create"); - //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - //return Docs.Create.SearchDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Search Docs: "${this._searchString}"` }); return Docs.Create.QueryDocument({ _autoHeight: true, title: this._searchString, filterQuery: this.filterQuery, searchQuery: this._searchString }); } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index e34a9b958..fc6e36485 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -89,7 +89,7 @@ export class CurrentUserUtils { { title: "use stamp", icon: "stamp", click: 'activateStamp(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this)', backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc }, { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "pink", activePen: doc }, { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "white", activePen: doc }, - { title: "search", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.SearchDocument({ _width: 200, title: "an image of a cat" })' }, + { title: "query", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, ]; -- cgit v1.2.3-70-g09d2 From 50552174123eb5622821de5f848e6e70c7346214 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 3 Apr 2020 23:45:34 -0400 Subject: fixed a bunch of warnings --- src/client/documents/Documents.ts | 7 ++-- src/client/util/SelectionManager.ts | 6 +--- src/client/views/DocumentDecorations.tsx | 1 - src/client/views/MainView.tsx | 40 +++++++++------------ src/client/views/SearchDocBox.tsx | 15 ++++---- src/client/views/TemplateMenu.tsx | 1 + .../views/collections/CollectionLinearView.scss | 2 ++ .../views/collections/CollectionLinearView.tsx | 27 +++++++------- .../views/collections/CollectionSchemaCells.tsx | 1 + src/client/views/nodes/DocumentBox.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 +-- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/KeyValuePair.tsx | 1 + src/client/views/pdf/PDFMenu.tsx | 2 +- src/client/views/search/SearchBox.tsx | 38 ++++++++------------ src/new_fields/documentSchemas.ts | 1 - .../authentication/models/current_user_utils.ts | 42 +++++++++++++--------- 17 files changed, 90 insertions(+), 102 deletions(-) (limited to 'src/client/views/SearchDocBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1a2969cf5..514200d95 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -118,7 +118,6 @@ export interface DocumentOptions { lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed opacity?: number; defaultBackgroundColor?: string; - dontDecorateSelection?: boolean; // whether document decorations should be displayed when the document is selected isBackground?: boolean; isButton?: boolean; columnWidth?: number; @@ -164,9 +163,9 @@ export interface DocumentOptions { flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; selectedIndex?: number; syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text - searchText?: string, //for searchbox - searchQuery?: string, // for queryBox - filterQuery?: string, + searchText?: string; //for searchbox + searchQuery?: string; // for queryBox + filterQuery?: string; linearViewIsExpanded?: boolean; // is linear view expanded } diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 7221fbbf9..2a6e3bf8a 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -33,7 +33,6 @@ export namespace SelectionManager { @action DeselectDoc(docView: DocumentView): void { if (manager.SelectedDocuments.get(docView)) { - docView.dontDecorateSelection = false; manager.SelectedDocuments.delete(docView); docView.props.whenActiveChanged(false); Doc.UserDoc().SelectedDocs = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); @@ -41,10 +40,7 @@ export namespace SelectionManager { } @action DeselectAll(): void { - Array.from(manager.SelectedDocuments.keys()).map(dv => { - dv.dontDecorateSelection = false; - dv.props.whenActiveChanged(false); - }); + Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false)); manager.SelectedDocuments.clear(); Doc.UserDoc().SelectedDocs = new List([]); } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index c35263237..e313b117f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -69,7 +69,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> get Bounds(): { x: number, y: number, b: number, r: number } { return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || - documentView.dontDecorateSelection || Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) { return bounds; } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index fae520e40..558bc1a4a 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,54 +1,46 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { - faFileAlt, faStickyNote, faArrowDown, faBullseye, faFilter, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faChevronRight, faClone, faCloudUploadAlt, faCommentAlt, faCut, faEllipsisV, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, - faMusic, faObjectGroup, faPause, faMousePointer, faPenNib, faFileAudio, faPen, faEraser, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt, faHighlighter, faMicrophone, faCompressArrowsAlt, faPhone, faStamp, faClipboard, faVideo, -} from '@fortawesome/free-solid-svg-icons'; +import { faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt, faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter, faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faThumbtack, faTree, faTv, faUndoAlt, faVideo } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import "normalize.css"; import * as React from 'react'; import Measure from 'react-measure'; -import { Doc, DocListCast, Field, FieldResult, Opt } from '../../new_fields/Doc'; +import { Doc, DocListCast, Field, Opt } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; import { List } from '../../new_fields/List'; import { listSpec } from '../../new_fields/Schema'; -import { Cast, FieldValue, StrCast, BoolCast } from '../../new_fields/Types'; +import { BoolCast, Cast, FieldValue, StrCast } from '../../new_fields/Types'; +import { TraceMobx } from '../../new_fields/util'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; -import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils, emptyPath } from '../../Utils'; +import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, Utils } from '../../Utils'; import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; import { Docs, DocumentOptions } from '../documents/Documents'; +import { DocumentType } from '../documents/DocumentTypes'; import { HistoryUtil } from '../util/History'; +import RichTextMenu from '../util/RichTextMenu'; +import { Scripting } from '../util/Scripting'; +import SettingsManager from '../util/SettingsManager'; import SharingManager from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { CollectionLinearView } from './collections/CollectionLinearView'; -import { CollectionViewType, CollectionView } from './collections/CollectionView'; import { CollectionDockingView } from './collections/CollectionDockingView'; +import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu'; +import { CollectionLinearView } from './collections/CollectionLinearView'; +import { CollectionView, CollectionViewType } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; +import GestureOverlay from './GestureOverlay'; import KeyManager from './GlobalKeyHandler'; import "./MainView.scss"; import { MainViewNotifs } from './MainViewNotifs'; +import { AudioBox } from './nodes/AudioBox'; import { DocumentView } from './nodes/DocumentView'; +import { RadialMenu } from './nodes/RadialMenu'; +import { OverlayView } from './OverlayView'; import PDFMenu from './pdf/PDFMenu'; import { PreviewCursor } from './PreviewCursor'; -import { FilterBox } from './search/FilterBox'; -import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField'; -//import { DocumentManager } from '../util/DocumentManager'; -import { RecommendationsBox } from './RecommendationsBox'; -import { PresBox } from './nodes/PresBox'; -import { OverlayView } from './OverlayView'; -import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu'; -import GestureOverlay from './GestureOverlay'; -import { Scripting } from '../util/Scripting'; -import { AudioBox } from './nodes/AudioBox'; -import SettingsManager from '../util/SettingsManager'; -import { TraceMobx } from '../../new_fields/util'; -import { RadialMenu } from './nodes/RadialMenu'; -import RichTextMenu from '../util/RichTextMenu'; -import { DocumentType } from '../documents/DocumentTypes'; @observer export class MainView extends React.Component { diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx index cd9666af8..4790a2ad7 100644 --- a/src/client/views/SearchDocBox.tsx +++ b/src/client/views/SearchDocBox.tsx @@ -81,8 +81,8 @@ export class SearchDocBox extends React.Component { updateKey = async (newKey: string) => { this.query = newKey; if (newKey.length > 1) { - let newdocs = await this.getAllResults(this.query); - let things = newdocs.docs + const newdocs = await this.getAllResults(this.query); + const things = newdocs.docs; console.log(things); console.log(this.content); runInAction(() => { @@ -152,10 +152,9 @@ export class SearchDocBox extends React.Component { enter = async (e: React.KeyboardEvent) => { console.log(e.key); if (e.key === "Enter") { - let newdocs = await this.getAllResults(this.query) - let things = newdocs.docs - console.log(things); - this.content = Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); + const newdocs = await this.getAllResults(this.query); + console.log(newdocs.docs); + this.content = Docs.Create.TreeDocument(newdocs.docs, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); } } @@ -290,7 +289,7 @@ export class SearchDocBox extends React.Component { } } //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - return Docs.Create.QueryDocument(docs, { _width: 200, _height: 400, searchText: this._searchString, title: `Query Docs: "${this._searchString}"` }); + return Docs.Create.QueryDocument({ _width: 200, _height: 400, searchText: this._searchString, title: `Query Docs: "${this._searchString}"` }); } @action.bound @@ -416,7 +415,7 @@ export class SearchDocBox extends React.Component { top: 0, }} title={"Add Metadata"} - onClick={action(() => { this.editingMetadata = !this.editingMetadata })} + onClick={action(() => this.editingMetadata = !this.editingMetadata)} />
{ CollectionView={undefined} ContainingCollectionDoc={undefined} ContainingCollectionView={undefined} + rootSelected={returnFalse} onCheckedClick={this.scriptField!} onChildClick={this.scriptField!} LibraryPath={emptyPath} diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss index eae9e0220..123a27deb 100644 --- a/src/client/views/collections/CollectionLinearView.scss +++ b/src/client/views/collections/CollectionLinearView.scss @@ -8,6 +8,8 @@ display:flex; height: 100%; >label { + margin-top: "auto"; + margin-bottom: "auto"; background: $dark-color; color: $light-color; display: inline-block; diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index a6ada75b2..728b3066d 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc'; import { makeInterface } from '../../../new_fields/Schema'; -import { BoolCast, NumCast, StrCast, Cast } from '../../../new_fields/Types'; +import { BoolCast, NumCast, StrCast, Cast, ScriptCast } from '../../../new_fields/Types'; import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils, returnFalse } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { Transform } from '../../util/Transform'; @@ -13,7 +13,6 @@ import { CollectionSubView } from './CollectionSubView'; import { DocumentView } from '../nodes/DocumentView'; import { documentSchema } from '../../../new_fields/documentSchemas'; import { Id } from '../../../new_fields/FieldSymbols'; -import { ScriptField } from '../../../new_fields/ScriptField'; type LinearDocument = makeInterface<[typeof documentSchema,]>; @@ -28,12 +27,10 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { private _selectedDisposer?: IReactionDisposer; componentWillUnmount() { - this._dropDisposer && this._dropDisposer(); - this._widthDisposer && this._widthDisposer(); - this._selectedDisposer && this._selectedDisposer(); - this.childLayoutPairs.map((pair, ind) => { - Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log); - }); + this._dropDisposer?.(); + this._widthDisposer?.(); + this._selectedDisposer?.(); + this.childLayoutPairs.map((pair, ind) => ScriptCast(pair.layout.proto?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log)); } componentDidMount() { @@ -54,11 +51,11 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { selected = pair; } else { - Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log); + ScriptCast(pair.layout.proto?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log); } }); if (selected && selected.layout) { - Cast(selected.layout.proto?.onPointerDown, ScriptField)?.script.run({ this: selected.layout.proto }, console.log); + ScriptCast(selected.layout.proto?.onPointerDown)?.script.run({ this: selected.layout.proto }, console.log); } }), { fireImmediately: true } @@ -81,14 +78,16 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { render() { const guid = Utils.GenerateGuid(); const flexDir: any = StrCast(this.Document.flexDirection); + const backgroundColor = StrCast(this.props.Document.backgroundColor, "black"); + const color = StrCast(this.props.Document.color, "white"); return
- this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> -