import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocCastAsync } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero, returnEmptyString, returnEmptyFilter } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager, SetupDrag } from "../../util/DragManager"; import { SearchUtil } from "../../util/SearchUtil"; import { Transform } from "../../util/Transform"; import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionViewType, CollectionView } from "../collections/CollectionView"; import { ParentDocSelector } from "../collections/ParentDocumentSelector"; import { ContextMenu } from "../ContextMenu"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; import { SearchBox } from "./SearchBox"; import "./SearchItem.scss"; import "./SelectorContextMenu.scss"; import { FieldViewProps, FieldView } from "../nodes/FieldView"; import { ViewBoxBaseComponent } from "../DocComponent"; import { makeInterface, createSchema, listSpec } from "../../../fields/Schema"; import { documentSchema } from "../../../fields/documentSchemas"; import { PrefetchProxy } from "../../../fields/Proxy"; import { Docs } from "../../documents/Documents"; import { ScriptField } from "../../../fields/ScriptField"; import { CollectionStackingView } from "../collections/CollectionStackingView"; export interface SearchItemProps { doc: Doc; query: string; highlighting: string[]; lines: string[]; } library.add(faCaretUp); library.add(faObjectGroup); library.add(faStickyNote); library.add(faFile); library.add(faFilePdf); library.add(faFilm); library.add(faMusic); library.add(faLink); library.add(faChartBar); library.add(faGlobeAsia, faFingerprint); @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() { const aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.doc[Id]}"` }); const map: Map = new Map; const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs))); 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 (col._viewType === CollectionViewType.Freeform) { const newPanX = NumCast(target.x) + NumCast(target._width) / 2; const newPanY = NumCast(target.y) + NumCast(target._height) / 2; col._panX = newPanX; col._panY = newPanY; } CollectionDockingView.AddRightSplit(col); }; } render() { return (

Contexts:

