aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/ClientRecommender.tsx26
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts12
-rw-r--r--src/client/documents/DocumentTypes.ts1
-rw-r--r--src/client/documents/Documents.ts9
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/MainView.tsx5
-rw-r--r--src/client/views/Recommendations.scss12
-rw-r--r--src/client/views/Recommendations.tsx176
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx16
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx27
11 files changed, 180 insertions, 109 deletions
diff --git a/src/client/ClientRecommender.tsx b/src/client/ClientRecommender.tsx
index 91973f0e2..103993a67 100644
--- a/src/client/ClientRecommender.tsx
+++ b/src/client/ClientRecommender.tsx
@@ -139,7 +139,7 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
let fielddata = Cast(dataDoc.data, RichTextField);
let data: string;
fielddata ? data = fielddata[ToPlainText]() : data = "";
- let converter = (results: any, data: string) => {
+ let converter = async (results: any, data: string) => {
let keyterms = new List<string>(); // raw keywords
let keyterms_counted = new List<string>(); // keywords, where each keyword is repeated as
let highKP: string[] = [""]; // most frequent
@@ -167,12 +167,12 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
});
this.highKP = highKP;
console.log(highKP);
- this.sendRequest(highKP);
const kts_counted = new List<string>();
keyterms_counted.forEach(kt => kts_counted.push(kt.toLowerCase()));
- return { keyterms: keyterms, keyterms_counted: kts_counted };
+ const values = await this.sendRequest(highKP);
+ return { keyterms: keyterms, keyterms_counted: kts_counted, values };
};
- await CognitiveServices.Text.Appliers.analyzer(dataDoc, extDoc, ["key words"], data, converter, mainDoc, internal);
+ return CognitiveServices.Text.Appliers.analyzer(dataDoc, extDoc, ["key words"], data, converter, mainDoc, internal);
}
private countFrequencies(keyphrase: string, paragraph: string) {
@@ -200,7 +200,9 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
private async sendRequest(keywords: string[]) {
let query = "";
keywords.forEach((kp: string) => query += " " + kp);
- await this.arxivrequest(query);
+ return new Promise<any>(resolve => {
+ this.arxivrequest(query).then(resolve);
+ });
}
/**
@@ -209,7 +211,7 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
arxivrequest = async (query: string) => {
let xhttp = new XMLHttpRequest();
- let serveraddress = "http://export.arxiv.org/api"
+ let serveraddress = "http://export.arxiv.org/api";
let endpoint = serveraddress + "/query?search_query=all:" + query + "&start=0&max_results=1";
let promisified = (resolve: any, reject: any) => {
xhttp.onreadystatechange = function () {
@@ -219,20 +221,22 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
console.log(xml);
switch (this.status) {
case 200:
+ let title: string = "Title";
+ let url: string = "Url";
//console.log(result);
if (xml) {
let titles = xml.getElementsByTagName("title");
if (titles && titles.length > 1) {
- let text = titles[1].childNodes[0].nodeValue;
- console.log(text);
+ title = titles[1].childNodes[0].nodeValue!;
+ console.log(title);
}
let ids = xml.getElementsByTagName("id");
if (ids && ids.length > 1) {
- let text = ids[1].childNodes[0].nodeValue;
- console.log(text);
+ url = ids[1].childNodes[0].nodeValue!;
+ console.log(url);
}
}
- return resolve(result);
+ return resolve({ title, url });
case 400:
default:
return reject(result);
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 8a58355a8..baafb63a1 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -15,7 +15,7 @@ type RequestExecutor = (apiKey: string, body: string, service: Service) => Promi
type AnalysisApplier<D> = (target: Doc, relevantKeys: string[], data: D, ...args: any) => any;
type BodyConverter<D> = (data: D) => string;
type Converter = (results: any) => Field;
-type TextConverter = (results: any, data: string) => { keyterms: Field, keyterms_counted: Field };
+type TextConverter = (results: any, data: string) => Promise<{ keyterms: Field, keyterms_counted: Field, values: any }>;
export type Tag = { name: string, confidence: number };
export type Rectangle = { top: number, left: number, width: number, height: number };
@@ -288,11 +288,15 @@ export namespace CognitiveServices {
export const analyzer = async (dataDoc: Doc, target: Doc, keys: string[], data: string, converter: TextConverter, mainDoc: boolean = false, internal: boolean = true) => {
let results = await ExecuteQuery(Service.Text, Manager, data);
console.log(results);
- let keyterms = converter(results, data);
+ let { keyterms, values, keyterms_counted } = await converter(results, data);
//target[keys[0]] = Docs.Get.DocumentHierarchyFromJson(results, "Key Word Analysis");
- target[keys[0]] = keyterms.keyterms;
+ target[keys[0]] = keyterms;
console.log("analyzed!");
- if (internal) await vectorize(keyterms.keyterms_counted, dataDoc, mainDoc, data);
+ if (internal) {
+ await vectorize(keyterms_counted, dataDoc, mainDoc, data);
+ } else {
+ return values;
+ }
};
// export async function countFrequencies()
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 1578e49fe..08f64fc8e 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -19,4 +19,5 @@ export enum DocumentType {
YOUTUBE = "youtube",
DRAGBOX = "dragbox",
PRES = "presentation",
+ RECOMMENDATION = "recommendation"
} \ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1e9d1687f..89358d773 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -45,6 +45,7 @@ import { PresBox } from "../views/nodes/PresBox";
import { ComputedField } from "../../new_fields/ScriptField";
import { ProxyField } from "../../new_fields/Proxy";
import { DocumentType } from "./DocumentTypes";
+import { RecommendationsBox } from "../views/Recommendations";
//import { PresBox } from "../views/nodes/PresBox";
//import { PresField } from "../../new_fields/PresField";
var requestImageSize = require('../util/request-image-size');
@@ -170,6 +171,10 @@ export namespace Docs {
[DocumentType.DRAGBOX, {
layout: { view: DragBox },
options: { width: 40, height: 40 },
+ }],
+ [DocumentType.RECOMMENDATION, {
+ layout: { view: RecommendationsBox },
+ options: { width: 200, height: 200 },
}]
]);
@@ -451,6 +456,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.IMPORT), new List<Doc>(), options);
}
+ export function RecommendationsDocument(data: Doc[], options: DocumentOptions = {}) {
+ return InstanceFromProto(Prototypes.get(DocumentType.RECOMMENDATION), new List<Doc>(data), options);
+ }
+
export type DocConfig = {
doc: Doc,
initialWidth?: number
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index d0464bd5f..4135afcb8 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -6,6 +6,7 @@ import { DragManager } from "../util/DragManager";
import { action, runInAction } from "mobx";
import { Doc } from "../../new_fields/Doc";
import { DictationManager } from "../util/DictationManager";
+import { RecommendationsBox } from "./Recommendations";
const modifiers = ["control", "meta", "shift", "alt"];
type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>;
@@ -72,6 +73,7 @@ export default class KeyManager {
main.toggleColorPicker(true);
SelectionManager.DeselectAll();
DictationManager.Controls.stop();
+ // RecommendationsBox.Instance.closeMenu();
break;
case "delete":
case "backspace":
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3a5795077..0bc539dca 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -40,7 +40,7 @@ import { PreviewCursor } from './PreviewCursor';
import { FilterBox } from './search/FilterBox';
import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
//import { DocumentManager } from '../util/DocumentManager';
-import { Recommendations } from './Recommendations';
+import { RecommendationsBox } from './Recommendations';
import PresModeMenu from './presentationview/PresentationModeMenu';
import { PresBox } from './nodes/PresBox';
@@ -204,7 +204,6 @@ export class MainView extends React.Component {
const targets = document.elementsFromPoint(e.x, e.y);
if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) {
ContextMenu.Instance.closeMenu();
- Recommendations.Instance.closeMenu();
}
});
@@ -567,7 +566,7 @@ export class MainView extends React.Component {
{this.miniPresentation}
<PreviewCursor />
<ContextMenu />
- <Recommendations />
+ {/* <RecommendationsBox /> */}
{this.nodesMenu()}
{this.miscButtons}
<PDFMenu />
diff --git a/src/client/views/Recommendations.scss b/src/client/views/Recommendations.scss
index 6619d8df3..dd8a105f6 100644
--- a/src/client/views/Recommendations.scss
+++ b/src/client/views/Recommendations.scss
@@ -4,7 +4,7 @@
display: inline-block;
margin: auto;
width: 50;
- height: 30px;
+ height: 150px;
border: 1px dashed grey;
padding: 10px 10px;
}
@@ -19,17 +19,20 @@
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
+ pointer-events: all;
// display: flex;
z-index: 10000;
box-shadow: gray 0.2vw 0.2vw 0.4vw;
// flex-direction: column;
background: whitesmoke;
padding-bottom: 10px;
- border-radius: 15px;
+ padding-top: 20px;
+ // border-radius: 15px;
border: solid #BBBBBBBB 1px;
- width: 250px;
+ width: 100%;
text-align: center;
- max-height: 250px;
+ // max-height: 250px;
+ height: 100%;
text-transform: uppercase;
color: grey;
letter-spacing: 2px;
@@ -48,7 +51,6 @@
background-color: transparent;
width: 50%;
text-align: center;
- height: 35px;
margin-left: 5px;
}
diff --git a/src/client/views/Recommendations.tsx b/src/client/views/Recommendations.tsx
index d0105ee18..b7b1d84d0 100644
--- a/src/client/views/Recommendations.tsx
+++ b/src/client/views/Recommendations.tsx
@@ -14,27 +14,37 @@ import { DocumentType } from '../documents/DocumentTypes';
import { ClientRecommender } from "../ClientRecommender";
import { DocServer } from "../DocServer";
import { Id } from "../../new_fields/FieldSymbols";
+import { FieldView, FieldViewProps } from "./nodes/FieldView";
+import { DocumentManager } from "../util/DocumentManager";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons";
+import { DocUtils } from "../documents/Documents";
export interface RecProps {
documents: { preview: Doc, similarity: number }[];
node: Doc;
}
+library.add(faBullseye, faLink);
+
@observer
-export class Recommendations extends React.Component<{}> {
+export class RecommendationsBox extends React.Component<FieldViewProps> {
+
+ public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(RecommendationsBox, fieldKey); }
- static Instance: Recommendations;
- @observable private _display: boolean = false;
+ static Instance: RecommendationsBox;
+ // @observable private _display: boolean = false;
@observable private _pageX: number = 0;
@observable private _pageY: number = 0;
@observable private _width: number = 0;
@observable private _height: number = 0;
- @observable private _documents: { preview: Doc, score: number }[] = [];
+ // @observable private _documents: { preview: Doc, score: number }[] = [];
private previewDocs: Doc[] = [];
- constructor(props: {}) {
+ constructor(props: FieldViewProps) {
super(props);
- Recommendations.Instance = this;
+ RecommendationsBox.Instance = this;
}
private DocumentIcon(doc: Doc) {
@@ -52,12 +62,12 @@ export class Recommendations extends React.Component<{}> {
};
}, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE });
}
- let returnXDimension = () => 50;
- let returnYDimension = () => 50;
+ let returnXDimension = () => 150;
+ let returnYDimension = () => 150;
let scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension());
//let scale = () => 1;
let newRenderDoc = Doc.MakeAlias(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt
- newRenderDoc.height = 50;
+ newRenderDoc.height = NumCast(this.props.Document.documentIconHeight);
newRenderDoc.autoHeight = false;
const docview = <div>
{/* onPointerDown={action(() => {
@@ -78,7 +88,8 @@ export class Recommendations extends React.Component<{}> {
PanelHeight={returnYDimension}
focus={emptyFunction}
backgroundColor={returnEmptyString}
- selectOnLoad={false}
+ // selectOnLoad={false}
+ pinToPres={emptyFunction}
parentActive={returnFalse}
whenActiveChanged={returnFalse}
bringToFront={emptyFunction}
@@ -96,83 +107,88 @@ export class Recommendations extends React.Component<{}> {
}
- @action
- closeMenu = () => {
- this._display = false;
- this.previewDocs.forEach(doc => DocServer.DeleteDocument(doc[Id]));
- this.previewDocs = [];
- }
-
- @action
- resetDocuments = () => {
- this._documents = [];
- }
-
- @action
- addDocuments = (documents: { preview: Doc, score: number }[]) => {
- this._documents = documents;
- }
-
- @action
- displayRecommendations(x: number, y: number) {
- this._pageX = x;
- this._pageY = y;
- this._display = true;
- }
+ // @action
+ // closeMenu = () => {
+ // this._display = false;
+ // this.previewDocs.forEach(doc => DocServer.DeleteDocument(doc[Id]));
+ // this.previewDocs = [];
+ // }
+
+ // @action
+ // resetDocuments = () => {
+ // this._documents = [];
+ // }
+
+ // @action
+ // displayRecommendations(x: number, y: number) {
+ // this._pageX = x;
+ // this._pageY = y;
+ // this._display = true;
+ // }
static readonly buffer = 20;
- get pageX() {
- const x = this._pageX;
- if (x < 0) {
- return 0;
- }
- const width = this._width;
- if (x + width > window.innerWidth - Recommendations.buffer) {
- return window.innerWidth - Recommendations.buffer - width;
- }
- return x;
- }
-
- get pageY() {
- const y = this._pageY;
- if (y < 0) {
- return 0;
- }
- const height = this._height;
- if (y + height > window.innerHeight - Recommendations.buffer) {
- return window.innerHeight - Recommendations.buffer - height;
- }
- return y;
- }
+ // get pageX() {
+ // const x = this._pageX;
+ // if (x < 0) {
+ // return 0;
+ // }
+ // const width = this._width;
+ // if (x + width > window.innerWidth - RecommendationsBox.buffer) {
+ // return window.innerWidth - RecommendationsBox.buffer - width;
+ // }
+ // return x;
+ // }
+
+ // get pageY() {
+ // const y = this._pageY;
+ // if (y < 0) {
+ // return 0;
+ // }
+ // const height = this._height;
+ // if (y + height > window.innerHeight - RecommendationsBox.buffer) {
+ // return window.innerHeight - RecommendationsBox.buffer - height;
+ // }
+ // return y;
+ // }
render() {
- if (!this._display) {
- return null;
- }
- let style = { left: this.pageX, top: this.pageY };
+ // if (!this._display) {
+ // return null;
+ // }
+ // let style = { left: this.pageX, top: this.pageY };
//const transform = "translate(" + (NumCast(this.props.node.x) + 350) + "px, " + NumCast(this.props.node.y) + "px"
+ let title = StrCast((this.props.Document.sourceDoc as Doc).title);
+ if (title.length > 15) {
+ title = title.substring(0, 15) + "...";
+ }
return (
- <Measure offset onResize={action((r: any) => { this._width = r.offset.width; this._height = r.offset.height; })}>
- {({ measureRef }) => (
- <div className="rec-scroll" style={style} ref={measureRef}>
- <p>Recommendations</p>
- {this._documents.map(doc => {
- return (
- <div className="content">
- <span className="image-background">
- {this.DocumentIcon(doc.preview)}
- </span>
- <span className="score">{doc.score.toFixed(4)}</span>
- </div>
- );
- })}
-
- </div>
- )
- }
-
- </Measure>
+ // <Measure offset onResize={action((r: any) => { this._width = r.offset.width; this._height = r.offset.height; })}>
+ // {({ measureRef }) => (
+ <div className="rec-scroll">
+ <p>Recommendations for "{title}"</p>
+ {DocListCast(this.props.Document.data).map(doc => {
+ return (
+ <div className="content">
+ <span style={{ height: NumCast(this.props.Document.documentIconHeight) }} className="image-background">
+ {this.DocumentIcon(doc)}
+ </span>
+ <span className="score">{NumCast(doc.score).toFixed(4)}</span>
+ <div style={{ marginRight: 50 }} onClick={() => DocumentManager.Instance.jumpToDocument(doc, true, undefined, undefined, undefined, this.props.Document.sourceDocContext as Doc)}>
+ <FontAwesomeIcon className="documentdecorations-icon" icon={"bullseye"} size="sm" />
+ </div>
+ <div style={{ marginRight: 50 }} onClick={() => DocUtils.MakeLink(this.props.Document.sourceDoc as Doc, doc, undefined, "User Selected Link", "Generated from Recommender", undefined)}>
+ <FontAwesomeIcon className="documentdecorations-icon" icon={"link"} size="sm" />
+ </div>
+ </div>
+ );
+ })}
+
+ </div>
+ // );
+ // }
+
+ // </Measure>
);
}
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 9c26a08f0..bf8c4b6f7 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -27,6 +27,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
import { KeyCodes } from "../../northstar/utils/KeyCodes";
import { undoBatch } from "../../util/UndoManager";
+import { List } from "lodash";
library.add(faExpand);
@@ -86,10 +87,23 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
}
@action
- onPointerDown = (e: React.PointerEvent): void => {
+ onPointerDown = async (e: React.PointerEvent): Promise<void> => {
this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
this.props.setPreviewDoc(this.props.rowProps.original);
+ const data = await DocListCastAsync(this.props.Document.data);
+ if (data) {
+ let url: string;
+ if (url = StrCast(data[0].href)) {
+ try {
+ new URL(url);
+ const temp = window.open(url)!;
+ temp.blur();
+ window.focus();
+ } catch { }
+ }
+ }
+
// this._isEditing = true;
// this.props.setIsEditing(true);
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index d77662355..c8a636727 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -29,6 +29,7 @@ import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { Doc } from "../../../new_fields/Doc";
import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
+import { RecommendationsBox } from "../../views/Recommendations";
import { ScriptField } from "../../../new_fields/ScriptField";
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -108,7 +109,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
if (!this.layout && (this.props.layoutKey !== "overlayLayout" || !this.templates.length)) return (null);
return <ObserverJsxParser
blacklistedAttrs={[]}
- components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox }}
+ components={{ FormattedTextBox, ImageBox, RecommendationsBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox }}
bindings={this.CreateBindings()}
jsx={this.finalLayout}
showWarnings={true}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f8b9cd0f1..a034bc1f4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -41,10 +41,11 @@ import "./DocumentView.scss";
import { FormattedTextBox } from './FormattedTextBox';
import React = require("react");
import requestPromise = require('request-promise');
-import { Recommendations } from '../Recommendations';
+import { RecommendationsBox } from '../Recommendations';
import { SearchUtil } from '../../util/SearchUtil';
import { ClientRecommender } from '../../ClientRecommender';
import { DocumentType } from '../../documents/DocumentTypes';
+import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField';
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
library.add(fa.faBrain);
@@ -751,8 +752,22 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
for (let i = 0; i < doclist.length; i++) {
recDocs.push({ preview: doclist[i].actualDoc, score: doclist[i].score });
}
- Recommendations.Instance.addDocuments(recDocs);
- Recommendations.Instance.displayRecommendations(e.pageX + 100, e.pageY);
+
+ const data = recDocs.map(unit => {
+ unit.preview.score = unit.score;
+ return unit.preview;
+ });
+
+ console.log(recDocs.map(doc => doc.score));
+
+ const title = `Showing ${data.length} recommendations for "${StrCast(this.props.Document.title)}"`;
+ const recommendations = Docs.Create.RecommendationsDocument(data, { title });
+ recommendations.documentIconHeight = 150;
+ recommendations.sourceDoc = this.props.Document;
+ recommendations.sourceDocContext = this.props.ContainingCollectionView!.props.Document;
+ CollectionDockingView.Instance.AddRightSplit(recommendations, undefined);
+
+ // RecommendationsBox.Instance.displayRecommendations(e.pageX + 100, e.pageY);
}
externalRecommendation = async (e: React.MouseEvent) => {
@@ -760,7 +775,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
ClientRecommender.Instance.reset_docs();
const doc = Doc.GetDataDoc(this.props.Document);
const extdoc = doc.data_ext as Doc;
- return ClientRecommender.Instance.extractText(doc, extdoc ? extdoc : doc, false);
+ const values = await ClientRecommender.Instance.extractText(doc, extdoc ? extdoc : doc, false);
+ const headers = [new SchemaHeaderField("title"), new SchemaHeaderField("href")];
+ const body = Docs.Create.FreeformDocument([], { title: values.title });
+ body.href = values.url;
+ CollectionDockingView.Instance.AddRightSplit(Docs.Create.SchemaDocument(headers, [body], { title: `Showing External Recommendations for "${StrCast(doc.title)}"` }), undefined);
}
onPointerEnter = (e: React.PointerEvent): void => { Doc.BrushDoc(this.props.Document); };