diff options
author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-05-13 02:09:08 -0400 |
---|---|---|
committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-05-13 02:09:08 -0400 |
commit | 2767d6b439dd9e90543f955c68e521e03c690af0 (patch) | |
tree | 63a912270dc6dc9ba71db4aa4691d7f2839f3b70 | |
parent | f52f5a408c62b93ae79eb690ff86538a6fbf60ed (diff) |
Added "find aliases" and "see collections that contain me"
-rw-r--r-- | src/client/util/SearchUtil.ts | 25 | ||||
-rw-r--r-- | src/client/views/collections/ParentDocumentSelector.tsx | 31 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 27 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 4 |
4 files changed, 73 insertions, 14 deletions
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts new file mode 100644 index 000000000..4ccff0d1b --- /dev/null +++ b/src/client/util/SearchUtil.ts @@ -0,0 +1,25 @@ +import * as rp from 'request-promise'; +import { DocServer } from '../DocServer'; +import { Doc } from '../../new_fields/Doc'; +import { Id } from '../../new_fields/RefField'; + +export namespace SearchUtil { + export function Search(query: string, returnDocs: true): Promise<Doc[]>; + export function Search(query: string, returnDocs: false): Promise<string[]>; + export async function Search(query: string, returnDocs: boolean) { + const ids = JSON.parse(await rp.get(DocServer.prepend("/search"), { + qs: { query } + })); + if (!returnDocs) { + return ids; + } + const docMap = await DocServer.GetRefFields(ids); + return ids.map((id: string) => docMap[id]).filter((doc: any) => doc instanceof Doc); + } + + export async function GetAliasesOfDocument(doc: Doc): Promise<Doc[]> { + const proto = await Doc.GetT(doc, "proto", Doc, true); + const protoId = (proto || doc)[Id]; + return Search(`{!join from=id to=proto_i}id:${protoId}`, true); + } +}
\ No newline at end of file diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 1fdb9d4d9..dd1516da7 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -2,7 +2,34 @@ import * as React from "react"; import './ParentDocumentSelector.scss'; import { Doc } from "../../../new_fields/Doc"; import { observer } from "mobx-react"; -import { observable, action } from "mobx"; +import { observable, action, runInAction } from "mobx"; +import { Id } from "../../../new_fields/RefField"; +import { SearchUtil } from "../../util/SearchUtil"; +import { CollectionDockingView } from "./CollectionDockingView"; + +@observer +export class SelectorContextMenu extends React.Component<{ Document: Doc }> { + @observable private _docs: Doc[] = []; + + constructor(props: { Document: Doc }) { + super(props); + + this.fetchDocuments(); + } + + async fetchDocuments() { + const docs = await SearchUtil.Search(`data_l:${this.props.Document[Id]}`, true); + runInAction(() => this._docs = docs); + } + + render() { + return ( + <> + {this._docs.map(doc => <p><a onClick={() => CollectionDockingView.Instance.AddRightSplit(doc)}>{doc.title}</a></p>)} + </> + ); + } +} @observer export class ParentDocSelector extends React.Component<{ Document: Doc }> { @@ -23,7 +50,7 @@ export class ParentDocSelector extends React.Component<{ Document: Doc }> { if (this.hover) { flyout = ( <div className="PDS-flyout"> - <p>Hello world</p> + <SelectorContextMenu Document={this.props.Document} /> </div> ); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 90f67db7c..edc2158f0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -26,6 +26,7 @@ import { CurrentUserUtils } from "../../../server/authentication/models/current_ import { DocServer } from "../../DocServer"; import { Id } from "../../../new_fields/RefField"; import { PresentationView } from "../PresentationView"; +import { SearchUtil } from "../../util/SearchUtil"; const linkSchema = createSchema({ title: "string", @@ -287,16 +288,22 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } e.preventDefault(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }); - ContextMenu.Instance.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeButton }); - ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked }); - ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }); - ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) }); - ContextMenu.Instance.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])) }); - ContextMenu.Instance.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]) }); - //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) - ContextMenu.Instance.addItem({ description: "Pin to Presentation", event: () => PresentationView.Instance.PinDoc(this.props.Document) }); - ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }); + const cm = ContextMenu.Instance; + cm.addItem({ description: "Full Screen", event: this.fullScreenClicked }); + cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeButton }); + cm.addItem({ description: "Fields", event: this.fieldsClicked }); + cm.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }); + cm.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) }); + cm.addItem({ + description: "Find aliases", event: async () => { + const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document); + CollectionDockingView.Instance.AddRightSplit(Docs.SchemaDocument(aliases, {})); + } + }); + cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])) }); + cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]) }); + cm.addItem({ description: "Pin to Presentation", event: () => PresentationView.Instance.PinDoc(this.props.Document) }); + cm.addItem({ description: "Delete", event: this.deleteClicked }); if (!this.topMost) { // DocumentViews should stop propagation of this event e.stopPropagation(); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 46ccb3e90..c08049a39 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -130,8 +130,8 @@ export namespace Doc { const self = doc[Self]; return getField(self, key, ignoreProto); } - export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): T | null | undefined { - return Cast(Get(doc, key, ignoreProto), ctor) as T | null | undefined; + export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> { + return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>; } export async function SetOnPrototype(doc: Doc, key: string, value: Field) { const proto = doc.proto; |