{[...this._docs, ...this._otherDocs].map(doc => { const item = React.createRef(); return
doc.col, undefined, undefined, () => SearchBox.Instance.closeSearch())}>
{doc.col.title}
; })}
); } } export interface LinkMenuProps { doc1: Doc; doc2: Doc; } @observer export class LinkContextMenu extends React.Component { highlightDoc = (doc: Doc) => () => Doc.BrushDoc(doc); unHighlightDoc = (doc: Doc) => () => Doc.UnBrushDoc(doc); getOnClick = (col: Doc) => () => CollectionDockingView.AddRightSplit(col); render() { return (

Anchors:

Doc 1: {this.props.doc2.title}
Doc 2: {this.props.doc1.title}
); } } type SearchSchema = makeInterface<[typeof documentSchema]>; export const SearchSchema = createSchema({ targetDoc: Doc, }); const SearchDocument = makeInterface(documentSchema); @observer export class SearchItem extends ViewBoxBaseComponent(SearchDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchItem, fieldKey); } constructor(props:any){ super(props); //this.rootDoc._viewType= CollectionViewType.Stacking; this.props.Document._height=46; if (!this.searchItemTemplate) { // create exactly one presElmentBox template to use by any and all presentations. Doc.UserDoc().searchItemTemplate = new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" })); // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data // stored on each pres element. (this.searchItemTemplate as Doc).lookupField = ScriptField.MakeFunction("lookupSearchBoxField(container, field, data)", { field: "string", data: Doc.name, container: Doc.name }); } } @observable _selected: boolean = false; onClick = () => { DocumentManager.Instance.jumpToDocument(this.rootDoc, false); } @observable _useIcons = true; @observable _displayDim = 50; @computed get query() { return StrCast(this.lookupField("query")); } private _oldHeight: number = 46; componentDidMount() { let parent: Doc |undefined = undefined; let height = 0; if (this.rootDoc.parent){ parent = Cast(this.rootDoc.parent, Doc, null); if (parent!== undefined){ height=(NumCast(parent._height)); } } this._reactionDisposer2 = reaction( () => this._useIcons, el=> { if (this.rootDoc.parent){ parent = Cast(this.rootDoc.parent, Doc, null) as Doc; height=(NumCast(parent._height)); }; console.log(height); console.log(this._oldHeight); setTimeout(() =>{this._mainRef.current?.getBoundingClientRect()? this.props.Document._height= this._mainRef.current?.getBoundingClientRect().height : null; parent!==undefined? this._mainRef.current?.getBoundingClientRect()? parent._height= -this._oldHeight + height +this._mainRef.current?.getBoundingClientRect().height : null: null; this._mainRef.current?.getBoundingClientRect()? this._oldHeight= this._mainRef.current?.getBoundingClientRect().height : null; // this._oldHeight 55? this._oldHeight =55:null; }, 1); } ); this._reactionDisposer3 = reaction( () => this._displayLines, el=> { if (this.rootDoc.parent){ parent = Cast(this.rootDoc.parent, Doc, null) as Doc; height=(NumCast(parent._height)); }; setTimeout(() =>{this._mainRef.current?.getBoundingClientRect()? this.props.Document._height= this._mainRef.current?.getBoundingClientRect().height : null; parent!==undefined? this._mainRef.current?.getBoundingClientRect()? parent._height= -this._oldHeight + height +this._mainRef.current?.getBoundingClientRect().height : null: null; this._mainRef.current?.getBoundingClientRect()? this._oldHeight= this._mainRef.current?.getBoundingClientRect().height : null; }, 1); } ); Doc.SetSearchQuery(this.query); this.rootDoc.searchMatch = true; } componentWillUnmount() { this.rootDoc.searchMatch = undefined; this._reactionDisposer2 && this._reactionDisposer2(); this._reactionDisposer3 && this._reactionDisposer3(); } private _reactionDisposer2?: IReactionDisposer; private _reactionDisposer3?: IReactionDisposer; @computed get highlightPos(){return NumCast(this.rootDoc.searchIndex)} @action public DocumentIcon() { const layoutresult = StrCast(this.rootDoc.type); if (!this._useIcons) { const returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); const returnYDimension = () => this._displayDim; const docview =
{ this._useIcons = !this._useIcons; this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); })} onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} >
; return docview; } const button = layoutresult.indexOf(DocumentType.PDF) !== -1 ? faFilePdf : layoutresult.indexOf(DocumentType.IMG) !== -1 ? faImage : layoutresult.indexOf(DocumentType.RTF) !== -1 ? faStickyNote : layoutresult.indexOf(DocumentType.VID) !== -1 ? faFilm : layoutresult.indexOf(DocumentType.COL) !== -1 ? faObjectGroup : layoutresult.indexOf(DocumentType.AUDIO) !== -1 ? faMusic : layoutresult.indexOf(DocumentType.LINK) !== -1 ? faLink : layoutresult.indexOf(DocumentType.WEB) !== -1 ? faGlobeAsia : faCaretUp; return
{ this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
{this.rootDoc.type ? this.rootDoc.type : "Other"}
; } collectionRef = React.createRef(); @action pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); } @action nextHighlight = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); //e.button === 0 && SearchBox.Instance.openSearch(e); this.rootDoc!.searchMatch = false; setTimeout(() => this.rootDoc!.searchMatch = true, 0); this.rootDoc.searchIndex=NumCast(this.rootDoc.searchIndex); this.length=NumCast(this.rootDoc!.length); } @action nextHighlight2 = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); //e.button === 0 && SearchBox.Instance.openSearch(e); this.rootDoc!.searchMatch2 = false; setTimeout(() => this.rootDoc!.searchMatch2 = true, 0); this.rootDoc.searchIndex=NumCast(this.rootDoc.searchIndex); this.length=NumCast(this.rootDoc!.length); } @observable length:number|undefined = 0; highlightDoc = (e: React.PointerEvent) => { if (this.rootDoc!.type === DocumentType.LINK) { if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) { const doc1 = Cast(this.rootDoc!.anchor1, Doc, null); const doc2 = Cast(this.rootDoc!.anchor2, Doc, null); Doc.BrushDoc(doc1); Doc.BrushDoc(doc2); } } else { Doc.BrushDoc(this.rootDoc!); } e.stopPropagation(); } unHighlightDoc = (e: React.PointerEvent) => { if (this.rootDoc!.type === DocumentType.LINK) { if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) { const doc1 = Cast(this.rootDoc!.anchor1, Doc, null); const doc2 = Cast(this.rootDoc!.anchor2, Doc, null); Doc.UnBrushDoc(doc1); Doc.UnBrushDoc(doc2); } } else { Doc.UnBrushDoc(this.rootDoc!); } } onContextMenu = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); ContextMenu.Instance.clearItems(); ContextMenu.Instance.addItem({ description: "Copy ID", event: () => { Utils.CopyText(StrCast(this.rootDoc[Id])); }, icon: "fingerprint" }); ContextMenu.Instance.displayMenu(e.clientX, e.clientY); } _downX = 0; _downY = 0; _target: any; onPointerDown = (e: React.PointerEvent) => { this._downX = e.clientX; this._downY = e.clientY; e.stopPropagation(); this._target = e.currentTarget; document.removeEventListener("pointermove", this.onPointerMoved); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMoved); document.addEventListener("pointerup", this.onPointerUp); } onPointerMoved = (e: PointerEvent) => { if (Math.abs(e.clientX - this._downX) > Utils.DRAG_THRESHOLD || Math.abs(e.clientY - this._downY) > Utils.DRAG_THRESHOLD) { document.removeEventListener("pointermove", this.onPointerMoved); document.removeEventListener("pointerup", this.onPointerUp); const doc = Doc.IsPrototype(this.rootDoc) ? Doc.MakeDelegate(this.rootDoc) : this.rootDoc; DragManager.StartDocumentDrag([this._target], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); } } onPointerUp = (e: PointerEvent) => { document.removeEventListener("pointermove", this.onPointerMoved); document.removeEventListener("pointerup", this.onPointerUp); } @computed get contextButton() { return CollectionDockingView.AddRightSplit(doc)} />; } @computed get searchElementDoc() { return this.rootDoc; } // @computed get targetDoc() { return this.searchElementDoc?.targetDoc as Doc; } @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); } childLayoutTemplate = () => this.layoutDoc._viewType === CollectionViewType.Stacking ? this.searchItemTemplate: undefined; getTransform = () => { return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight } panelHeight = () => { return this.props.PanelHeight(); } selectElement = (doc: Doc) => { //this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.layoutDoc._itemIndex)); } newsearch(){ runInAction(()=>{ if (StrCast(this.rootDoc.bucketfield)!=="results"){ SearchBox.Instance._icons=[StrCast(this.rootDoc.bucketfield)]; SearchBox.Instance._icons=SearchBox.Instance._icons; } else{ SearchBox.Instance._icons=SearchBox.Instance._allIcons; } SearchBox.Instance.expandedBucket= true; SearchBox.Instance.submitSearch(); }) } @action returnLines(){ if ((Cast(this.rootDoc.lines, listSpec("string")))!.length>1){ if (!this._displayLines) { console.log(Cast(this.rootDoc.lines, listSpec("string"))); return
{ this._displayLines = !this._displayLines; //this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); })} //onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} > {Cast(this.rootDoc.lines, listSpec("string"))!.filter((m, i) => i).map((l, i) =>
{l}
)}
;; } } } //this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); @observable _displayLines: boolean = true; returnButtons(){ return
{ this.rootDoc!.type === DocumentType.PDF? this._displayLines = !this._displayLines : null; })}> {this.rootDoc!.type === DocumentType.PDF?"Expand Lines": null} {NumCast(this.rootDoc!.length)>1?`Instance ${NumCast(this.rootDoc.searchIndex)===0? NumCast(this.rootDoc.length):NumCast(this.rootDoc.searchIndex) } of ${NumCast(this.rootDoc.length)}`: null}
{this.returnLines()}
} private _mainRef: React.RefObject = React.createRef(); render() { const doc1 = Cast(this.rootDoc!.anchor1, Doc); const doc2 = Cast(this.rootDoc!.anchor2, Doc); if (StrCast(this.rootDoc.bucketfield)==="webs"){ this.props.Document._viewType=CollectionViewType.Stacking; this.props.Document._chromeStatus='disabled'; this.props.Document._height=this.rootDoc._height; return
} if (this.rootDoc.isBucket === true){ this.props.Document._viewType=CollectionViewType.Stacking; this.props.Document._chromeStatus='disabled'; this.props.Document._height=this.rootDoc._height; return
} else if (this.rootDoc.isBucket === false){ this.props.Document._chromeStatus='disabled'; return
No Search Results
} else { return
{StrCast(this.rootDoc.title)}
{this.rootDoc.highlighting? StrCast(this.rootDoc.highlighting).length ? "Matched fields:" + StrCast(this.rootDoc.highlighting) : Cast(this.rootDoc.lines, listSpec("string"))!.length ? Cast(this.rootDoc.lines, listSpec("string"))![0] : "":null}
{NumCast(this.rootDoc.length) > 1 || this.rootDoc!.type === DocumentType.PDF?this.returnButtons(): null}
{this.DocumentIcon()}
{/*
{(doc1 instanceof Doc && doc2 instanceof Doc) && this.rootDoc!.type === DocumentType.LINK ? : this.contextButton}
*/}
; } } }