From 9fc23e4207297cad48e04ac3ef0cb6846331ca8a Mon Sep 17 00:00:00 2001 From: madelinegr Date: Tue, 4 Jun 2019 11:56:02 -0400 Subject: changed search item --- src/client/views/SearchItem.tsx | 127 ++++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 25 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 01c7316d6..cf440535d 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -6,8 +6,12 @@ import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } fr import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Cast } from "../../new_fields/Types"; import { FieldView, FieldViewProps } from './nodes/FieldView'; -import { computed } from "mobx"; +import { computed, observable } from "mobx"; import { IconField } from "../../new_fields/IconField"; +import { listSpec } from "../../new_fields/Schema"; +import { Transform } from "../util/Transform"; +import { ObjectField } from "../../new_fields/ObjectField"; +import { RichTextField } from "../../new_fields/RichTextField"; import { SetupDrag } from "../util/DragManager"; @@ -15,38 +19,63 @@ export interface SearchProps { doc: Doc; } +export interface SearchItemProps { + doc: Doc; + subitems: FieldViewProps; +} + library.add(faCaretUp); library.add(faObjectGroup); library.add(faStickyNote); library.add(faFilePdf); library.add(faFilm); -export class SearchItem extends React.Component { +export class SearchItem extends React.Component { + + @observable _selected: boolean = false; onClick = () => { DocumentManager.Instance.jumpToDocument(this.props.doc); } - //needs help - // @computed get layout(): string { const field = Cast(this.props.doc[fieldKey], IconField); return field ? field.icon : "

Error loading icon data

"; } + containingCollection(): string { + let docView = DocumentManager.Instance.getDocumentView(this.props.doc); + if (docView) { + let containerView = docView.props.ContainingCollectionView; + if (containerView) { + let container = containerView.props.Document; + const field = Cast(container.title, RichTextField); + return field ? field.Data : "

Error loading icon data

"; + } + } + return "None"; + } + containingCollectionView() { + let docView = DocumentManager.Instance.getDocumentView(this.props.doc); + if (docView) { + let containerView = docView.props.ContainingCollectionView; + if (containerView) { + return containerView.props.Document; + } + } - public static DocumentIcon(layout: string) { - let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf : - layout.indexOf("ImageBox") !== -1 ? faImage : - layout.indexOf("Formatted") !== -1 ? faStickyNote : - layout.indexOf("Video") !== -1 ? faFilm : - layout.indexOf("Collection") !== -1 ? faObjectGroup : - faCaretUp; - return ; - } - onPointerEnter = (e: React.PointerEvent) => { - this.props.doc.libraryBrush = true; - Doc.SetOnPrototype(this.props.doc, "protoBrush", true); + return this.props.doc; } - onPointerLeave = (e: React.PointerEvent) => { - this.props.doc.libraryBrush = false; - Doc.SetOnPrototype(this.props.doc, "protoBrush", false); + + public DocumentIcon() { + let layoutresult = Cast(this.props.doc.layout, "string", ""); + + //TODO: images showing up as collections because the layout is collectionview + console.log(layoutresult) + + let button = layoutresult.indexOf("PDFBox") !== -1 ? faFilePdf : + layoutresult.indexOf("ImageBox") !== -1 ? faImage : + layoutresult.indexOf("Formatted") !== -1 ? faStickyNote : + layoutresult.indexOf("Video") !== -1 ? faFilm : + layoutresult.indexOf("Collection") !== -1 ? faObjectGroup : + faCaretUp; + return ; } collectionRef = React.createRef(); @@ -59,14 +88,62 @@ export class SearchItem extends React.Component { return Doc.MakeAlias(doc); } } + + select = () => { + // console.log('moused'); + // console.log("before:", this.props.doc[Id], this._selected) + this._selected = !this._selected; + // console.log("after:", this.props.doc[Id], this._selected) + } + + linkCount = () => { + let linkToSize = Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length; + let linkFromSize = Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; + let linkCount = linkToSize + linkFromSize; + console.log(linkCount) + return linkCount; + } + + //taken from collectionschemaview, counld show doc preview to the left of the results. not sure if this should go in here + // get previewDocument(): Doc | undefined { + // const children = Cast(this.props.doc[this.props.subitems.fieldKey], listSpec(Doc), []); + // const selected = children.length > this._selectedIndex ? FieldValue(children[this._selectedIndex]) : undefined; + // return selected ? (this.previewScript ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; + // } + + // get previewRegionHeight() { return 200; } + // get previewRegionWidth() { return 300; } + // private previewDocNativeWidth = () => Cast(this.previewDocument!.nativeWidth, "number", this.previewRegionWidth); + // private previewDocNativeHeight = () => Cast(this.previewDocument!.nativeHeight, "number", this.previewRegionHeight); + // private previewContentScaling = () => { + // let wscale = this.previewRegionWidth / (this.previewDocNativeWidth() ? this.previewDocNativeWidth() : this.previewRegionWidth); + // if (wscale * this.previewDocNativeHeight() > this.previewRegionHeight) { + // return this.previewRegionHeight / (this.previewDocNativeHeight() ? this.previewDocNativeHeight() : this.previewRegionHeight); + // } + // return wscale; + // } + // private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); + // private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); + // get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } + // getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( + // - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, + // - this.borderWidth).scale(1 / this.previewContentScaling()) + + render() { return ( -
-
title: {this.props.doc.title}
- {/*
Type: {this.props.doc.layout}
*/} - {/*
{SearchItem.DocumentIcon(this.layout)}
*/} +
+
+
title: {this.props.doc.title}
+
+
{this.linkCount()}
+
{this.DocumentIcon()}
+
+
+
+
Collection: {this.containingCollection()}
+
+
); } -- cgit v1.2.3-70-g09d2 From 4fd53320c87313c9add8f551154f8df3e2522b5f Mon Sep 17 00:00:00 2001 From: madelinegr Date: Tue, 4 Jun 2019 18:15:54 -0400 Subject: end of day 6/4 --- src/client/documents/Documents.ts | 23 ++--- src/client/util/SearchUtil.ts | 4 + src/client/views/SearchBox.scss | 70 ++++++++++++- src/client/views/SearchBox.tsx | 24 ++++- src/client/views/SearchItem.tsx | 109 +++++++++++---------- src/client/views/ViewItem.tsx | 18 ++++ .../CollectionFreeFormLinksView.scss | 2 +- .../CollectionFreeFormLinksView.tsx | 2 +- 8 files changed, 182 insertions(+), 70 deletions(-) create mode 100644 src/client/views/ViewItem.tsx (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ab61b915c..2da4c8d88 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -41,6 +41,7 @@ var path = require('path'); export interface DocumentOptions { x?: number; y?: number; + type?: string; ink?: InkField; width?: number; height?: number; @@ -73,7 +74,7 @@ export namespace DocUtils { let protoSrc = source.proto ? source.proto : source; let protoTarg = target.proto ? target.proto : target; UndoManager.RunInBatch(() => { - let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 }); + let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1, type: "link" }); //let linkDoc = new Doc; linkDoc.proto!.title = "-link name-"; linkDoc.proto!.linkDescription = ""; @@ -154,54 +155,54 @@ export namespace Docs { function CreateImagePrototype(): Doc { let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0 }); + { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0, type: "image" }); return imageProto; } function CreateHistogramPrototype(): Doc { let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("annotations"), - { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString() }); + { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString(), type: "histogram" }); return histoProto; } function CreateIconPrototype(): Doc { let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(), - { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE) }); + { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), type: "icon" }); return iconProto; } function CreateTextPrototype(): Doc { let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb" }); + { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb", type: "text" }); return textProto; } function CreatePdfPrototype(): Doc { let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 }); + { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1, type: "pdf" }); return pdfProto; } function CreateWebPrototype(): Doc { let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 300 }); + { x: 0, y: 0, width: 300, height: 300, type: "web" }); return webProto; } function CreateCollectionPrototype(): Doc { let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("data"), - { panX: 0, panY: 0, scale: 1, width: 500, height: 500 }); + { panX: 0, panY: 0, scale: 1, width: 500, height: 500, type: "collection" }); return collProto; } function CreateKVPPrototype(): Doc { let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150 }); + { x: 0, y: 0, width: 300, height: 150, type: "kvp" }); return kvpProto; } function CreateVideoPrototype(): Doc { let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0 }); + { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0, type: "video" }); return videoProto; } function CreateAudioPrototype(): Doc { let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150 }); + { x: 0, y: 0, width: 300, height: 150, type: "audio" }); return audioProto; } diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 28ec8ca14..27d27a3b8 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -23,4 +23,8 @@ export namespace SearchUtil { return Search(`proto_i:"${protoId}"`, true); // return Search(`{!join from=id to=proto_i}id:${protoId}`, true); } + + export async function GetViewsOfDocument(doc: Doc): Promise { + return Search(`proto_i:"${doc[Id]}"`, true); + } } \ No newline at end of file diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index b38e6091d..22b198739 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -48,7 +48,6 @@ .filter-form { background: $dark-color; height: 400px; - width: 400px; position: relative; right: 1px; color: $light-color; @@ -71,15 +70,14 @@ top: 300px; display: flex; flex-direction: column; + margin-right: 72px; .search-item { + pointer-events: auto; width: 500px; - height: 50px; background: $light-color-secondary; - display: flex; justify-content: space-between; align-items: center; - transition: all 0.1s; border-width: 0.11px; border-style: none; border-color: $intermediate-color; @@ -89,6 +87,18 @@ font-size: 13px; } + .search-info { + display: flex; + justify-content: flex-end; + width: 100%; + } + + .main-search-info { + display: flex; + flex-direction: row; + width: 100%; + } + .search-item:hover { transition: all 0.1s; background: $lighter-alt-accent; @@ -98,5 +108,57 @@ text-transform: uppercase; text-align: left; width: 8vw; + font-weight: bold; + } + + .more-search-info { + text-align: left; + } + + .link-count { + height: 25px; + width: 25px; + border-radius: 50%; + background: $dark-color; + color: $light-color-secondary; + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; + } + + .search-type { + width: 25PX; + height: 25PX; + display: flex; + justify-content: center; + align-items: center; + } + + + .searchBox-instances { + display: inline-block; + background: $dark-color; + width: 100px; + opacity: 1; + // width: 0px; this is real + // visibility: hidden; + // opacity: 0; THIS IS REAL + // transition: all 0.2s ease; + color: $light-color; + } + + .search-overview { + display: flex; + // float: left; + justify-content: flex-end; + } + + .search-overview:hover { + .searchBox-instances { + // visibility: visible; + opacity: 1; + width: 100px; + } } } \ No newline at end of file diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 63d2065e2..51fcb4596 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -22,6 +22,7 @@ import { SetupDrag } from '../util/DragManager'; import { Docs } from '../documents/Documents'; import { RouteStore } from '../../server/RouteStore'; import { NumCast } from '../../new_fields/Types'; +import { SearchUtil } from '../util/SearchUtil'; library.add(faSearch); library.add(faObjectGroup); @@ -169,6 +170,18 @@ export class SearchBox extends React.Component { return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this.searchString}"` }); } + @action + getViews = async (doc: Doc) => { + console.log("getting view") + const results = await SearchUtil.GetViewsOfDocument(doc); + let toReturn: Doc[] = []; + await runInAction(() => { + toReturn = results; + }); + return toReturn; + } + + // Useful queries: // Delegates of a document: {!join from=id to=proto_i}id:{protoId} // Documents in a collection: {!join from=data_l to=id}id:{collectionProtoId} @@ -183,12 +196,19 @@ export class SearchBox extends React.Component { - {/* */} + {/* */}
{this._resultsOpen ? (
- {this._results.map(result => )} + {this._results.map(result => { + this.getViews(result).then((res: Doc[]) => { + console.log("found") + return + }) + })} + {/* {this._results.map(result => )} */} + {/*views = {this.getViews(result)}*/}
) : null} diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index cf440535d..e82aa0719 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -2,26 +2,31 @@ import React = require("react"); import { Doc } from "../../new_fields/Doc"; import { DocumentManager } from "../util/DocumentManager"; import { library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Cast } from "../../new_fields/Types"; import { FieldView, FieldViewProps } from './nodes/FieldView'; -import { computed, observable } from "mobx"; +import { computed, observable, action, runInAction } from "mobx"; import { IconField } from "../../new_fields/IconField"; import { listSpec } from "../../new_fields/Schema"; import { Transform } from "../util/Transform"; import { ObjectField } from "../../new_fields/ObjectField"; import { RichTextField } from "../../new_fields/RichTextField"; import { SetupDrag } from "../util/DragManager"; +import { SearchUtil } from "../util/SearchUtil"; +import { Id } from "../../new_fields/FieldSymbols"; +import { ViewItem } from "./ViewItem"; export interface SearchProps { doc: Doc; + views: Doc[]; } export interface SearchItemProps { doc: Doc; - subitems: FieldViewProps; + views: Doc[]; + // subitems: FieldViewProps; } library.add(faCaretUp); @@ -29,15 +34,31 @@ library.add(faObjectGroup); library.add(faStickyNote); library.add(faFilePdf); library.add(faFilm); +library.add(faMusic); +library.add(faLink); +library.add(faChartBar); +library.add(faGlobeAsia); export class SearchItem extends React.Component { @observable _selected: boolean = false; + @observable + private _instances: Doc[] = []; + + // @action + // getViews = async () => { + // const results = await SearchUtil.GetViewsOfDocument(this.props.doc); + // runInAction(() => { + // this._instances = results; + // }); + // } + onClick = () => { DocumentManager.Instance.jumpToDocument(this.props.doc); } + //something wrong with this containingCollection(): string { let docView = DocumentManager.Instance.getDocumentView(this.props.doc); if (docView) { @@ -51,6 +72,7 @@ export class SearchItem extends React.Component { return "None"; } + //also probably with this rip containingCollectionView() { let docView = DocumentManager.Instance.getDocumentView(this.props.doc); if (docView) { @@ -64,17 +86,18 @@ export class SearchItem extends React.Component { } public DocumentIcon() { - let layoutresult = Cast(this.props.doc.layout, "string", ""); - - //TODO: images showing up as collections because the layout is collectionview - console.log(layoutresult) - - let button = layoutresult.indexOf("PDFBox") !== -1 ? faFilePdf : - layoutresult.indexOf("ImageBox") !== -1 ? faImage : - layoutresult.indexOf("Formatted") !== -1 ? faStickyNote : - layoutresult.indexOf("Video") !== -1 ? faFilm : - layoutresult.indexOf("Collection") !== -1 ? faObjectGroup : - faCaretUp; + let layoutresult = Cast(this.props.doc.type, "string", ""); + + let button = layoutresult.indexOf("pdf") !== -1 ? faFilePdf : + layoutresult.indexOf("image") !== -1 ? faImage : + layoutresult.indexOf("text") !== -1 ? faStickyNote : + layoutresult.indexOf("video") !== -1 ? faFilm : + layoutresult.indexOf("collection") !== -1 ? faObjectGroup : + layoutresult.indexOf("audio") !== -1 ? faMusic : + layoutresult.indexOf("link") !== -1 ? faLink : + layoutresult.indexOf("histogram") !== -1 ? faChartBar : + layoutresult.indexOf("web") !== -1 ? faGlobeAsia : + faCaretUp; return ; } @@ -91,59 +114,43 @@ export class SearchItem extends React.Component { select = () => { // console.log('moused'); - // console.log("before:", this.props.doc[Id], this._selected) + // console.log("before:", this.props.doc, this._selected) this._selected = !this._selected; - // console.log("after:", this.props.doc[Id], this._selected) + // console.log("after:", this.props.doc, this._selected) } linkCount = () => { + console.log("counting") let linkToSize = Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length; let linkFromSize = Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; let linkCount = linkToSize + linkFromSize; - console.log(linkCount) return linkCount; } - //taken from collectionschemaview, counld show doc preview to the left of the results. not sure if this should go in here - // get previewDocument(): Doc | undefined { - // const children = Cast(this.props.doc[this.props.subitems.fieldKey], listSpec(Doc), []); - // const selected = children.length > this._selectedIndex ? FieldValue(children[this._selectedIndex]) : undefined; - // return selected ? (this.previewScript ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; - // } - - // get previewRegionHeight() { return 200; } - // get previewRegionWidth() { return 300; } - // private previewDocNativeWidth = () => Cast(this.previewDocument!.nativeWidth, "number", this.previewRegionWidth); - // private previewDocNativeHeight = () => Cast(this.previewDocument!.nativeHeight, "number", this.previewRegionHeight); - // private previewContentScaling = () => { - // let wscale = this.previewRegionWidth / (this.previewDocNativeWidth() ? this.previewDocNativeWidth() : this.previewRegionWidth); - // if (wscale * this.previewDocNativeHeight() > this.previewRegionHeight) { - // return this.previewRegionHeight / (this.previewDocNativeHeight() ? this.previewDocNativeHeight() : this.previewRegionHeight); - // } - // return wscale; - // } - // private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); - // private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); - // get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } - // getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( - // - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, - // - this.borderWidth).scale(1 / this.previewContentScaling()) - - render() { return ( -
-
-
title: {this.props.doc.title}
-
-
{this.linkCount()}
-
{this.DocumentIcon()}
+
+
+ {this.props.views.map(result => )} +
+
+
+
{this.props.doc.title}
+
+
{this.linkCount()}
+
{this.DocumentIcon()}
+
+
+
+
Where Found: (i.e. title, body, etc)
+ {/*
Collection: {this.containingCollection()}
*/}
-
+ + {/*
Collection: {this.containingCollection()}
-
+
*/}
); } diff --git a/src/client/views/ViewItem.tsx b/src/client/views/ViewItem.tsx new file mode 100644 index 000000000..85f436b44 --- /dev/null +++ b/src/client/views/ViewItem.tsx @@ -0,0 +1,18 @@ +import { Doc } from "../../new_fields/Doc"; +import React = require("react"); +import "./SearchBox.scss"; + +export interface ViewitemProps { + doc: Doc; + // subitems: FieldViewProps; +} + +export class ViewItem extends React.Component { + + render() { + return ( +
{this.props.doc.title}
+ + ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss index 30e158603..a80e09fa8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss @@ -1,4 +1,4 @@ -.collectionfreeformlinksview-svgCanvas{ +p.collectionfreeformlinksview-svgCanvas{ transform: translate(-10000px,-10000px); position: absolute; top: 0; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index a43c5f241..2df66ce54 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -110,7 +110,7 @@ export class CollectionFreeFormLinksView extends React.Component Date: Wed, 5 Jun 2019 08:09:10 -0400 Subject: fixed full screen text bug. cleaned up imports --- src/client/views/DocumentDecorations.tsx | 33 +++++++++++----------- src/client/views/InkingControl.tsx | 1 - src/client/views/PresentationView.tsx | 16 +++++------ src/client/views/SearchItem.tsx | 8 ++---- src/client/views/TemplateMenu.tsx | 11 ++++---- .../views/collections/CollectionBaseView.tsx | 12 ++++---- .../views/collections/CollectionDockingView.tsx | 15 +++++----- .../views/collections/CollectionSchemaView.tsx | 1 - src/client/views/collections/CollectionSubView.tsx | 31 ++++++++++---------- .../views/collections/CollectionTreeView.tsx | 26 ++++++++--------- .../CollectionFreeFormLinkView.tsx | 7 ++--- .../CollectionFreeFormLinksView.tsx | 14 ++++----- .../CollectionFreeFormRemoteCursors.tsx | 12 ++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 20 ++++++------- .../collections/collectionFreeForm/MarqueeView.tsx | 26 ++++++++--------- src/client/views/nodes/FieldView.tsx | 29 +++++++++---------- src/client/views/nodes/FormattedTextBox.tsx | 6 ++-- src/client/views/nodes/ImageBox.tsx | 24 ++++++++-------- src/client/views/nodes/VideoBox.tsx | 16 +++++------ src/client/views/nodes/WebBox.tsx | 9 +++--- 20 files changed, 147 insertions(+), 170 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index da9b1253e..37895516a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,33 +1,32 @@ -import { action, computed, observable, runInAction, untracked, reaction } from "mobx"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faLink } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../new_fields/Doc"; +import { List } from "../../new_fields/List"; +import { listSpec } from "../../new_fields/Schema"; +import { Cast, NumCast, StrCast } from "../../new_fields/Types"; import { emptyFunction, Utils } from "../../Utils"; +import { Docs } from "../documents/Documents"; +import { DocumentManager } from "../util/DocumentManager"; import { DragLinksAsDocuments, DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; +import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; +import { CollectionView } from "./collections/CollectionView"; import './DocumentDecorations.scss'; import { DocumentView, PositionDocument } from "./nodes/DocumentView"; +import { FieldView } from "./nodes/FieldView"; +import { FormattedTextBox } from "./nodes/FormattedTextBox"; +import { IconBox } from "./nodes/IconBox"; import { LinkMenu } from "./nodes/LinkMenu"; import { TemplateMenu } from "./TemplateMenu"; -import React = require("react"); import { Template, Templates } from "./Templates"; -import { CompileScript } from "../util/Scripting"; -import { IconBox } from "./nodes/IconBox"; -import { Cast, FieldValue, NumCast, StrCast } from "../../new_fields/Types"; -import { Doc, FieldResult } from "../../new_fields/Doc"; -import { listSpec } from "../../new_fields/Schema"; -import { Docs } from "../documents/Documents"; -import { List } from "../../new_fields/List"; +import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; -import { faLink } from '@fortawesome/free-solid-svg-icons'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; -import { CollectionView } from "./collections/CollectionView"; -import { DocumentManager } from "../util/DocumentManager"; -import { FormattedTextBox } from "./nodes/FormattedTextBox"; -import { FieldView } from "./nodes/FieldView"; library.add(faLink); diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index d456f531f..d1a6eb7fd 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -1,5 +1,4 @@ import { observable, action, computed } from "mobx"; - import { CirclePicker, ColorResult } from 'react-color'; import React = require("react"); import { observer } from "mobx-react"; diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx index 9d5798ff1..b0c93ee26 100644 --- a/src/client/views/PresentationView.tsx +++ b/src/client/views/PresentationView.tsx @@ -1,15 +1,13 @@ +import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import React = require("react"); -import { observable, action, runInAction, reaction } from "mobx"; -import "./PresentationView.scss"; -import { DocumentManager } from "../util/DocumentManager"; -import { Utils } from "../../Utils"; -import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc"; -import { listSpec } from "../../new_fields/Schema"; -import { Cast, NumCast, FieldValue, PromiseValue, StrCast, BoolCast } from "../../new_fields/Types"; +import { Doc, DocListCast } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; import { List } from "../../new_fields/List"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { listSpec } from "../../new_fields/Schema"; +import { BoolCast, Cast, FieldValue, NumCast, StrCast } from "../../new_fields/Types"; +import { DocumentManager } from "../util/DocumentManager"; +import "./PresentationView.scss"; +import React = require("react"); export interface PresViewProps { Document: Doc; diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 01c7316d6..6901f60da 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -1,13 +1,9 @@ import React = require("react"); -import { Doc } from "../../new_fields/Doc"; -import { DocumentManager } from "../util/DocumentManager"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast } from "../../new_fields/Types"; -import { FieldView, FieldViewProps } from './nodes/FieldView'; -import { computed } from "mobx"; -import { IconField } from "../../new_fields/IconField"; +import { Doc } from "../../new_fields/Doc"; +import { DocumentManager } from "../util/DocumentManager"; import { SetupDrag } from "../util/DragManager"; diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index e5b679e24..3288abd90 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,12 +1,11 @@ -import { observable, computed, action, trace } from "mobx"; -import React = require("react"); +import { action, observable } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../new_fields/Doc"; +import { List } from "../../new_fields/List"; import './DocumentDecorations.scss'; -import { Template } from "./Templates"; import { DocumentView } from "./nodes/DocumentView"; -import { List } from "../../new_fields/List"; -import { Doc } from "../../new_fields/Doc"; -import { NumCast } from "../../new_fields/Types"; +import { Template } from "./Templates"; +import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 734669893..9350dc974 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -1,14 +1,14 @@ import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ContextMenu } from '../ContextMenu'; -import { FieldViewProps } from '../nodes/FieldView'; -import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Types'; -import { Doc, FieldResult, Opt, DocListCast } from '../../../new_fields/Doc'; -import { listSpec } from '../../../new_fields/Schema'; +import { Doc, DocListCast, 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, NumCast, PromiseValue } from '../../../new_fields/Types'; import { SelectionManager } from '../../util/SelectionManager'; -import { Id } from '../../../new_fields/FieldSymbols'; +import { ContextMenu } from '../ContextMenu'; +import { FieldViewProps } from '../nodes/FieldView'; export enum CollectionViewType { Invalid, diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index dcc1bd95d..8f6c9b1fc 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,28 +1,28 @@ import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, observable, reaction, Lambda } from "mobx"; +import { action, Lambda, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; -import { Doc, Field, Opt, DocListCast } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc"; +import { Id } from '../../../new_fields/FieldSymbols'; import { FieldId } from "../../../new_fields/RefField"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { emptyFunction, returnTrue, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; +import { DocumentManager } from '../../util/DocumentManager'; import { DragLinksAsDocuments, DragManager } from "../../util/DragManager"; +import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DocumentView } from "../nodes/DocumentView"; +import { CollectionViewType } from './CollectionBaseView'; import "./CollectionDockingView.scss"; import { SubCollectionViewProps } from "./CollectionSubView"; -import React = require("react"); import { ParentDocSelector } from './ParentDocumentSelector'; -import { DocumentManager } from '../../util/DocumentManager'; -import { CollectionViewType } from './CollectionBaseView'; -import { Id } from '../../../new_fields/FieldSymbols'; -import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; +import React = require("react"); @observer export class CollectionDockingView extends React.Component { @@ -357,6 +357,7 @@ export class CollectionDockingView extends React.Component; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index be37efd3d..31e662da5 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,23 +1,22 @@ -import { action, runInAction } from "mobx"; -import React = require("react"); -import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { DragManager } from "../../util/DragManager"; -import { Docs, DocumentOptions } from "../../documents/Documents"; -import { RouteStore } from "../../../server/RouteStore"; +import { action } from "mobx"; +import * as rp from 'request-promise'; +import CursorField from "../../../new_fields/CursorField"; +import { Doc, DocListCast, Opt } from "../../../new_fields/Doc"; +import { List } from "../../../new_fields/List"; +import { listSpec } from "../../../new_fields/Schema"; +import { Cast, PromiseValue } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; +import { RouteStore } from "../../../server/RouteStore"; +import { DocServer } from "../../DocServer"; +import { Docs, DocumentOptions } from "../../documents/Documents"; +import { DragManager } from "../../util/DragManager"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { DocComponent } from "../DocComponent"; import { FieldViewProps } from "../nodes/FieldView"; -import * as rp from 'request-promise'; -import { CollectionView } from "./CollectionView"; import { CollectionPDFView } from "./CollectionPDFView"; import { CollectionVideoView } from "./CollectionVideoView"; -import { Doc, Opt, FieldResult, DocListCast } from "../../../new_fields/Doc"; -import { DocComponent } from "../DocComponent"; -import { listSpec } from "../../../new_fields/Schema"; -import { Cast, PromiseValue, FieldValue, ListSpec } from "../../../new_fields/Types"; -import { List } from "../../../new_fields/List"; -import { DocServer } from "../../DocServer"; -import CursorField from "../../../new_fields/CursorField"; -import { DocumentManager } from "../../util/DocumentManager"; +import { CollectionView } from "./CollectionView"; +import React = require("react"); export interface CollectionViewProps extends FieldViewProps { addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 48da52ffa..9fb1da716 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,25 +1,24 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretDown, faCaretRight, faTrashAlt, faAngleRight } from '@fortawesome/free-solid-svg-icons'; +import { faAngleRight, faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable, trace } from "mobx"; import { observer } from "mobx-react"; -import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager"; -import { EditableView } from "../EditableView"; -import { CollectionSubView } from "./CollectionSubView"; -import "./CollectionTreeView.scss"; -import React = require("react"); -import { Document, listSpec } from '../../../new_fields/Schema'; -import { Cast, StrCast, BoolCast, FieldValue, NumCast } from '../../../new_fields/Types'; import { Doc, DocListCast } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; -import { ContextMenu } from '../ContextMenu'; -import { undoBatch } from '../../util/UndoManager'; -import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; -import { CollectionDockingView } from './CollectionDockingView'; -import { DocumentManager } from '../../util/DocumentManager'; +import { Document, listSpec } from '../../../new_fields/Schema'; +import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types'; import { Docs } from '../../documents/Documents'; +import { DocumentManager } from '../../util/DocumentManager'; +import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; +import { undoBatch } from '../../util/UndoManager'; +import { ContextMenu } from '../ContextMenu'; +import { EditableView } from "../EditableView"; import { MainView } from '../MainView'; import { CollectionViewType } from './CollectionBaseView'; +import { CollectionDockingView } from './CollectionDockingView'; +import { CollectionSubView } from "./CollectionSubView"; +import "./CollectionTreeView.scss"; +import React = require("react"); export interface TreeViewProps { @@ -220,6 +219,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { } } render() { + trace(); let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType; if (!this.childDocs) { return (null); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 301b769af..ca7c99f28 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,11 +1,10 @@ import { observer } from "mobx-react"; -import { Utils } from "../../../../Utils"; +import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc"; +import { BoolCast, NumCast, StrCast } from "../../../../new_fields/Types"; +import { InkingControl } from "../../InkingControl"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); import v5 = require("uuid/v5"); -import { StrCast, NumCast, BoolCast } from "../../../../new_fields/Types"; -import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc"; -import { InkingControl } from "../../InkingControl"; export interface CollectionFreeFormLinkViewProps { A: Doc; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index a43c5f241..c4dd534ed 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,17 +1,16 @@ -import { computed, IReactionDisposer, reaction, trace } from "mobx"; +import { computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Utils } from "../../../../Utils"; +import { Doc, DocListCast } 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, NumCast, StrCast } from "../../../../new_fields/Types"; import { DocumentManager } from "../../../util/DocumentManager"; import { DocumentView } from "../../nodes/DocumentView"; import { CollectionViewProps } from "../CollectionSubView"; import "./CollectionFreeFormLinksView.scss"; import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView"; import React = require("react"); -import { Doc, DocListCastAsync, DocListCast } from "../../../../new_fields/Doc"; -import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types"; -import { listSpec } from "../../../../new_fields/Schema"; -import { List } from "../../../../new_fields/List"; -import { Id } from "../../../../new_fields/FieldSymbols"; @observer export class CollectionFreeFormLinksView extends React.Component { @@ -110,7 +109,6 @@ export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9d19df540..2b43c76c6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,8 +1,15 @@ -import { action, computed, trace } from "mobx"; +import { action, computed } from "mobx"; import { observer } from "mobx-react"; -import { emptyFunction, returnFalse, returnOne } from "../../../../Utils"; +import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc"; +import { Id } from "../../../../new_fields/FieldSymbols"; +import { InkField, StrokeData } from "../../../../new_fields/InkField"; +import { createSchema, makeInterface } from "../../../../new_fields/Schema"; +import { BoolCast, Cast, FieldValue, NumCast } from "../../../../new_fields/Types"; +import { emptyFunction, returnOne } from "../../../../Utils"; +import { DocServer } from "../../../DocServer"; import { DocumentManager } from "../../../util/DocumentManager"; import { DragManager } from "../../../util/DragManager"; +import { HistoryUtil } from "../../../util/History"; import { SelectionManager } from "../../../util/SelectionManager"; import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; @@ -11,6 +18,7 @@ import { InkingCanvas } from "../../InkingCanvas"; import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentContentsView } from "../../nodes/DocumentContentsView"; import { DocumentViewProps, positionSchema } from "../../nodes/DocumentView"; +import { pageSchema } from "../../nodes/ImageBox"; import { CollectionSubView } from "../CollectionSubView"; import { CollectionFreeFormLinksView } from "./CollectionFreeFormLinksView"; import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors"; @@ -18,14 +26,6 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); -import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema"; -import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc"; -import { FieldValue, Cast, NumCast, BoolCast } from "../../../../new_fields/Types"; -import { pageSchema } from "../../nodes/ImageBox"; -import { InkField, StrokeData } from "../../../../new_fields/InkField"; -import { HistoryUtil } from "../../../util/History"; -import { Id } from "../../../../new_fields/FieldSymbols"; -import { DocServer } from "../../../DocServer"; export const panZoomSchema = createSchema({ panX: "number", diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 29734fa19..9ec941eff 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -1,27 +1,25 @@ import * as htmlToImage from "html-to-image"; -import { action, computed, observable, trace } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../../../new_fields/Doc"; +import { Id } from "../../../../new_fields/FieldSymbols"; +import { InkField, StrokeData } from "../../../../new_fields/InkField"; +import { List } from "../../../../new_fields/List"; +import { Cast, NumCast } from "../../../../new_fields/Types"; +import { Utils } from "../../../../Utils"; +import { DocServer } from "../../../DocServer"; import { Docs } from "../../../documents/Documents"; import { SelectionManager } from "../../../util/SelectionManager"; import { Transform } from "../../../util/Transform"; -import { undoBatch, UndoManager } from "../../../util/UndoManager"; +import { undoBatch } from "../../../util/UndoManager"; import { InkingCanvas } from "../../InkingCanvas"; import { PreviewCursor } from "../../PreviewCursor"; +import { SearchBox } from "../../SearchBox"; +import { Templates } from "../../Templates"; +import { CollectionViewType } from "../CollectionBaseView"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); -import { Utils } from "../../../../Utils"; -import { Doc } from "../../../../new_fields/Doc"; -import { NumCast, Cast } from "../../../../new_fields/Types"; -import { InkField, StrokeData } from "../../../../new_fields/InkField"; -import { List } from "../../../../new_fields/List"; -import { ImageField } from "../../../../new_fields/URLField"; -import { Template, Templates } from "../../Templates"; -import { SearchBox } from "../../SearchBox"; -import { DocServer } from "../../../DocServer"; -import { Id } from "../../../../new_fields/FieldSymbols"; -import { CollectionView } from "../CollectionView"; -import { CollectionViewType } from "../CollectionBaseView"; interface MarqueeViewProps { getContainerTransform: () => Transform; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 7b642b299..5a83de8e3 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,24 +1,23 @@ import React = require("react"); +import { computed } from "mobx"; import { observer } from "mobx-react"; -import { computed, observable } from "mobx"; -import { FormattedTextBox } from "./FormattedTextBox"; -import { ImageBox } from "./ImageBox"; -import { VideoBox } from "./VideoBox"; -import { AudioBox } from "./AudioBox"; -import { DocumentContentsView } from "./DocumentContentsView"; +import { DateField } from "../../../new_fields/DateField"; +import { Doc, FieldResult, Opt } from "../../../new_fields/Doc"; +import { IconField } from "../../../new_fields/IconField"; +import { List } from "../../../new_fields/List"; +import { RichTextField } from "../../../new_fields/RichTextField"; +import { AudioField, ImageField, VideoField } from "../../../new_fields/URLField"; +import { emptyFunction, returnFalse, returnOne } from "../../../Utils"; import { Transform } from "../../util/Transform"; -import { returnFalse, emptyFunction, returnOne } from "../../../Utils"; -import { CollectionView } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; +import { CollectionView } from "../collections/CollectionView"; +import { AudioBox } from "./AudioBox"; +import { DocumentContentsView } from "./DocumentContentsView"; +import { FormattedTextBox } from "./FormattedTextBox"; import { IconBox } from "./IconBox"; -import { Opt, Doc, FieldResult } from "../../../new_fields/Doc"; -import { List } from "../../../new_fields/List"; -import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField"; -import { IconField } from "../../../new_fields/IconField"; -import { RichTextField } from "../../../new_fields/RichTextField"; -import { DateField } from "../../../new_fields/DateField"; -import { NumCast } from "../../../new_fields/Types"; +import { ImageBox } from "./ImageBox"; +import { VideoBox } from "./VideoBox"; // diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5c635cc0c..53ab7c35e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -7,11 +7,12 @@ import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { EditorState, Plugin, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; -import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc"; +import { Doc, Opt } from "../../../new_fields/Doc"; import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; +import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; @@ -21,14 +22,11 @@ import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { ContextMenu } from "../../views/ContextMenu"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); -import { DocUtils } from '../../documents/Documents'; library.add(faEdit); library.add(faSmile); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4c2b73b70..06ecc794b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,25 +1,25 @@ -import { action, observable, trace } from 'mobx'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faImage } from '@fortawesome/free-solid-svg-icons'; +import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app +import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc'; +import { List } from '../../../new_fields/List'; +import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema'; +import { Cast, FieldValue, NumCast, StrCast } from '../../../new_fields/Types'; +import { ImageField } from '../../../new_fields/URLField'; import { Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from "../../views/ContextMenu"; +import { ContextMenuProps } from '../ContextMenuItem'; +import { DocComponent } from '../DocComponent'; +import { InkingControl } from '../InkingControl'; +import { positionSchema } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); -import { createSchema, makeInterface, listSpec } from '../../../new_fields/Schema'; -import { DocComponent } from '../DocComponent'; -import { positionSchema } from './DocumentView'; -import { FieldValue, Cast, StrCast, PromiseValue, NumCast } from '../../../new_fields/Types'; -import { ImageField } from '../../../new_fields/URLField'; -import { List } from '../../../new_fields/List'; -import { InkingControl } from '../InkingControl'; -import { Doc, WidthSym, HeightSym } from '../../../new_fields/Doc'; -import { faImage } from '@fortawesome/free-solid-svg-icons'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { ContextMenuItemProps, ContextMenuProps } from '../ContextMenuItem'; var path = require('path'); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 35ecf12f6..1239b498f 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,19 +1,17 @@ import React = require("react"); +import { action, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { FieldView, FieldViewProps } from './FieldView'; import * as rp from "request-promise"; -import "./VideoBox.scss"; -import { action, IReactionDisposer, reaction, observable } from "mobx"; -import { DocComponent } from "../DocComponent"; -import { positionSchema } from "./DocumentView"; import { makeInterface } from "../../../new_fields/Schema"; -import { pageSchema } from "./ImageBox"; -import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; +import { Cast, FieldValue } from "../../../new_fields/Types"; import { VideoField } from "../../../new_fields/URLField"; -import "./VideoBox.scss"; import { RouteStore } from "../../../server/RouteStore"; import { DocServer } from "../../DocServer"; -import { actionFieldDecorator } from "mobx/lib/internal"; +import { DocComponent } from "../DocComponent"; +import { positionSchema } from "./DocumentView"; +import { FieldView, FieldViewProps } from './FieldView'; +import { pageSchema } from "./ImageBox"; +import "./VideoBox.scss"; type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; const VideoDocument = makeInterface(positionSchema, pageSchema); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2239a8e38..98c57fc75 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,12 +1,11 @@ -import "./WebBox.scss"; -import React = require("react"); -import { FieldViewProps, FieldView } from './FieldView'; +import { observer } from "mobx-react"; import { HtmlField } from "../../../new_fields/HtmlField"; import { WebField } from "../../../new_fields/URLField"; -import { observer } from "mobx-react"; -import { computed, reaction, IReactionDisposer } from 'mobx'; import { DocumentDecorations } from "../DocumentDecorations"; import { InkingControl } from "../InkingControl"; +import { FieldView, FieldViewProps } from './FieldView'; +import "./WebBox.scss"; +import React = require("react"); @observer export class WebBox extends React.Component { -- cgit v1.2.3-70-g09d2 From 1b3089350c807a52a2acd98c25330e315313b19e Mon Sep 17 00:00:00 2001 From: madelinegr Date: Wed, 5 Jun 2019 13:16:17 -0400 Subject: collections sort of works --- src/client/views/SearchBox.scss | 24 +++---- src/client/views/SearchBox.tsx | 11 +--- src/client/views/SearchItem.tsx | 141 ++++++++++++++++++++++------------------ src/client/views/ViewItem.tsx | 18 ----- 4 files changed, 92 insertions(+), 102 deletions(-) delete mode 100644 src/client/views/ViewItem.tsx (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 22b198739..c8f139144 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -73,6 +73,8 @@ margin-right: 72px; .search-item { + position: relative; + z-index: 1000; pointer-events: auto; width: 500px; background: $light-color-secondary; @@ -85,6 +87,7 @@ padding: 10px; white-space: nowrap; font-size: 13px; + height: 70px; } .search-info { @@ -137,28 +140,27 @@ .searchBox-instances { - display: inline-block; - background: $dark-color; - width: 100px; - opacity: 1; - // width: 0px; this is real - // visibility: hidden; - // opacity: 0; THIS IS REAL - // transition: all 0.2s ease; - color: $light-color; + display: block; + background: $light-color-secondary; + opacity: 0; + width: 150px; + transition: all 0.2s ease; + color: black; + transform: translateX(150px); } + .search-overview { display: flex; // float: left; justify-content: flex-end; + height: 70px; } .search-overview:hover { .searchBox-instances { - // visibility: visible; + transform: translateX(0px); opacity: 1; - width: 100px; } } } \ No newline at end of file diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 51fcb4596..0fd3c0904 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -38,6 +38,7 @@ export class SearchBox extends React.Component { @observable private _results: Doc[] = []; + @action.bound onChange(e: React.ChangeEvent) { this.searchString = e.target.value; @@ -73,6 +74,7 @@ export class SearchBox extends React.Component { } return docs; } + public static async convertDataUri(imageUri: string, returnedFilename: string) { try { let posting = DocServer.prepend(RouteStore.dataUriToImage); @@ -201,14 +203,7 @@ export class SearchBox extends React.Component {
{this._resultsOpen ? (
- {this._results.map(result => { - this.getViews(result).then((res: Doc[]) => { - console.log("found") - return - }) - })} - {/* {this._results.map(result => )} */} - {/*views = {this.getViews(result)}*/} + {this._results.map(result => )}
) : null}
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index e82aa0719..ba32a408e 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -4,7 +4,7 @@ import { DocumentManager } from "../util/DocumentManager"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast } from "../../new_fields/Types"; +import { Cast, NumCast } from "../../new_fields/Types"; import { FieldView, FieldViewProps } from './nodes/FieldView'; import { computed, observable, action, runInAction } from "mobx"; import { IconField } from "../../new_fields/IconField"; @@ -15,18 +15,13 @@ import { RichTextField } from "../../new_fields/RichTextField"; import { SetupDrag } from "../util/DragManager"; import { SearchUtil } from "../util/SearchUtil"; import { Id } from "../../new_fields/FieldSymbols"; -import { ViewItem } from "./ViewItem"; - - -export interface SearchProps { - doc: Doc; - views: Doc[]; -} +import { CollectionDockingView } from "./collections/CollectionDockingView"; +import { observer } from "mobx-react"; +import { CollectionViewType } from "./collections/CollectionBaseView"; export interface SearchItemProps { doc: Doc; - views: Doc[]; - // subitems: FieldViewProps; + // addDocTab(doc: Doc, location: string): void } library.add(faCaretUp); @@ -39,50 +34,66 @@ library.add(faLink); library.add(faChartBar); library.add(faGlobeAsia); -export class SearchItem extends React.Component { +@observer +export class SelectorContextMenu extends React.Component { + @observable private _docs: { col: Doc, target: Doc }[] = []; + @observable private _otherDocs: { col: Doc, target: Doc }[] = []; - @observable _selected: boolean = false; + constructor(props: SearchItemProps) { + super(props); - @observable - private _instances: Doc[] = []; + this.fetchDocuments(); + } - // @action - // getViews = async () => { - // const results = await SearchUtil.GetViewsOfDocument(this.props.doc); - // runInAction(() => { - // this._instances = results; - // }); - // } + async fetchDocuments() { + console.log("fetching"); + let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); + const docs = await SearchUtil.Search(`data_l:"${this.props.doc[Id]}"`, true); + const map: Map = new Map; + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search(`data_l:"${doc[Id]}"`, true))); + allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); + docs.forEach(doc => map.delete(doc)); + runInAction(() => { + console.log("action running") + this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.doc })); + this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); + }); + } - onClick = () => { - DocumentManager.Instance.jumpToDocument(this.props.doc); + getOnClick({ col, target }: { col: Doc, target: Doc }) { + return () => { + console.log("returning!") + // col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; + // if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { + // const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; + // const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; + // col.panX = newPanX; + // col.panY = newPanY; + // } + // this.props.addDocTab(col, "inTab"); + }; } - //something wrong with this - containingCollection(): string { - let docView = DocumentManager.Instance.getDocumentView(this.props.doc); - if (docView) { - let containerView = docView.props.ContainingCollectionView; - if (containerView) { - let container = containerView.props.Document; - const field = Cast(container.title, RichTextField); - return field ? field.Data : "

Error loading icon data

"; - } - } - return "None"; + render() { + return ( + <> +

Contexts:

+ {this._docs.map(doc =>

{doc.col.title}

)} + {this._otherDocs.length ?
: null} + {this._otherDocs.map(doc =>

{doc.col.title}

)} + + ); } +} - //also probably with this rip - containingCollectionView() { - let docView = DocumentManager.Instance.getDocumentView(this.props.doc); - if (docView) { - let containerView = docView.props.ContainingCollectionView; - if (containerView) { - return containerView.props.Document; - } - } +@observer +export class SearchItem extends React.Component { + + @observable _selected: boolean = false; + @observable hover = false; - return this.props.doc; + onClick = () => { + DocumentManager.Instance.jumpToDocument(this.props.doc); } public DocumentIcon() { @@ -112,27 +123,33 @@ export class SearchItem extends React.Component { } } - select = () => { - // console.log('moused'); - // console.log("before:", this.props.doc, this._selected) - this._selected = !this._selected; - // console.log("after:", this.props.doc, this._selected) - } - linkCount = () => { - console.log("counting") - let linkToSize = Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length; - let linkFromSize = Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; - let linkCount = linkToSize + linkFromSize; - return linkCount; + return Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length + Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; } + // @action + // onMouseLeave = () => { + // this.hover = false; + // } + + // @action + // onMouseEnter = () => { + // this.hover = true; + // } + render() { return ( -
+
+ {/* onMouseEnter={this.onMouseEnter} + onMouseLeave={this.onMouseLeave}> */}
- {this.props.views.map(result => )} +
+ {/* {this.hover ? ( +
+ +
+ ) : null} */}
{this.props.doc.title}
@@ -143,14 +160,8 @@ export class SearchItem extends React.Component {
Where Found: (i.e. title, body, etc)
- {/*
Collection: {this.containingCollection()}
*/}
- - {/*
-
Collection: {this.containingCollection()}
-
-
*/}
); } diff --git a/src/client/views/ViewItem.tsx b/src/client/views/ViewItem.tsx deleted file mode 100644 index 85f436b44..000000000 --- a/src/client/views/ViewItem.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Doc } from "../../new_fields/Doc"; -import React = require("react"); -import "./SearchBox.scss"; - -export interface ViewitemProps { - doc: Doc; - // subitems: FieldViewProps; -} - -export class ViewItem extends React.Component { - - render() { - return ( -
{this.props.doc.title}
- - ); - } -} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3dc4e6ee14294ae110ac5c6449df804ebe0212a1 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Wed, 5 Jun 2019 13:40:14 -0400 Subject: a bit of clean up --- src/client/views/SearchBox.scss | 1 - src/client/views/SearchBox.tsx | 10 ---------- src/client/views/SearchItem.tsx | 27 ++------------------------- 3 files changed, 2 insertions(+), 36 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index c8f139144..d7c8b857a 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -152,7 +152,6 @@ .search-overview { display: flex; - // float: left; justify-content: flex-end; height: 70px; } diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 0fd3c0904..657273791 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -1,23 +1,15 @@ import * as React from 'react'; import { observer } from 'mobx-react'; import { observable, action, runInAction } from 'mobx'; -import { Utils } from '../../Utils'; -import { MessageStore } from '../../server/Message'; import "./SearchBox.scss"; import { faSearch, faObjectGroup } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; -// const app = express(); -// import * as express from 'express'; -import { Search } from '../../server/Search'; import * as rp from 'request-promise'; import { SearchItem } from './SearchItem'; -import { isString } from 'util'; -import { constant } from 'async'; import { DocServer } from '../DocServer'; import { Doc } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; -import { DocumentManager } from '../util/DocumentManager'; import { SetupDrag } from '../util/DragManager'; import { Docs } from '../documents/Documents'; import { RouteStore } from '../../server/RouteStore'; @@ -174,7 +166,6 @@ export class SearchBox extends React.Component { @action getViews = async (doc: Doc) => { - console.log("getting view") const results = await SearchUtil.GetViewsOfDocument(doc); let toReturn: Doc[] = []; await runInAction(() => { @@ -199,7 +190,6 @@ export class SearchBox extends React.Component { className="searchBox-barChild searchBox-input" onKeyPress={this.enter} style={{ width: this._resultsOpen ? "500px" : undefined }} /> - {/* */}
{this._resultsOpen ? (
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index ae9bc350f..ba67363fb 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -2,14 +2,9 @@ import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast, NumCast } from "../../new_fields/Types"; -import { FieldView, FieldViewProps } from './nodes/FieldView'; -import { computed, observable, action, runInAction } from "mobx"; -import { IconField } from "../../new_fields/IconField"; +import { Cast } from "../../new_fields/Types"; +import { observable, runInAction } from "mobx"; import { listSpec } from "../../new_fields/Schema"; -import { Transform } from "../util/Transform"; -import { ObjectField } from "../../new_fields/ObjectField"; -import { RichTextField } from "../../new_fields/RichTextField"; import { Doc } from "../../new_fields/Doc"; import { DocumentManager } from "../util/DocumentManager"; import { SetupDrag } from "../util/DragManager"; @@ -17,7 +12,6 @@ import { SearchUtil } from "../util/SearchUtil"; import { Id } from "../../new_fields/FieldSymbols"; import { CollectionDockingView } from "./collections/CollectionDockingView"; import { observer } from "mobx-react"; -import { CollectionViewType } from "./collections/CollectionBaseView"; export interface SearchItemProps { doc: Doc; @@ -127,29 +121,12 @@ export class SearchItem extends React.Component { return Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length + Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; } - // @action - // onMouseLeave = () => { - // this.hover = false; - // } - - // @action - // onMouseEnter = () => { - // this.hover = true; - // } - render() { return (
- {/* onMouseEnter={this.onMouseEnter} - onMouseLeave={this.onMouseLeave}> */}
- {/* {this.hover ? ( -
- -
- ) : null} */}
{this.props.doc.title}
-- cgit v1.2.3-70-g09d2 From ddbd871da2611a8297729dbabab74cd87b5dd412 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Wed, 5 Jun 2019 16:32:10 -0400 Subject: search is working rip my previous progress --- src/client/views/SearchBox.scss | 37 +++++++++++++++++++++++--------- src/client/views/SearchItem.tsx | 17 ++++++--------- src/client/views/globalCssVariables.scss | 1 + 3 files changed, 35 insertions(+), 20 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 72a0d4b72..4c60710da 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -73,6 +73,7 @@ margin-right: 72px; .search-item { + float: right; position: relative; z-index: 1000; pointer-events: auto; @@ -103,7 +104,7 @@ } .search-item:hover { - transition: all 0.1s; + transition: all 0.2s; background: $lighter-alt-accent; } @@ -140,26 +141,42 @@ .searchBox-instances { - display: block; - background: $lighter-alt-accent; - opacity: 0; + float: left; + display: inline-block; + opacity: 1; width: 150px; transition: all 0.2s ease; color: black; - transform: translateX(150px); + transform-origin: top right; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + height: 100% } + .collection{ + border-color: $darker-alt-accent; + border-bottom-style: solid; + } .search-overview { display: flex; + flex-direction: row-reverse; justify-content: flex-end; height: 70px; } - .search-overview:hover { - .searchBox-instances { - transform: translateX(0px); - opacity: 1; - } + .parents{ + background: $light-color-secondary; + padding: 10px; } + + .search-item:hover~.searchBox-instances, .searchBox-instances:hover { + opacity: 1; + background: $lighter-alt-accent; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + } \ No newline at end of file diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index ba67363fb..052c14acb 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -40,7 +40,6 @@ export class SelectorContextMenu extends React.Component { } async fetchDocuments() { - console.log("fetching"); let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); const docs = await SearchUtil.Search(`data_l:"${this.props.doc[Id]}"`, true); const map: Map = new Map; @@ -48,7 +47,6 @@ export class SelectorContextMenu extends React.Component { allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); runInAction(() => { - console.log("action running") this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.doc })); this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); }); @@ -70,12 +68,11 @@ export class SelectorContextMenu extends React.Component { render() { return ( - <> + < div className="parents">

Contexts:

- {this._docs.map(doc =>

{doc.col.title}

)} - {this._otherDocs.length ?
: null} - {this._otherDocs.map(doc =>

{doc.col.title}

)} - + {this._docs.map(doc => )} + {this._otherDocs.map(doc =>)} +
); } } @@ -124,9 +121,6 @@ export class SearchItem extends React.Component { render() { return (
-
- -
{this.props.doc.title}
@@ -139,6 +133,9 @@ export class SearchItem extends React.Component {
Where Found: (i.e. title, body, etc)
+
+ +
); } diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index 838d4d9ac..cfbf4aab8 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -9,6 +9,7 @@ $main-accent: #aaaaa3; //$alt-accent: #59dff7; $alt-accent: #c2c2c5; $lighter-alt-accent: rgb(207, 220, 240); +$darker-alt-accent: rgb(178, 206, 248); $intermediate-color: #9c9396; $dark-color: #121721; // fonts -- cgit v1.2.3-70-g09d2 From 0cfbf74a3f61b3b3e15e06fe11793dae653a7952 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Wed, 5 Jun 2019 17:15:22 -0400 Subject: split scss files --- src/client/views/SearchBox.scss | 117 --------------------------------------- src/client/views/SearchItem.scss | 109 ++++++++++++++++++++++++++++++++++++ src/client/views/SearchItem.tsx | 1 + 3 files changed, 110 insertions(+), 117 deletions(-) create mode 100644 src/client/views/SearchItem.scss (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 4c60710da..cba706602 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -30,15 +30,6 @@ align-self: stretch; } - .searchBox-submit { - color: $dark-color; - } - - .searchBox-submit:hover { - color: $main-accent; - transform: scale(1.05); - cursor: pointer; - } } .searchBox-results { @@ -71,112 +62,4 @@ display: flex; flex-direction: column; margin-right: 72px; - - .search-item { - float: right; - position: relative; - z-index: 1000; - pointer-events: auto; - width: 500px; - background: $light-color-secondary; - justify-content: space-between; - align-items: center; - border-width: 0.11px; - border-style: none; - border-color: $intermediate-color; - border-bottom-style: solid; - padding: 10px; - white-space: nowrap; - font-size: 13px; - height: 70px; - } - - .search-info { - display: flex; - justify-content: flex-end; - width: 100%; - } - - .main-search-info { - display: flex; - flex-direction: row; - width: 100%; - } - - .search-item:hover { - transition: all 0.2s; - background: $lighter-alt-accent; - } - - .search-title { - text-transform: uppercase; - text-align: left; - width: 8vw; - font-weight: bold; - } - - .more-search-info { - text-align: left; - } - - .link-count { - height: 25px; - width: 25px; - border-radius: 50%; - background: $dark-color; - color: $light-color-secondary; - display: flex; - justify-content: center; - align-items: center; - margin-right: 10px; - } - - .search-type { - width: 25PX; - height: 25PX; - display: flex; - justify-content: center; - align-items: center; - } - - - .searchBox-instances { - float: left; - display: inline-block; - opacity: 1; - width: 150px; - transition: all 0.2s ease; - color: black; - transform-origin: top right; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); - height: 100% - } - - .collection{ - border-color: $darker-alt-accent; - border-bottom-style: solid; - } - - .search-overview { - display: flex; - flex-direction: row-reverse; - justify-content: flex-end; - height: 70px; - } - - .parents{ - background: $light-color-secondary; - padding: 10px; - } - - .search-item:hover~.searchBox-instances, .searchBox-instances:hover { - opacity: 1; - background: $lighter-alt-accent; - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - } - } \ No newline at end of file diff --git a/src/client/views/SearchItem.scss b/src/client/views/SearchItem.scss new file mode 100644 index 000000000..7ee51bb54 --- /dev/null +++ b/src/client/views/SearchItem.scss @@ -0,0 +1,109 @@ +@import "globalCssVariables"; + +.search-item { + float: right; + position: relative; + z-index: 1000; + pointer-events: auto; + width: 500px; + background: $light-color-secondary; + justify-content: space-between; + align-items: center; + border-width: 0.11px; + border-style: none; + border-color: $intermediate-color; + border-bottom-style: solid; + padding: 10px; + white-space: nowrap; + font-size: 13px; + height: 70px; +} + +.search-info { + display: flex; + justify-content: flex-end; + width: 100%; +} + +.main-search-info { + display: flex; + flex-direction: row; + width: 100%; +} + +.search-item:hover { + transition: all 0.2s; + background: $lighter-alt-accent; +} + +.search-title { + text-transform: uppercase; + text-align: left; + width: 8vw; + font-weight: bold; +} + +.more-search-info { + text-align: left; +} + +.link-count { + height: 25px; + width: 25px; + border-radius: 50%; + background: $dark-color; + color: $light-color-secondary; + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; +} + +.search-type { + width: 25PX; + height: 25PX; + display: flex; + justify-content: center; + align-items: center; +} + + +.searchBox-instances { + float: left; + display: inline-block; + opacity: 1; + width: 150px; + transition: all 0.2s ease; + color: black; + transform-origin: top right; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + height: 100% +} + +.collection { + border-color: $darker-alt-accent; + border-bottom-style: solid; +} + +.search-overview { + display: flex; + flex-direction: row-reverse; + justify-content: flex-end; + height: 70px; +} + +.parents { + background: $lighter-alt-accent; + padding: 10px; +} + +.search-item:hover~.searchBox-instances, +.searchBox-instances:hover { + opacity: 1; + background: $lighter-alt-accent; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} \ No newline at end of file diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 052c14acb..dfa1014f5 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -12,6 +12,7 @@ import { SearchUtil } from "../util/SearchUtil"; import { Id } from "../../new_fields/FieldSymbols"; import { CollectionDockingView } from "./collections/CollectionDockingView"; import { observer } from "mobx-react"; +import "./SearchItem.scss"; export interface SearchItemProps { doc: Doc; -- cgit v1.2.3-70-g09d2 From 234fd22cf888f1d4efea70189b2762e865a61819 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Wed, 5 Jun 2019 17:28:15 -0400 Subject: css updates --- src/client/views/SearchItem.scss | 17 +---------------- src/client/views/SearchItem.tsx | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchItem.scss b/src/client/views/SearchItem.scss index 7ee51bb54..b6ee7deca 100644 --- a/src/client/views/SearchItem.scss +++ b/src/client/views/SearchItem.scss @@ -1,21 +1,11 @@ @import "globalCssVariables"; .search-item { - float: right; - position: relative; - z-index: 1000; - pointer-events: auto; width: 500px; background: $light-color-secondary; - justify-content: space-between; - align-items: center; - border-width: 0.11px; - border-style: none; border-color: $intermediate-color; border-bottom-style: solid; padding: 10px; - white-space: nowrap; - font-size: 13px; height: 70px; } @@ -43,10 +33,6 @@ font-weight: bold; } -.more-search-info { - text-align: left; -} - .link-count { height: 25px; width: 25px; @@ -70,8 +56,7 @@ .searchBox-instances { float: left; - display: inline-block; - opacity: 1; + opacity: 0; width: 150px; transition: all 0.2s ease; color: black; diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index dfa1014f5..40b8cf2bf 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -130,9 +130,7 @@ export class SearchItem extends React.Component {
{this.DocumentIcon()}
-
Where Found: (i.e. title, body, etc)
-
-- cgit v1.2.3-70-g09d2 From bff9c34aa8294cd8ec09b968cfea95280b383c77 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Thu, 6 Jun 2019 14:15:32 -0400 Subject: weird thingsS --- package.json | 1 + src/client/views/SearchBox.tsx | 22 +++++++++++++--------- src/client/views/SearchItem.scss | 14 +++++++++----- src/client/views/SearchItem.tsx | 37 +++++++++++++++++++++++++------------ 4 files changed, 48 insertions(+), 26 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/package.json b/package.json index df0767b50..95221cbc9 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@hig/theme-context": "^2.1.3", "@hig/theme-data": "^2.3.3", "@trendmicro/react-dropdown": "^1.3.0", + "@types/animejs": "^2.0.2", "@types/async": "^2.4.1", "@types/bcrypt-nodejs": "0.0.30", "@types/bluebird": "^3.5.25", diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 5e1389959..ed8dbbe51 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -15,6 +15,8 @@ import { Docs } from '../documents/Documents'; import { RouteStore } from '../../server/RouteStore'; import { NumCast } from '../../new_fields/Types'; import { SearchUtil } from '../util/SearchUtil'; +import * as anime from 'animejs'; +// import anime from 'animejs'; library.add(faSearch); library.add(faObjectGroup); @@ -54,6 +56,7 @@ export class SearchBox extends React.Component { this._resultsOpen = true; this._results = results; }); + } @action @@ -216,15 +219,16 @@ export class SearchBox extends React.Component {
temp for filtering by a type of node
- - - - - - - - - + {/* hoping to ultimately animate a reorder when an icon is chosen */} + + + + + + + + +
diff --git a/src/client/views/SearchItem.scss b/src/client/views/SearchItem.scss index b6ee7deca..a6cd852b1 100644 --- a/src/client/views/SearchItem.scss +++ b/src/client/views/SearchItem.scss @@ -56,14 +56,18 @@ .searchBox-instances { float: left; - opacity: 0; + // opacity: 0; + opacity: 1; width: 150px; transition: all 0.2s ease; color: black; transform-origin: top right; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); + // -webkit-transform: scale(0); + // -ms-transform: scale(0); + // transform: scale(0); + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); height: 100% } @@ -85,7 +89,7 @@ } .search-item:hover~.searchBox-instances, -.searchBox-instances:hover { +.searchBox-instances:hover, .searchBox-instances:active{ opacity: 1; background: $lighter-alt-accent; -webkit-transform: scale(1); diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 40b8cf2bf..16a2aa790 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast } from "../../new_fields/Types"; +import { Cast, NumCast } from "../../new_fields/Types"; import { observable, runInAction } from "mobx"; import { listSpec } from "../../new_fields/Schema"; import { Doc } from "../../new_fields/Doc"; @@ -13,6 +13,7 @@ import { Id } from "../../new_fields/FieldSymbols"; import { CollectionDockingView } from "./collections/CollectionDockingView"; import { observer } from "mobx-react"; import "./SearchItem.scss"; +import { CollectionViewType } from "./collections/CollectionBaseView"; export interface SearchItemProps { doc: Doc; @@ -54,25 +55,37 @@ export class SelectorContextMenu extends React.Component { } getOnClick({ col, target }: { col: Doc, target: Doc }) { + console.log("hello world") return () => { console.log("returning!") - // col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; - // if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - // const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; - // const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; - // col.panX = newPanX; - // col.panY = newPanY; - // } + col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; + if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { + const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; + const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; + col.panX = newPanX; + col.panY = newPanY; + } // this.props.addDocTab(col, "inTab"); + CollectionDockingView.Instance.AddRightSplit(col); }; } render() { return ( - < div className="parents"> + < div className="parents" onClick = {() => {console.log("hello there")}}>

Contexts:

- {this._docs.map(doc => )} - {this._otherDocs.map(doc =>)} + {this._docs.map(doc => )} + {this._otherDocs.map(doc => )}
); } @@ -130,7 +143,7 @@ export class SearchItem extends React.Component {
{this.DocumentIcon()}
-
Where Found: (i.e. title, body, etc)
+
Where Found: (i.e. title, body, etc)
-- cgit v1.2.3-70-g09d2 From 7e3493a95aaf8d4ba585b326c278556e39346f11 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Thu, 6 Jun 2019 17:08:38 -0400 Subject: opening and closing filter and results works --- src/client/views/SearchBox.tsx | 54 ++++++++++++++++++++++++---------------- src/client/views/SearchItem.scss | 12 ++++----- src/client/views/SearchItem.tsx | 21 ++++++++-------- 3 files changed, 48 insertions(+), 39 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index ed8dbbe51..8fb180273 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -96,34 +96,45 @@ export class SearchBox extends React.Component { } @action - handleClickFilter = (e: Event): void => { - var className = (e.target as any).className; - var id = (e.target as any).id; - if (className !== "filter-button" && className !== "filter-form") { + handleSearchClick = (e: Event): void => { + let element = document.getElementsByClassName((e.target as any).className)[0]; + //handles case with filter button + if((e.target as any).className.includes("filter")){ + this._resultsOpen = false; + this._open = true;} + else if (element && element.parentElement){ + //if the filter element is found, show the form and hide the results + if(this.findAncestor(element, "filter-form")){ + this._resultsOpen = false; + this._open = true; + } + //if in main search div, keep results open and close filter + else if(this.findAncestor(element, "main-searchDiv")){ + this._resultsOpen = true; + this._open = false; + } + } + //not in either, close both + else{ + this._resultsOpen = false; this._open = false; } - + } - @action - handleClickResults = (e: Event): void => { - var className = (e.target as any).className; - var id = (e.target as any).id; - if (id !== "result") { - this._resultsOpen = false; - this._results = []; - } + //finds ancestor div that matches class name passed in, if not found false returned + findAncestor(curElement: any, cls: string) { + while ((curElement = curElement.parentElement) && !curElement.classList.contains(cls)); + return curElement; } componentWillMount() { - document.addEventListener('mousedown', this.handleClickFilter, false); - document.addEventListener('mousedown', this.handleClickResults, false); + document.addEventListener('mousedown', this.handleSearchClick, false); } componentWillUnmount() { - document.removeEventListener('mousedown', this.handleClickFilter, false); - document.removeEventListener('mousedown', this.handleClickResults, false); + document.removeEventListener('mousedown', this.handleSearchClick, false); } @action @@ -131,7 +142,7 @@ export class SearchBox extends React.Component { this._open = !this._open; } - enter = (e: React.KeyboardEvent) => { + enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } @@ -199,8 +210,8 @@ export class SearchBox extends React.Component { - + style={{ width: this._resultsOpen ? "500px" : "100px" }} /> +
{this._resultsOpen ? (
@@ -208,11 +219,11 @@ export class SearchBox extends React.Component {
) : null} + {/* these all need class names in order to find ancestor - please do not delete */} {this._open ? (
- filter by collection, key, type of node
temp for making words required
@@ -238,7 +249,6 @@ export class SearchBox extends React.Component { temp for filtering where in doc the keywords are found
- ) : null} diff --git a/src/client/views/SearchItem.scss b/src/client/views/SearchItem.scss index a6cd852b1..4c1d781e3 100644 --- a/src/client/views/SearchItem.scss +++ b/src/client/views/SearchItem.scss @@ -62,12 +62,12 @@ transition: all 0.2s ease; color: black; transform-origin: top right; - // -webkit-transform: scale(0); - // -ms-transform: scale(0); - // transform: scale(0); - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + // -webkit-transform: scale(1); + // -ms-transform: scale(1); + // transform: scale(1); height: 100% } diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 16a2aa790..c80d9baa2 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -55,9 +55,7 @@ export class SelectorContextMenu extends React.Component { } getOnClick({ col, target }: { col: Doc, target: Doc }) { - console.log("hello world") return () => { - console.log("returning!") col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; @@ -70,19 +68,20 @@ export class SelectorContextMenu extends React.Component { }; } + onClick = () => { + console.log("click"); + } + + //these all need class names in order to find ancestor - please do not delete render() { return ( - < div className="parents" onClick = {() => {console.log("hello there")}}> -

Contexts:

- {this._docs.map(doc =>
{ - console.log("pointerdown"); - e.preventDefault(); - e.stopPropagation() + < div className="parents"> +

Contexts:

+ {this._docs.map(doc =>
)} - {this._otherDocs.map(doc =>
{ - e.preventDefault(); - e.stopPropagation() + {this._otherDocs.map(doc => )} -- cgit v1.2.3-70-g09d2 From 94e6613e92a71e35427875e4ed8eb72a0302bca1 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Thu, 6 Jun 2019 19:17:02 -0400 Subject: i hate everytihgn the freickin import end of day 6/6 --- deploy/index.html | 1 + package.json | 1 + src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/SearchBox.scss | 17 +++++ src/client/views/SearchBox.tsx | 121 ++++++++++++++++++++++++++++---- src/client/views/SearchItem.tsx | 19 ++--- tsconfig.json | 1 + 7 files changed, 131 insertions(+), 31 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/deploy/index.html b/deploy/index.html index 532b995f8..92635e7f5 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -6,6 +6,7 @@ + diff --git a/package.json b/package.json index 95221cbc9..7946d8553 100644 --- a/package.json +++ b/package.json @@ -152,6 +152,7 @@ "pug": "^2.0.3", "raw-loader": "^1.0.0", "react": "^16.8.4", + "react-anime": "^2.2.0", "react-bootstrap": "^1.0.0-beta.5", "react-bootstrap-dropdown-menu": "^1.1.15", "react-color": "^2.17.0", diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 24327b995..d1224febe 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -102,6 +102,6 @@ export class MainOverlayTextBox extends React.Component
; } - else return (null); Z + else return (null); } } \ No newline at end of file diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 76332a515..eff47393b 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -75,4 +75,21 @@ width: 100%; } +} + +.toggle-bar{ + width: 100%; + height: 50px; + background-color: $alt-accent; + border-radius: 10px; + padding: 5px; + display: flex; + align-items: center; + + .toggle-button{ + width: 80px; + height: 100%; + border-radius: 10px; + background-color: $light-color; + } } \ No newline at end of file diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 8fb180273..4ebf77f60 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { observer } from 'mobx-react'; import { observable, action, runInAction } from 'mobx'; import "./SearchBox.scss"; -import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; +import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; import * as rp from 'request-promise'; @@ -16,7 +16,12 @@ import { RouteStore } from '../../server/RouteStore'; import { NumCast } from '../../new_fields/Types'; import { SearchUtil } from '../util/SearchUtil'; import * as anime from 'animejs'; -// import anime from 'animejs'; +// const Anime = ReactAnime.default; +// import * as anime from '../../../node_modules/@types'; +// const anime = require('lib/anime.js'); +// import anime from 'animejs/lib/anime.es'; +// import anime = require ('lib/anime.min.js'); +// import Anime from 'react-anime'; library.add(faSearch); library.add(faObjectGroup); @@ -28,12 +33,98 @@ library.add(faMusic); library.add(faLink); library.add(faChartBar); library.add(faGlobeAsia); +library.add(faBan); + +export interface ToggleBarProps { + //false = right, true = left + // status: boolean; + changeStatus(value: boolean): void; + //addDocTab(doc: Doc, location: string): void; +} + +@observer +export class ToggleBar extends React.Component{ + + @observable _status: boolean = false; + + // @observable clicked: boolean = true; + + @action.bound + toggle() { + this._status = !this._status; + } + + render() { + var timeline = anime.timeline({ + autoplay:false + }) + + timeline.add({ + targets: '.toggle-button', + translateX: '100%', + direction: 'alternate', + easing: 'easeInOutQuad' + }); + + // var wordQueryToggle = anime({ + // targets: '.toggle-button', + // translateX: '100%', + // direction: 'alternate', + // easing: 'easeInOutQuad' + // }); + // document.querySelector('.toggle-button').onClick = wordQueryToggle; + + return ( +
+
timeline.play()}> + {/*
*/} + {/* {this._status ? ( + +
+ + ) : ( + +
+ + )} */} + +{/* + + +
+ */} + {/*
*/} +
+ ); + }; +} + @observer export class SearchBox extends React.Component { @observable searchString: string = ""; + @observable _wordStatus: boolean = true; + @observable private _open: boolean = false; @observable private _resultsOpen: boolean = false; @@ -99,27 +190,28 @@ export class SearchBox extends React.Component { handleSearchClick = (e: Event): void => { let element = document.getElementsByClassName((e.target as any).className)[0]; //handles case with filter button - if((e.target as any).className.includes("filter")){ + if ((e.target as any).className.includes("filter")) { this._resultsOpen = false; - this._open = true;} - else if (element && element.parentElement){ + this._open = true; + } + else if (element && element.parentElement) { //if the filter element is found, show the form and hide the results - if(this.findAncestor(element, "filter-form")){ + if (this.findAncestor(element, "filter-form")) { this._resultsOpen = false; this._open = true; } //if in main search div, keep results open and close filter - else if(this.findAncestor(element, "main-searchDiv")){ + else if (this.findAncestor(element, "main-searchDiv")) { this._resultsOpen = true; this._open = false; } } //not in either, close both - else{ + else { this._resultsOpen = false; this._open = false; } - + } @@ -137,11 +229,6 @@ export class SearchBox extends React.Component { document.removeEventListener('mousedown', this.handleSearchClick, false); } - @action - toggleFilterDisplay = () => { - this._open = !this._open; - } - enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); @@ -196,6 +283,9 @@ export class SearchBox extends React.Component { return toReturn; } + handleWordQueryChange = (value: boolean) => { + this._wordStatus = value; + } // Useful queries: // Delegates of a document: {!join from=id to=proto_i}id:{protoId} @@ -225,12 +315,13 @@ export class SearchBox extends React.Component {
- temp for making words required +
temp for filtering by a type of node
{/* hoping to ultimately animate a reorder when an icon is chosen */} + diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index c80d9baa2..8e6a4010a 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -17,7 +17,6 @@ import { CollectionViewType } from "./collections/CollectionBaseView"; export interface SearchItemProps { doc: Doc; - // addDocTab(doc: Doc, location: string): void } library.add(faCaretUp); @@ -63,28 +62,17 @@ export class SelectorContextMenu extends React.Component { col.panX = newPanX; col.panY = newPanY; } - // this.props.addDocTab(col, "inTab"); CollectionDockingView.Instance.AddRightSplit(col); }; } - onClick = () => { - console.log("click"); - } - //these all need class names in order to find ancestor - please do not delete render() { return ( < div className="parents">

Contexts:

- {this._docs.map(doc => )} - {this._otherDocs.map(doc => )} + {this._docs.map(doc => )} + {this._otherDocs.map(doc => )}
); } @@ -97,7 +85,8 @@ export class SearchItem extends React.Component { @observable hover = false; onClick = () => { - DocumentManager.Instance.jumpToDocument(this.props.doc); + // DocumentManager.Instance.jumpToDocument(this.props.doc); + CollectionDockingView.Instance.AddRightSplit(this.props.doc); } public DocumentIcon() { diff --git a/tsconfig.json b/tsconfig.json index 0d4d77002..f3b87cac9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "target": "es5", "removeComments": true, "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, "strict": true, "jsx": "react", "sourceMap": true, -- cgit v1.2.3-70-g09d2 From 54d41e1eae499459e14d6d3a729127f231520f98 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Mon, 10 Jun 2019 14:51:52 -0400 Subject: thigns working --- src/client/documents/Documents.ts | 35 +++++-- src/client/views/SearchBox.scss | 15 ++- src/client/views/SearchBox.tsx | 193 ++++++++++++++++++++++++++++---------- src/client/views/SearchItem.tsx | 19 ++-- tsconfig.json | 1 + 5 files changed, 193 insertions(+), 70 deletions(-) (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2da4c8d88..8884bcc52 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -38,6 +38,21 @@ import { RouteStore } from "../../server/RouteStore"; var requestImageSize = require('request-image-size'); var path = require('path'); +export enum DocTypes { + NONE = "none", + IMG = "image", + HIST = "histogram", + ICON = "icon", + TEXT = "text", + PDF = "pdf", + WEB = "web", + COL = "collection", + KVP = "kvp", + VID = "video", + AUDIO = "audio", + LINK = "link" +} + export interface DocumentOptions { x?: number; y?: number; @@ -155,54 +170,54 @@ export namespace Docs { function CreateImagePrototype(): Doc { let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0, type: "image" }); + { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0, type: DocTypes.IMG }); return imageProto; } function CreateHistogramPrototype(): Doc { let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("annotations"), - { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString(), type: "histogram" }); + { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString(), type: DocTypes.HIST }); return histoProto; } function CreateIconPrototype(): Doc { let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(), - { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), type: "icon" }); + { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), type: DocTypes.ICON }); return iconProto; } function CreateTextPrototype(): Doc { let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb", type: "text" }); + { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb", type: DocTypes.TEXT }); return textProto; } function CreatePdfPrototype(): Doc { let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1, type: "pdf" }); + { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1, type: DocTypes.PDF }); return pdfProto; } function CreateWebPrototype(): Doc { let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 300, type: "web" }); + { x: 0, y: 0, width: 300, height: 300, type: DocTypes.WEB }); return webProto; } function CreateCollectionPrototype(): Doc { let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("data"), - { panX: 0, panY: 0, scale: 1, width: 500, height: 500, type: "collection" }); + { panX: 0, panY: 0, scale: 1, width: 500, height: 500, type: DocTypes.COL }); return collProto; } function CreateKVPPrototype(): Doc { let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, type: "kvp" }); + { x: 0, y: 0, width: 300, height: 150, type: DocTypes.KVP }); return kvpProto; } function CreateVideoPrototype(): Doc { let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("annotations"), - { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0, type: "video" }); + { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0, type: DocTypes.VID }); return videoProto; } function CreateAudioPrototype(): Doc { let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, type: "audio" }); + { x: 0, y: 0, width: 300, height: 150, type: DocTypes.AUDIO }); return audioProto; } diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss index 8ec440fca..91d17d001 100644 --- a/src/client/views/SearchBox.scss +++ b/src/client/views/SearchBox.scss @@ -82,12 +82,19 @@ } .type-icon{ - margin-right: 5px; - margin-left: 5px; - height: 40px; - width: 40px; + height: 50px; + width: 50px; color: $light-color; border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + background-color: "#121721"; + } + + .fontawesome-icon{ + height: 28px; + width: 28px; } .type-icon:hover{ diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index d959826a1..c2ac0c06c 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -11,11 +11,16 @@ import { DocServer } from '../DocServer'; import { Doc } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; import { SetupDrag } from '../util/DragManager'; -import { Docs } from '../documents/Documents'; +import { Docs, DocTypes } from '../documents/Documents'; import { RouteStore } from '../../server/RouteStore'; import { NumCast } from '../../new_fields/Types'; import { SearchUtil } from '../util/SearchUtil'; import * as anime from 'animejs'; +import { updateFunction } from '../../new_fields/util'; +import * as _ from "lodash"; +// import "./globalCssVariables.scss"; +import { findDOMNode } from 'react-dom'; + // import * as anime from '../../../node_modules/@types'; // const anime = require('lib/anime.js'); // import anime from 'animejs/lib/anime.es'; @@ -34,17 +39,117 @@ library.add(faChartBar); library.add(faGlobeAsia); library.add(faBan); +export interface IconBarProps { + updateIcon(newIcons: string[]): void; + getIcons(): string[]; +} + +@observer +export class IconBar extends React.Component { + + @observable newIcons: string[] = []; + + //changes colors of buttons on click - not sure if this is the best method (it probably isn't) + //but i spent a ton of time on it and this is the only thing i could get to work + componentDidMount = () => { + + let buttons = document.querySelectorAll(".type-icon").forEach(node => + node.addEventListener('click', function () { + if (this.style.backgroundColor === "rgb(194, 194, 197)") { + this.style.backgroundColor = "#121721"; + } + else { + this.style.backgroundColor = "#c2c2c5" + } + }) + ); + + } + + onClick = (value: string) => { + let oldIcons = this.props.getIcons() + if (value === "none") { + this.newIcons = [value]; + } + else { + if (oldIcons.includes(value)) { + this.newIcons = _.remove(oldIcons, value); + if (this.newIcons.length === 0) { + this.newIcons = ["none"]; + } + } + else { + this.newIcons = oldIcons; + if (this.newIcons.length === 1 && this.newIcons[0] === "none") { + this.newIcons = [value] + } + else { this.newIcons.push(value); } + } + } + this.props.updateIcon(this.newIcons) + + } + + render() { + + return ( +
+
+
{ this.onClick(DocTypes.NONE) }}> + +
+
{ this.onClick(DocTypes.PDF) }}> + +
+
{ this.onClick(DocTypes.HIST) }}> + +
+
{ this.onClick(DocTypes.COL) }}> + +
+
{ this.onClick(DocTypes.IMG) }}> + +
+
{ this.onClick(DocTypes.VID) }}> + +
+
{ this.onClick(DocTypes.WEB) }}> + +
+
{ this.onClick(DocTypes.LINK) }}> + +
+
{ this.onClick(DocTypes.AUDIO) }}> + +
+
{ this.onClick(DocTypes.TEXT) }}> + +
+
+
+ ) + } +} + export interface ToggleBarProps { //false = right, true = left // status: boolean; changeStatus(value: boolean): void; optionOne: string; optionTwo: string; - //addDocTab(doc: Doc, location: string): void; } //TODO: justify content will align to specific side. Maybe do status passed in and out? - @observer export class ToggleBar extends React.Component{ @@ -55,12 +160,14 @@ export class ToggleBar extends React.Component{ constructor(props: ToggleBarProps) { super(props); this._toggleButton = React.createRef(); - this.timeline = anime.timeline({autoplay: false, - direction: "reverse"}); + this.timeline = anime.timeline({ + autoplay: false, + direction: "reverse" + }); } componentDidMount = () => { - + let bar = document.getElementById("toggle-bar"); let tog = document.getElementById("toggle-button"); let barwidth = 0; @@ -68,7 +175,6 @@ export class ToggleBar extends React.Component{ if (bar && tog) { barwidth = bar.clientWidth; togwidth = tog.clientWidth; - console.log(togwidth) } let totalWidth = (barwidth - togwidth - 10); @@ -80,11 +186,10 @@ export class ToggleBar extends React.Component{ duration: 500 }); } - + @action.bound onclick() { this._status = !this._status; - console.log("sttaus should be:", this._status) this.props.changeStatus(this._status); this.timeline.play(); this.timeline.reverse(); @@ -93,13 +198,13 @@ export class ToggleBar extends React.Component{ render() { return (
-
-
{this.props.optionOne}
-
{this.props.optionTwo}
-
-
-
-
+
+
{this.props.optionOne}
+
{this.props.optionTwo}
+
+
+
+
); }; @@ -108,25 +213,21 @@ export class ToggleBar extends React.Component{ @observer export class SearchBox extends React.Component { - @observable - searchString: string = ""; + @observable _searchString: string = ""; @observable _wordStatus: boolean = true; - + @observable _icons: string[] = ["none"]; @observable private _open: boolean = false; @observable private _resultsOpen: boolean = false; - - @observable - private _results: Doc[] = []; - + @observable private _results: Doc[] = []; @action.bound onChange(e: React.ChangeEvent) { - this.searchString = e.target.value; + this._searchString = e.target.value; } @action submitSearch = async () => { - let query = this.searchString; + let query = this._searchString; //gets json result into a list of documents that can be used const results = await this.getResults(query); @@ -176,8 +277,9 @@ export class SearchBox extends React.Component { @action handleSearchClick = (e: Event): void => { let element = document.getElementsByClassName((e.target as any).className)[0]; + let name: string = (e.target as any).className; //handles case with filter button - if ((e.target as any).className.includes("filter")) { + if (String(name).indexOf("filter") !== -1 || String(name).indexOf("SVG") !== -1) { this._resultsOpen = false; this._open = true; } @@ -195,13 +297,13 @@ export class SearchBox extends React.Component { } //not in either, close both else { + console.log("not either") this._resultsOpen = false; this._open = false; } } - //finds ancestor div that matches class name passed in, if not found false returned findAncestor(curElement: any, cls: string) { while ((curElement = curElement.parentElement) && !curElement.classList.contains(cls)); @@ -224,7 +326,7 @@ export class SearchBox extends React.Component { collectionRef = React.createRef(); startDragCollection = async () => { - const results = await this.getResults(this.searchString); + const results = await this.getResults(this._searchString); const docs = results.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); if (isProto) { @@ -257,7 +359,7 @@ export class SearchBox extends React.Component { y += 300; } } - return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this.searchString}"` }); + return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); } @action @@ -272,7 +374,16 @@ export class SearchBox extends React.Component { handleWordQueryChange = (value: boolean) => { this._wordStatus = value; - console.log("changed toL:", this._wordStatus) + } + + @action.bound + updateIcon(newArray: string[]) { + this._icons = newArray; + } + + @action.bound + getIcons(): string[] { + return this._icons; } // Useful queries: @@ -286,7 +397,7 @@ export class SearchBox extends React.Component { - @@ -295,7 +406,7 @@ export class SearchBox extends React.Component {
{this._results.map(result => )}
- ) : null} + ) : undefined}
{/* these all need class names in order to find ancestor - please do not delete */} {this._open ? ( @@ -303,23 +414,11 @@ export class SearchBox extends React.Component {
- +
temp for filtering by a type of node -
- {/* hoping to ultimately animate a reorder when an icon is chosen */} - - - - - - - - - - -
+
temp for filtering by collection @@ -329,7 +428,7 @@ export class SearchBox extends React.Component {
- ) : null} + ) : undefined}
); } diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 8e6a4010a..acb7eeac4 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -14,6 +14,7 @@ import { CollectionDockingView } from "./collections/CollectionDockingView"; import { observer } from "mobx-react"; import "./SearchItem.scss"; import { CollectionViewType } from "./collections/CollectionBaseView"; +import { DocTypes } from "../documents/Documents"; export interface SearchItemProps { doc: Doc; @@ -92,15 +93,15 @@ export class SearchItem extends React.Component { public DocumentIcon() { let layoutresult = Cast(this.props.doc.type, "string", ""); - let button = layoutresult.indexOf("pdf") !== -1 ? faFilePdf : - layoutresult.indexOf("image") !== -1 ? faImage : - layoutresult.indexOf("text") !== -1 ? faStickyNote : - layoutresult.indexOf("video") !== -1 ? faFilm : - layoutresult.indexOf("collection") !== -1 ? faObjectGroup : - layoutresult.indexOf("audio") !== -1 ? faMusic : - layoutresult.indexOf("link") !== -1 ? faLink : - layoutresult.indexOf("histogram") !== -1 ? faChartBar : - layoutresult.indexOf("web") !== -1 ? faGlobeAsia : + let button = layoutresult.indexOf(DocTypes.PDF) !== -1 ? faFilePdf : + layoutresult.indexOf(DocTypes.IMG) !== -1 ? faImage : + layoutresult.indexOf(DocTypes.TEXT) !== -1 ? faStickyNote : + layoutresult.indexOf(DocTypes.VID) !== -1 ? faFilm : + layoutresult.indexOf(DocTypes.COL) !== -1 ? faObjectGroup : + layoutresult.indexOf(DocTypes.AUDIO) !== -1 ? faMusic : + layoutresult.indexOf(DocTypes.LINK) !== -1 ? faLink : + layoutresult.indexOf(DocTypes.HIST) !== -1 ? faChartBar : + layoutresult.indexOf(DocTypes.WEB) !== -1 ? faGlobeAsia : faCaretUp; return ; } diff --git a/tsconfig.json b/tsconfig.json index f3b87cac9..7f96e406e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "target": "es5", + // "module": "system", "removeComments": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, -- cgit v1.2.3-70-g09d2 From 3655e529eef051e3d68f6e9c242d320be9b32906 Mon Sep 17 00:00:00 2001 From: madelinegr Date: Mon, 10 Jun 2019 15:45:12 -0400 Subject: end of day 6/10 eek --- src/client/views/MainView.tsx | 2 +- src/client/views/SearchBox.scss | 135 ------- src/client/views/SearchBox.tsx | 449 --------------------- src/client/views/SearchItem.scss | 98 ----- src/client/views/SearchItem.tsx | 143 ------- .../views/collections/CollectionVideoView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/search/IconBar.scss | 0 src/client/views/search/IconBar.tsx | 0 src/client/views/search/SearchBox.scss | 135 +++++++ src/client/views/search/SearchBox.tsx | 382 ++++++++++++++++++ src/client/views/search/SearchItem.scss | 98 +++++ src/client/views/search/SearchItem.tsx | 143 +++++++ src/client/views/search/ToggleBar.scss | 0 src/client/views/search/ToggleBar.tsx | 74 ++++ 16 files changed, 836 insertions(+), 829 deletions(-) delete mode 100644 src/client/views/SearchBox.scss delete mode 100644 src/client/views/SearchBox.tsx delete mode 100644 src/client/views/SearchItem.scss delete mode 100644 src/client/views/SearchItem.tsx create mode 100644 src/client/views/search/IconBar.scss create mode 100644 src/client/views/search/IconBar.tsx create mode 100644 src/client/views/search/SearchBox.scss create mode 100644 src/client/views/search/SearchBox.tsx create mode 100644 src/client/views/search/SearchItem.scss create mode 100644 src/client/views/search/SearchItem.tsx create mode 100644 src/client/views/search/ToggleBar.scss create mode 100644 src/client/views/search/ToggleBar.tsx (limited to 'src/client/views/SearchItem.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index b3a0fde8d..307f23df1 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -23,7 +23,7 @@ import "./Main.scss"; import { MainOverlayTextBox } from './MainOverlayTextBox'; import { DocumentView } from './nodes/DocumentView'; import { PreviewCursor } from './PreviewCursor'; -import { SearchBox } from './SearchBox'; +import { SearchBox } from './search/SearchBox'; import { SelectionManager } from '../util/SelectionManager'; import { FieldResult, Field, Doc, Opt, DocListCast } from '../../new_fields/Doc'; import { Cast, FieldValue, StrCast, PromiseValue } from '../../new_fields/Types'; diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss deleted file mode 100644 index 91d17d001..000000000 --- a/src/client/views/SearchBox.scss +++ /dev/null @@ -1,135 +0,0 @@ -@import "globalCssVariables"; - -.searchBox-bar { - height: 32px; - display: flex; - justify-content: flex-end; - align-items: center; - padding-left: 2px; - padding-right: 2px; - - .searchBox-input { - width: 130px; - -webkit-transition: width 0.4s; - transition: width 0.4s; - align-self: stretch; - } - - .searchBox-input:focus { - width: 500px; - outline: 3px solid lightblue; - } - - .searchBox-barChild { - flex: 0 1 auto; - margin-left: 2px; - margin-right: 2px; - } - - .searchBox-filter { - align-self: stretch; - } - -} - -.searchBox-results { - margin-left: 27px; //Is there a better way to do this? -} - -.filter-form { - background: $dark-color; - height: 400px; - position: relative; - right: 1px; - color: $light-color; - flex-direction: column; -} - -#filter{ - padding: 25px; - width: 600px; -} - -#header { - text-transform: uppercase; - letter-spacing: 2px; - font-size: 25; - height: 40px; -} - -#option { - height: 20px; -} - -.searchBox-results { - top: 300px; - display: flex; - flex-direction: column; - margin-right: 72px; -} - -.type-of-node{ - height: 50px; - - .icon-bar{ - display: flex; - justify-content: space-evenly; - align-items: center; - height: 40px; - width: 100%; - flex-wrap: wrap; - font-size: 2em; - } - - .type-icon{ - height: 50px; - width: 50px; - color: $light-color; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - background-color: "#121721"; - } - - .fontawesome-icon{ - height: 28px; - width: 28px; - } - - .type-icon:hover{ - background-color: $alt-accent; - } - -} - -.toggle-title{ - display: flex; - align-items: center; - color: $light-color; - text-transform: uppercase; - flex-direction: row; - justify-content: space-around; - padding: 5px; - - .toggle-option{ - width: 100px; - text-align: center; - } -} - -.toggle-bar{ - height: 50px; - background-color: $alt-accent; - border-radius: 10px; - padding: 5px; - display: flex; - align-items: center; - - .toggle-button{ - width: 275px; - height: 100%; - border-radius: 10px; - background-color: $light-color; - } -} \ No newline at end of file diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx deleted file mode 100644 index 812876d14..000000000 --- a/src/client/views/SearchBox.tsx +++ /dev/null @@ -1,449 +0,0 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { observable, action, runInAction } from 'mobx'; -import "./SearchBox.scss"; -import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import * as rp from 'request-promise'; -import { SearchItem } from './SearchItem'; -import { DocServer } from '../DocServer'; -import { Doc } from '../../new_fields/Doc'; -import { Id } from '../../new_fields/FieldSymbols'; -import { SetupDrag } from '../util/DragManager'; -import { Docs, DocTypes } from '../documents/Documents'; -import { RouteStore } from '../../server/RouteStore'; -import { NumCast } from '../../new_fields/Types'; -import { SearchUtil } from '../util/SearchUtil'; -import * as anime from 'animejs'; -import { updateFunction } from '../../new_fields/util'; -import * as _ from "lodash"; -// import "./globalCssVariables.scss"; -import { findDOMNode } from 'react-dom'; - -// import * as anime from '../../../node_modules/@types'; -// const anime = require('lib/anime.js'); -// import anime from 'animejs/lib/anime.es'; -// import anime = require ('lib/anime.min.js'); -// import Anime from 'react-anime'; - -library.add(faSearch); -library.add(faObjectGroup); -library.add(faImage); -library.add(faStickyNote); -library.add(faFilePdf); -library.add(faFilm); -library.add(faMusic); -library.add(faLink); -library.add(faChartBar); -library.add(faGlobeAsia); -library.add(faBan); - -export interface IconBarProps { - updateIcon(newIcons: string[]): void; - getIcons(): string[]; -} - -@observer -export class IconBar extends React.Component { - - @observable newIcons: string[] = []; - - //changes colors of buttons on click - not sure if this is the best method (it probably isn't) - //but i spent a ton of time on it and this is the only thing i could get to work - componentDidMount = () => { - - let buttons = document.querySelectorAll(".type-icon").forEach(node => - node.addEventListener('click', function () { - if (this.style.backgroundColor === "rgb(194, 194, 197)") { - this.style.backgroundColor = "#121721"; - } - else { - this.style.backgroundColor = "#c2c2c5" - } - }) - ); - - } - - onClick = (value: string) => { - let oldIcons = this.props.getIcons() - if (value === DocTypes.NONE) { - this.newIcons = [value]; - //if its none, change the color of all the other circles - document.querySelectorAll(".type-icon").forEach(node => { - if (node.id === "none") { - node.style.backgroundColor = "#c2c2c5"; - } - else { - node.style.backgroundColor = "#121721"; - } - } - ); - } - else { - //turns "none" button off - let noneDoc = document.getElementById(DocTypes.NONE) - if(noneDoc){ - noneDoc.style.backgroundColor = "#121721"; - } - if (oldIcons.includes(value)) { - this.newIcons = _.remove(oldIcons, value); - if (this.newIcons.length === 0) { - this.newIcons = [DocTypes.NONE]; - } - } - else { - this.newIcons = oldIcons; - if (this.newIcons.length === 1 && this.newIcons[0] === DocTypes.NONE) { - this.newIcons = [value] - } - else { this.newIcons.push(value); } - } - } - this.props.updateIcon(this.newIcons) - - } - - render() { - - return ( -
-
-
{ this.onClick(DocTypes.NONE) }}> - -
-
{ this.onClick(DocTypes.PDF) }}> - -
-
{ this.onClick(DocTypes.HIST) }}> - -
-
{ this.onClick(DocTypes.COL) }}> - -
-
{ this.onClick(DocTypes.IMG) }}> - -
-
{ this.onClick(DocTypes.VID) }}> - -
-
{ this.onClick(DocTypes.WEB) }}> - -
-
{ this.onClick(DocTypes.LINK) }}> - -
-
{ this.onClick(DocTypes.AUDIO) }}> - -
-
{ this.onClick(DocTypes.TEXT) }}> - -
-
-
- ) - } -} - -export interface ToggleBarProps { - //false = right, true = left - // status: boolean; - changeStatus(value: boolean): void; - optionOne: string; - optionTwo: string; -} - -//TODO: justify content will align to specific side. Maybe do status passed in and out? -@observer -export class ToggleBar extends React.Component{ - - @observable _status: boolean = false; - @observable timeline: anime.AnimeTimelineInstance; - @observable _toggleButton: React.RefObject; - - constructor(props: ToggleBarProps) { - super(props); - this._toggleButton = React.createRef(); - this.timeline = anime.timeline({ - autoplay: false, - direction: "reverse" - }); - } - - componentDidMount = () => { - - let bar = document.getElementById("toggle-bar"); - let tog = document.getElementById("toggle-button"); - let barwidth = 0; - let togwidth = 0; - if (bar && tog) { - barwidth = bar.clientWidth; - togwidth = tog.clientWidth; - } - let totalWidth = (barwidth - togwidth - 10); - - this.timeline.add({ - targets: this._toggleButton.current, - loop: false, - translateX: totalWidth, - easing: "easeInOutQuad", - duration: 500 - }); - } - - @action.bound - onclick() { - this._status = !this._status; - this.props.changeStatus(this._status); - this.timeline.play(); - this.timeline.reverse(); - } - - render() { - return ( -
-
-
{this.props.optionOne}
-
{this.props.optionTwo}
-
-
-
-
-
- ); - }; -} - - -@observer -export class SearchBox extends React.Component { - @observable _searchString: string = ""; - @observable _wordStatus: boolean = true; - @observable _icons: string[] = ["none"]; - @observable private _open: boolean = false; - @observable private _resultsOpen: boolean = false; - @observable private _results: Doc[] = []; - - @action.bound - onChange(e: React.ChangeEvent) { - this._searchString = e.target.value; - } - - @action - submitSearch = async () => { - let query = this._searchString; - //gets json result into a list of documents that can be used - const results = await this.getResults(query); - - runInAction(() => { - this._resultsOpen = true; - this._results = results; - }); - - } - - @action - getResults = async (query: string) => { - let response = await rp.get(DocServer.prepend('/search'), { - qs: { - query - } - }); - let res: string[] = JSON.parse(response); - const fields = await DocServer.GetRefFields(res); - const docs: Doc[] = []; - for (const id of res) { - const field = fields[id]; - if (field instanceof Doc) { - docs.push(field); - } - } - return docs; - } - - public static async convertDataUri(imageUri: string, returnedFilename: string) { - try { - let posting = DocServer.prepend(RouteStore.dataUriToImage); - const returnedUri = await rp.post(posting, { - body: { - uri: imageUri, - name: returnedFilename - }, - json: true, - }); - return returnedUri; - - } catch (e) { - console.log(e); - } - } - - @action - handleSearchClick = (e: Event): void => { - let element = document.getElementsByClassName((e.target as any).className)[0]; - let name: string = (e.target as any).className; - //handles case with filter button - if (String(name).indexOf("filter") !== -1 || String(name).indexOf("SVG") !== -1) { - this._resultsOpen = false; - this._open = true; - } - else if (element && element.parentElement) { - //if the filter element is found, show the form and hide the results - if (this.findAncestor(element, "filter-form")) { - this._resultsOpen = false; - this._open = true; - } - //if in main search div, keep results open and close filter - else if (this.findAncestor(element, "main-searchDiv")) { - this._resultsOpen = true; - this._open = false; - } - } - //not in either, close both - else { - this._resultsOpen = false; - this._open = false; - } - - } - - //finds ancestor div that matches class name passed in, if not found false returned - findAncestor(curElement: any, cls: string) { - while ((curElement = curElement.parentElement) && !curElement.classList.contains(cls)); - return curElement; - } - - componentWillMount() { - document.addEventListener('mousedown', this.handleSearchClick, false); - } - - componentWillUnmount() { - document.removeEventListener('mousedown', this.handleSearchClick, false); - } - - enter = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - this.submitSearch(); - } - } - - collectionRef = React.createRef(); - startDragCollection = async () => { - const results = await this.getResults(this._searchString); - const docs = results.map(doc => { - const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { - return Doc.MakeDelegate(doc); - } else { - return Doc.MakeAlias(doc); - } - }); - let x = 0; - let y = 0; - for (const doc of docs) { - doc.x = x; - doc.y = y; - const size = 200; - const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1); - if (aspect > 1) { - doc.height = size; - doc.width = size / aspect; - } else if (aspect > 0) { - doc.width = size; - doc.height = size * aspect; - } else { - doc.width = size; - doc.height = size; - } - doc.zoomBasis = 1; - x += 250; - if (x > 1000) { - x = 0; - y += 300; - } - } - return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - } - - @action - getViews = async (doc: Doc) => { - const results = await SearchUtil.GetViewsOfDocument(doc); - let toReturn: Doc[] = []; - await runInAction(() => { - toReturn = results; - }); - return toReturn; - } - - handleWordQueryChange = (value: boolean) => { - this._wordStatus = value; - } - - @action.bound - updateIcon(newArray: string[]) { - this._icons = newArray; - } - - @action.bound - getIcons(): string[] { - return this._icons; - } - - // Useful queries: - // Delegates of a document: {!join from=id to=proto_i}id:{protoId} - // Documents in a collection: {!join from=data_l to=id}id:{collectionProtoId} - render() { - return ( -
-
-
- - - - - -
- {this._resultsOpen ? ( -
- {this._results.map(result => )} -
- ) : undefined} -
- {/* these all need class names in order to find ancestor - please do not delete */} - {this._open ? ( -
- -
-
- -
-
- temp for filtering by a type of node - -
-
- temp for filtering by collection -
-
- temp for filtering where in doc the keywords are found -
-
-
- ) : undefined} -
- ); - } -} \ No newline at end of file diff --git a/src/client/views/SearchItem.scss b/src/client/views/SearchItem.scss deleted file mode 100644 index 4c1d781e3..000000000 --- a/src/client/views/SearchItem.scss +++ /dev/null @@ -1,98 +0,0 @@ -@import "globalCssVariables"; - -.search-item { - width: 500px; - background: $light-color-secondary; - border-color: $intermediate-color; - border-bottom-style: solid; - padding: 10px; - height: 70px; -} - -.search-info { - display: flex; - justify-content: flex-end; - width: 100%; -} - -.main-search-info { - display: flex; - flex-direction: row; - width: 100%; -} - -.search-item:hover { - transition: all 0.2s; - background: $lighter-alt-accent; -} - -.search-title { - text-transform: uppercase; - text-align: left; - width: 8vw; - font-weight: bold; -} - -.link-count { - height: 25px; - width: 25px; - border-radius: 50%; - background: $dark-color; - color: $light-color-secondary; - display: flex; - justify-content: center; - align-items: center; - margin-right: 10px; -} - -.search-type { - width: 25PX; - height: 25PX; - display: flex; - justify-content: center; - align-items: center; -} - - -.searchBox-instances { - float: left; - // opacity: 0; - opacity: 1; - width: 150px; - transition: all 0.2s ease; - color: black; - transform-origin: top right; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); - // -webkit-transform: scale(1); - // -ms-transform: scale(1); - // transform: scale(1); - height: 100% -} - -.collection { - border-color: $darker-alt-accent; - border-bottom-style: solid; -} - -.search-overview { - display: flex; - flex-direction: row-reverse; - justify-content: flex-end; - height: 70px; -} - -.parents { - background: $lighter-alt-accent; - padding: 10px; -} - -.search-item:hover~.searchBox-instances, -.searchBox-instances:hover, .searchBox-instances:active{ - opacity: 1; - background: $lighter-alt-accent; - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); -} \ No newline at end of file diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx deleted file mode 100644 index acb7eeac4..000000000 --- a/src/client/views/SearchItem.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React = require("react"); -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast, NumCast } from "../../new_fields/Types"; -import { observable, runInAction } from "mobx"; -import { listSpec } from "../../new_fields/Schema"; -import { Doc } from "../../new_fields/Doc"; -import { DocumentManager } from "../util/DocumentManager"; -import { SetupDrag } from "../util/DragManager"; -import { SearchUtil } from "../util/SearchUtil"; -import { Id } from "../../new_fields/FieldSymbols"; -import { CollectionDockingView } from "./collections/CollectionDockingView"; -import { observer } from "mobx-react"; -import "./SearchItem.scss"; -import { CollectionViewType } from "./collections/CollectionBaseView"; -import { DocTypes } from "../documents/Documents"; - -export interface SearchItemProps { - doc: Doc; -} - -library.add(faCaretUp); -library.add(faObjectGroup); -library.add(faStickyNote); -library.add(faFilePdf); -library.add(faFilm); -library.add(faMusic); -library.add(faLink); -library.add(faChartBar); -library.add(faGlobeAsia); - -@observer -export class SelectorContextMenu extends React.Component { - @observable private _docs: { col: Doc, target: Doc }[] = []; - @observable private _otherDocs: { col: Doc, target: Doc }[] = []; - - constructor(props: SearchItemProps) { - super(props); - - this.fetchDocuments(); - } - - async fetchDocuments() { - let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); - const docs = await SearchUtil.Search(`data_l:"${this.props.doc[Id]}"`, true); - const map: Map = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search(`data_l:"${doc[Id]}"`, true))); - allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); - docs.forEach(doc => map.delete(doc)); - runInAction(() => { - this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.doc })); - this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); - }); - } - - getOnClick({ col, target }: { col: Doc, target: Doc }) { - return () => { - col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; - if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; - const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; - col.panX = newPanX; - col.panY = newPanY; - } - CollectionDockingView.Instance.AddRightSplit(col); - }; - } - - //these all need class names in order to find ancestor - please do not delete - render() { - return ( - < div className="parents"> -

Contexts:

- {this._docs.map(doc => )} - {this._otherDocs.map(doc => )} -
- ); - } -} - -@observer -export class SearchItem extends React.Component { - - @observable _selected: boolean = false; - @observable hover = false; - - onClick = () => { - // DocumentManager.Instance.jumpToDocument(this.props.doc); - CollectionDockingView.Instance.AddRightSplit(this.props.doc); - } - - public DocumentIcon() { - let layoutresult = Cast(this.props.doc.type, "string", ""); - - let button = layoutresult.indexOf(DocTypes.PDF) !== -1 ? faFilePdf : - layoutresult.indexOf(DocTypes.IMG) !== -1 ? faImage : - layoutresult.indexOf(DocTypes.TEXT) !== -1 ? faStickyNote : - layoutresult.indexOf(DocTypes.VID) !== -1 ? faFilm : - layoutresult.indexOf(DocTypes.COL) !== -1 ? faObjectGroup : - layoutresult.indexOf(DocTypes.AUDIO) !== -1 ? faMusic : - layoutresult.indexOf(DocTypes.LINK) !== -1 ? faLink : - layoutresult.indexOf(DocTypes.HIST) !== -1 ? faChartBar : - layoutresult.indexOf(DocTypes.WEB) !== -1 ? faGlobeAsia : - faCaretUp; - return ; - } - - collectionRef = React.createRef(); - startDocDrag = () => { - let doc = this.props.doc; - const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { - return Doc.MakeDelegate(doc); - } else { - return Doc.MakeAlias(doc); - } - } - - linkCount = () => { - return Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length + Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; - } - - render() { - return ( -
-
-
-
{this.props.doc.title}
-
-
{this.linkCount()}
-
{this.DocumentIcon()}
-
-
-
Where Found: (i.e. title, body, etc)
-
-
- -
-
- ); - } -} \ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 7853544d5..c1a6ca44e 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -12,7 +12,7 @@ import { Id } from "../../../new_fields/FieldSymbols"; import { VideoBox } from "../nodes/VideoBox"; import { NumCast, Cast, StrCast } from "../../../new_fields/Types"; import { VideoField } from "../../../new_fields/URLField"; -import { SearchBox } from "../SearchBox"; +import { SearchBox } from "../search/SearchBox"; import { DocServer } from "../../DocServer"; import { Docs, DocUtils } from "../../documents/Documents"; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 9ec941eff..658f18f6a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -14,7 +14,7 @@ import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; import { InkingCanvas } from "../../InkingCanvas"; import { PreviewCursor } from "../../PreviewCursor"; -import { SearchBox } from "../../SearchBox"; +import { SearchBox } from "../../search/SearchBox"; import { Templates } from "../../Templates"; import { CollectionViewType } from "../CollectionBaseView"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index aa29a7170..b1fd54df1 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -15,7 +15,7 @@ import { Utils } from '../../../Utils'; import { DocServer } from "../../DocServer"; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; -import { SearchBox } from "../SearchBox"; +import { SearchBox } from "../search/SearchBox"; import { Annotation } from './Annotation'; import { positionSchema } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss new file mode 100644 index 000000000..91d17d001 --- /dev/null +++ b/src/client/views/search/SearchBox.scss @@ -0,0 +1,135 @@ +@import "globalCssVariables"; + +.searchBox-bar { + height: 32px; + display: flex; + justify-content: flex-end; + align-items: center; + padding-left: 2px; + padding-right: 2px; + + .searchBox-input { + width: 130px; + -webkit-transition: width 0.4s; + transition: width 0.4s; + align-self: stretch; + } + + .searchBox-input:focus { + width: 500px; + outline: 3px solid lightblue; + } + + .searchBox-barChild { + flex: 0 1 auto; + margin-left: 2px; + margin-right: 2px; + } + + .searchBox-filter { + align-self: stretch; + } + +} + +.searchBox-results { + margin-left: 27px; //Is there a better way to do this? +} + +.filter-form { + background: $dark-color; + height: 400px; + position: relative; + right: 1px; + color: $light-color; + flex-direction: column; +} + +#filter{ + padding: 25px; + width: 600px; +} + +#header { + text-transform: uppercase; + letter-spacing: 2px; + font-size: 25; + height: 40px; +} + +#option { + height: 20px; +} + +.searchBox-results { + top: 300px; + display: flex; + flex-direction: column; + margin-right: 72px; +} + +.type-of-node{ + height: 50px; + + .icon-bar{ + display: flex; + justify-content: space-evenly; + align-items: center; + height: 40px; + width: 100%; + flex-wrap: wrap; + font-size: 2em; + } + + .type-icon{ + height: 50px; + width: 50px; + color: $light-color; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + background-color: "#121721"; + } + + .fontawesome-icon{ + height: 28px; + width: 28px; + } + + .type-icon:hover{ + background-color: $alt-accent; + } + +} + +.toggle-title{ + display: flex; + align-items: center; + color: $light-color; + text-transform: uppercase; + flex-direction: row; + justify-content: space-around; + padding: 5px; + + .toggle-option{ + width: 100px; + text-align: center; + } +} + +.toggle-bar{ + height: 50px; + background-color: $alt-accent; + border-radius: 10px; + padding: 5px; + display: flex; + align-items: center; + + .toggle-button{ + width: 275px; + height: 100%; + border-radius: 10px; + background-color: $light-color; + } +} \ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx new file mode 100644 index 000000000..0dd32d4fa --- /dev/null +++ b/src/client/views/search/SearchBox.tsx @@ -0,0 +1,382 @@ +import * as React from 'react'; +import { observer } from 'mobx-react'; +import { observable, action, runInAction } from 'mobx'; +import "./SearchBox.scss"; +import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import * as rp from 'request-promise'; +import { SearchItem } from './SearchItem'; +import { DocServer } from '../../DocServer'; +import { Doc } from '../../../new_fields/Doc'; +import { Id } from '../../../new_fields/FieldSymbols'; +import { SetupDrag } from '../../util/DragManager'; +import { Docs, DocTypes } from '../../documents/Documents'; +import { RouteStore } from '../../../server/RouteStore'; +import { NumCast } from '../../../new_fields/Types'; +import { SearchUtil } from '../../util/SearchUtil'; +import * as anime from 'animejs'; +import { updateFunction } from '../../../new_fields/util'; +import * as _ from "lodash"; +// import "./globalCssVariables.scss"; +import { findDOMNode } from 'react-dom'; +import { ToggleBar } from './ToggleBar'; + +// import * as anime from '../../../node_modules/@types'; +// const anime = require('lib/anime.js'); +// import anime from 'animejs/lib/anime.es'; +// import anime = require ('lib/anime.min.js'); +// import Anime from 'react-anime'; + +library.add(faSearch); +library.add(faObjectGroup); +library.add(faImage); +library.add(faStickyNote); +library.add(faFilePdf); +library.add(faFilm); +library.add(faMusic); +library.add(faLink); +library.add(faChartBar); +library.add(faGlobeAsia); +library.add(faBan); + +export interface IconBarProps { + updateIcon(newIcons: string[]): void; + getIcons(): string[]; +} + +@observer +export class IconBar extends React.Component { + + @observable newIcons: string[] = []; + + //changes colors of buttons on click - not sure if this is the best method (it probably isn't) + //but i spent a ton of time on it and this is the only thing i could get to work + componentDidMount = () => { + + let buttons = document.querySelectorAll(".type-icon").forEach(node => + node.addEventListener('click', function () { + if (this.style.backgroundColor === "rgb(194, 194, 197)") { + this.style.backgroundColor = "#121721"; + } + else { + this.style.backgroundColor = "#c2c2c5" + } + }) + ); + + } + + onClick = (value: string) => { + let oldIcons = this.props.getIcons() + if (value === DocTypes.NONE) { + this.newIcons = [value]; + //if its none, change the color of all the other circles + document.querySelectorAll(".type-icon").forEach(node => { + if (node.id === "none") { + node.style.backgroundColor = "#c2c2c5"; + } + else { + node.style.backgroundColor = "#121721"; + } + } + ); + } + else { + //turns "none" button off + let noneDoc = document.getElementById(DocTypes.NONE) + if (noneDoc) { + noneDoc.style.backgroundColor = "#121721"; + } + if (oldIcons.includes(value)) { + this.newIcons = _.remove(oldIcons, value); + if (this.newIcons.length === 0) { + this.newIcons = [DocTypes.NONE]; + } + } + else { + this.newIcons = oldIcons; + if (this.newIcons.length === 1 && this.newIcons[0] === DocTypes.NONE) { + this.newIcons = [value] + } + else { this.newIcons.push(value); } + } + } + this.props.updateIcon(this.newIcons) + + } + + render() { + + return ( +
+
+
{ this.onClick(DocTypes.NONE) }}> + +
+
{ this.onClick(DocTypes.PDF) }}> + +
+
{ this.onClick(DocTypes.HIST) }}> + +
+
{ this.onClick(DocTypes.COL) }}> + +
+
{ this.onClick(DocTypes.IMG) }}> + +
+
{ this.onClick(DocTypes.VID) }}> + +
+
{ this.onClick(DocTypes.WEB) }}> + +
+
{ this.onClick(DocTypes.LINK) }}> + +
+
{ this.onClick(DocTypes.AUDIO) }}> + +
+
{ this.onClick(DocTypes.TEXT) }}> + +
+
+
+ ) + } +} + + + +@observer +export class SearchBox extends React.Component { + @observable _searchString: string = ""; + @observable _wordStatus: boolean = true; + @observable _icons: string[] = ["none"]; + @observable private _open: boolean = false; + @observable private _resultsOpen: boolean = false; + @observable private _results: Doc[] = []; + + @action.bound + onChange(e: React.ChangeEvent) { + this._searchString = e.target.value; + } + + @action + submitSearch = async () => { + let query = this._searchString; + //gets json result into a list of documents that can be used + const results = await this.getResults(query); + + runInAction(() => { + this._resultsOpen = true; + this._results = results; + }); + + } + + @action + getResults = async (query: string) => { + let response = await rp.get(DocServer.prepend('/search'), { + qs: { + query + } + }); + let res: string[] = JSON.parse(response); + const fields = await DocServer.GetRefFields(res); + const docs: Doc[] = []; + for (const id of res) { + const field = fields[id]; + if (field instanceof Doc) { + docs.push(field); + } + } + return docs; + } + + public static async convertDataUri(imageUri: string, returnedFilename: string) { + try { + let posting = DocServer.prepend(RouteStore.dataUriToImage); + const returnedUri = await rp.post(posting, { + body: { + uri: imageUri, + name: returnedFilename + }, + json: true, + }); + return returnedUri; + + } catch (e) { + console.log(e); + } + } + + @action + handleSearchClick = (e: Event): void => { + let element = document.getElementsByClassName((e.target as any).className)[0]; + let name: string = (e.target as any).className; + //handles case with filter button + if (String(name).indexOf("filter") !== -1 || String(name).indexOf("SVG") !== -1) { + this._resultsOpen = false; + this._open = true; + } + else if (element && element.parentElement) { + //if the filter element is found, show the form and hide the results + if (this.findAncestor(element, "filter-form")) { + this._resultsOpen = false; + this._open = true; + } + //if in main search div, keep results open and close filter + else if (this.findAncestor(element, "main-searchDiv")) { + this._resultsOpen = true; + this._open = false; + } + } + //not in either, close both + else { + this._resultsOpen = false; + this._open = false; + } + + } + + //finds ancestor div that matches class name passed in, if not found false returned + findAncestor(curElement: any, cls: string) { + while ((curElement = curElement.parentElement) && !curElement.classList.contains(cls)); + return curElement; + } + + componentWillMount() { + document.addEventListener('mousedown', this.handleSearchClick, false); + } + + componentWillUnmount() { + document.removeEventListener('mousedown', this.handleSearchClick, false); + } + + enter = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + this.submitSearch(); + } + } + + collectionRef = React.createRef(); + startDragCollection = async () => { + const results = await this.getResults(this._searchString); + const docs = results.map(doc => { + const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); + if (isProto) { + return Doc.MakeDelegate(doc); + } else { + return Doc.MakeAlias(doc); + } + }); + let x = 0; + let y = 0; + for (const doc of docs) { + doc.x = x; + doc.y = y; + const size = 200; + const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1); + if (aspect > 1) { + doc.height = size; + doc.width = size / aspect; + } else if (aspect > 0) { + doc.width = size; + doc.height = size * aspect; + } else { + doc.width = size; + doc.height = size; + } + doc.zoomBasis = 1; + x += 250; + if (x > 1000) { + x = 0; + y += 300; + } + } + return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + } + + @action + getViews = async (doc: Doc) => { + const results = await SearchUtil.GetViewsOfDocument(doc); + let toReturn: Doc[] = []; + await runInAction(() => { + toReturn = results; + }); + return toReturn; + } + + handleWordQueryChange = (value: boolean) => { + this._wordStatus = value; + } + + @action.bound + updateIcon(newArray: string[]) { + this._icons = newArray; + } + + @action.bound + getIcons(): string[] { + return this._icons; + } + + // Useful queries: + // Delegates of a document: {!join from=id to=proto_i}id:{protoId} + // Documents in a collection: {!join from=data_l to=id}id:{collectionProtoId} + render() { + return ( +
+
+
+ + + + + +
+ {this._resultsOpen ? ( +
+ {this._results.map(result => )} +
+ ) : undefined} +
+ {/* these all need class names in order to find ancestor - please do not delete */} + {this._open ? ( +
+ +
+
+ +
+
+ temp for filtering by a type of node + +
+
+ temp for filtering by collection +
+
+ temp for filtering where in doc the keywords are found +
+
+
+ ) : undefined} +
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss new file mode 100644 index 000000000..4c90643f9 --- /dev/null +++ b/src/client/views/search/SearchItem.scss @@ -0,0 +1,98 @@ +@import "././globalCssVariables"; + +.search-item { + width: 500px; + background: $light-color-secondary; + border-color: $intermediate-color; + border-bottom-style: solid; + padding: 10px; + height: 70px; +} + +.search-info { + display: flex; + justify-content: flex-end; + width: 100%; +} + +.main-search-info { + display: flex; + flex-direction: row; + width: 100%; +} + +.search-item:hover { + transition: all 0.2s; + background: $lighter-alt-accent; +} + +.search-title { + text-transform: uppercase; + text-align: left; + width: 8vw; + font-weight: bold; +} + +.link-count { + height: 25px; + width: 25px; + border-radius: 50%; + background: $dark-color; + color: $light-color-secondary; + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; +} + +.search-type { + width: 25PX; + height: 25PX; + display: flex; + justify-content: center; + align-items: center; +} + + +.searchBox-instances { + float: left; + // opacity: 0; + opacity: 1; + width: 150px; + transition: all 0.2s ease; + color: black; + transform-origin: top right; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + // -webkit-transform: scale(1); + // -ms-transform: scale(1); + // transform: scale(1); + height: 100% +} + +.collection { + border-color: $darker-alt-accent; + border-bottom-style: solid; +} + +.search-overview { + display: flex; + flex-direction: row-reverse; + justify-content: flex-end; + height: 70px; +} + +.parents { + background: $lighter-alt-accent; + padding: 10px; +} + +.search-item:hover~.searchBox-instances, +.searchBox-instances:hover, .searchBox-instances:active{ + opacity: 1; + background: $lighter-alt-accent; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} \ No newline at end of file diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx new file mode 100644 index 000000000..9b4170f4c --- /dev/null +++ b/src/client/views/search/SearchItem.tsx @@ -0,0 +1,143 @@ +import React = require("react"); +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Cast, NumCast } from "../../../new_fields/Types"; +import { observable, runInAction } from "mobx"; +import { listSpec } from "../../../new_fields/Schema"; +import { Doc } from "../../../new_fields/Doc"; +import { DocumentManager } from "../../util/DocumentManager"; +import { SetupDrag } from "../../util/DragManager"; +import { SearchUtil } from "../../util/SearchUtil"; +import { Id } from "../../../new_fields/FieldSymbols"; +import { CollectionDockingView } from "../collections/CollectionDockingView"; +import { observer } from "mobx-react"; +import "./SearchItem.scss"; +import { CollectionViewType } from "../collections/CollectionBaseView"; +import { DocTypes } from "../../documents/Documents"; + +export interface SearchItemProps { + doc: Doc; +} + +library.add(faCaretUp); +library.add(faObjectGroup); +library.add(faStickyNote); +library.add(faFilePdf); +library.add(faFilm); +library.add(faMusic); +library.add(faLink); +library.add(faChartBar); +library.add(faGlobeAsia); + +@observer +export class SelectorContextMenu extends React.Component { + @observable private _docs: { col: Doc, target: Doc }[] = []; + @observable private _otherDocs: { col: Doc, target: Doc }[] = []; + + constructor(props: SearchItemProps) { + super(props); + + this.fetchDocuments(); + } + + async fetchDocuments() { + let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); + const docs = await SearchUtil.Search(`data_l:"${this.props.doc[Id]}"`, true); + const map: Map = new Map; + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search(`data_l:"${doc[Id]}"`, true))); + allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); + docs.forEach(doc => map.delete(doc)); + runInAction(() => { + this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.doc })); + this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); + }); + } + + getOnClick({ col, target }: { col: Doc, target: Doc }) { + return () => { + col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; + if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { + const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; + const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; + col.panX = newPanX; + col.panY = newPanY; + } + CollectionDockingView.Instance.AddRightSplit(col); + }; + } + + //these all need class names in order to find ancestor - please do not delete + render() { + return ( + < div className="parents"> +

Contexts:

+ {this._docs.map(doc => )} + {this._otherDocs.map(doc => )} +
+ ); + } +} + +@observer +export class SearchItem extends React.Component { + + @observable _selected: boolean = false; + @observable hover = false; + + onClick = () => { + // DocumentManager.Instance.jumpToDocument(this.props.doc); + CollectionDockingView.Instance.AddRightSplit(this.props.doc); + } + + public DocumentIcon() { + let layoutresult = Cast(this.props.doc.type, "string", ""); + + let button = layoutresult.indexOf(DocTypes.PDF) !== -1 ? faFilePdf : + layoutresult.indexOf(DocTypes.IMG) !== -1 ? faImage : + layoutresult.indexOf(DocTypes.TEXT) !== -1 ? faStickyNote : + layoutresult.indexOf(DocTypes.VID) !== -1 ? faFilm : + layoutresult.indexOf(DocTypes.COL) !== -1 ? faObjectGroup : + layoutresult.indexOf(DocTypes.AUDIO) !== -1 ? faMusic : + layoutresult.indexOf(DocTypes.LINK) !== -1 ? faLink : + layoutresult.indexOf(DocTypes.HIST) !== -1 ? faChartBar : + layoutresult.indexOf(DocTypes.WEB) !== -1 ? faGlobeAsia : + faCaretUp; + return ; + } + + collectionRef = React.createRef(); + startDocDrag = () => { + let doc = this.props.doc; + const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); + if (isProto) { + return Doc.MakeDelegate(doc); + } else { + return Doc.MakeAlias(doc); + } + } + + linkCount = () => { + return Cast(this.props.doc.linkedToDocs, listSpec(Doc), []).length + Cast(this.props.doc.linkedFromDocs, listSpec(Doc), []).length; + } + + render() { + return ( +
+
+
+
{this.props.doc.title}
+
+
{this.linkCount()}
+
{this.DocumentIcon()}
+
+
+
Where Found: (i.e. title, body, etc)
+
+
+ +
+
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/search/ToggleBar.scss b/src/client/views/search/ToggleBar.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/client/views/search/ToggleBar.tsx b/src/client/views/search/ToggleBar.tsx new file mode 100644 index 000000000..74aa5dd9a --- /dev/null +++ b/src/client/views/search/ToggleBar.tsx @@ -0,0 +1,74 @@ +import * as React from 'react'; +import { observer } from 'mobx-react'; +import { observable, action, runInAction } from 'mobx'; +import "./SearchBox.scss"; +import * as anime from 'animejs'; + +export interface ToggleBarProps { + //false = right, true = left + // status: boolean; + changeStatus(value: boolean): void; + optionOne: string; + optionTwo: string; +} + +//TODO: justify content will align to specific side. Maybe do status passed in and out? +@observer +export class ToggleBar extends React.Component{ + + @observable _status: boolean = false; + @observable timeline: anime.AnimeTimelineInstance; + @observable _toggleButton: React.RefObject; + + constructor(props: ToggleBarProps) { + super(props); + this._toggleButton = React.createRef(); + this.timeline = anime.timeline({ + autoplay: false, + direction: "reverse" + }); + } + + componentDidMount = () => { + + let bar = document.getElementById("toggle-bar"); + let tog = document.getElementById("toggle-button"); + let barwidth = 0; + let togwidth = 0; + if (bar && tog) { + barwidth = bar.clientWidth; + togwidth = tog.clientWidth; + } + let totalWidth = (barwidth - togwidth - 10); + + this.timeline.add({ + targets: this._toggleButton.current, + loop: false, + translateX: totalWidth, + easing: "easeInOutQuad", + duration: 500 + }); + } + + @action.bound + onclick() { + this._status = !this._status; + this.props.changeStatus(this._status); + this.timeline.play(); + this.timeline.reverse(); + } + + render() { + return ( +
+
+
{this.props.optionOne}
+
{this.props.optionTwo}
+
+
+
+
+
+ ); + }; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2