aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts40
-rw-r--r--src/client/util/DragManager.ts1
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingView.scss5
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx8
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx1
-rw-r--r--src/client/views/collections/KeyRestrictionRow.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx50
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx7
-rw-r--r--src/client/views/nodes/ButtonBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/FaceRectangles.tsx2
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx5
-rw-r--r--src/client/views/nodes/ImageBox.tsx49
-rw-r--r--src/client/views/pdf/Annotation.tsx12
-rw-r--r--src/client/views/pdf/Page.tsx2
17 files changed, 130 insertions, 64 deletions
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index bbc438a9b..076907f09 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -42,7 +42,7 @@ export enum Confidence {
*/
export namespace CognitiveServices {
- const executeQuery = async <D, R>(service: Service, manager: APIManager<D>, data: D): Promise<Opt<R>> => {
+ const ExecuteQuery = async <D, R>(service: Service, manager: APIManager<D>, data: D): Promise<Opt<R>> => {
return fetch(Utils.prepend(`${RouteStore.cognitiveServices}/${service}`)).then(async response => {
let apiKey = await response.text();
if (!apiKey) {
@@ -103,15 +103,15 @@ export namespace CognitiveServices {
return request.post(options);
},
- analyzer: async (target: Doc, keys: string[], service: Service, converter: Converter) => {
+ analyzer: async (target: Doc, keys: string[], url: string, service: Service, converter: Converter) => {
let batch = UndoManager.StartBatch("Image Analysis");
- let imageData = Cast(target.data, ImageField);
+
let storageKey = keys[0];
- if (!imageData || await Cast(target[storageKey], Doc)) {
+ if (!url || await Cast(target[storageKey], Doc)) {
return;
}
let toStore: any;
- let results = await executeQuery<string, any>(service, Manager, imageData.url.href);
+ let results = await ExecuteQuery<string, any>(service, Manager, url);
if (!results) {
toStore = "Cognitive Services could not process the given image URL.";
} else {
@@ -122,6 +122,7 @@ export namespace CognitiveServices {
}
}
target[storageKey] = toStore;
+
batch.end();
}
@@ -129,31 +130,6 @@ export namespace CognitiveServices {
export type Face = { faceAttributes: any, faceId: string, faceRectangle: Rectangle };
- export const generateMetadata = async (target: Doc, threshold: Confidence = Confidence.Excellent) => {
- let converter = (results: any) => {
- let tagDoc = new Doc;
- results.tags.map((tag: Tag) => {
- let sanitized = tag.name.replace(" ", "_");
- let script = `return (${tag.confidence} >= this.confidence) ? ${tag.confidence} : "${ComputedField.undefined}"`;
- let computed = CompileScript(script, { params: { this: "Doc" } });
- computed.compiled && (tagDoc[sanitized] = new ComputedField(computed));
- });
- tagDoc.title = "Generated Tags";
- tagDoc.confidence = threshold;
- return tagDoc;
- };
- Manager.analyzer(target, ["generatedTags"], Service.ComputerVision, converter);
- };
-
- export const extractFaces = async (target: Doc) => {
- let converter = (results: any) => {
- let faceDocs = new List<Doc>();
- results.map((face: Face) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!));
- return faceDocs;
- };
- Manager.analyzer(target, ["faces"], Service.Face, converter);
- };
-
}
export namespace Inking {
@@ -209,7 +185,8 @@ export namespace CognitiveServices {
analyzer: async (target: Doc, keys: string[], inkData: InkData) => {
let batch = UndoManager.StartBatch("Ink Analysis");
- let results = await executeQuery<InkData, any>(Service.Handwriting, Manager, inkData);
+
+ let results = await ExecuteQuery<InkData, any>(Service.Handwriting, Manager, inkData);
if (results) {
results.recognitionUnits && (results = results.recognitionUnits);
target[keys[0]] = Docs.Get.DocumentHierarchyFromJson(results, "Ink Analysis");
@@ -217,6 +194,7 @@ export namespace CognitiveServices {
let individualWords = recognizedText.filter((text: string) => text && text.split(" ").length === 1);
target[keys[1]] = individualWords.join(" ");
}
+
batch.end();
}
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 9221ef274..abcc3a4e1 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -216,6 +216,7 @@ export namespace DragManager {
this.annotationDocument = annotationDoc;
this.xOffset = this.yOffset = 0;
}
+ targetContext: Doc | undefined;
dragDocument: Doc;
annotationDocument: Doc;
dropDocument: Doc;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 996118c00..08ab22725 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -233,6 +233,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
}
render() {
+ Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
// if (SelectionManager.SelectedDocuments().length > 0) console.log(StrCast(SelectionManager.SelectedDocuments()[0].Document.title));
// if (DocumentManager.Instance.getDocumentView(this.props.Document)) console.log(StrCast(this.props.Document.title), SelectionManager.IsSelected(DocumentManager.Instance.getDocumentView(this.props.Document)!))
return (
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 2bb36c825..0cb01dc9d 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -135,9 +135,9 @@
.collectionStackingView-addDocumentButton,
.collectionStackingView-addGroupButton {
- display: inline-block;
- margin: 0 5px;
+ display: flex;
overflow: hidden;
+ margin: auto;
width: 90%;
color: lightgrey;
overflow: ellipses;
@@ -146,6 +146,7 @@
.editableView-container-editing {
color: grey;
padding: 10px;
+ width: 100%;
}
.editableView-input:hover,
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 6e1968774..bcf3a85d7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -276,6 +276,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
SetValue: this.addGroup,
contents: "+ ADD A GROUP"
};
+ Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
+
// let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
return (
<div className="collectionStackingView"
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index b5dbc1a22..d8bed7e88 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -239,7 +239,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
};
let headingView = this.props.headingObject ?
<div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
- style={{ width: (style.columnWidth) / ((uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0)) || 1) }}>
+ style={{
+ width: (style.columnWidth) /
+ ((uniqueHeadings.length +
+ (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0)) || 1)
+ }}>
{/* the default bucket (no key value) has a tooltip that describes what it is.
Further, it does not have a color and cannot be deleted. */}
<div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
@@ -266,7 +270,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
{headingView}
<div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
style={{
- padding: singleColumn ? `${style.yMargin}px ${5}px ${style.yMargin}px ${5}px` : `${style.yMargin}px ${0}px`,
+ padding: singleColumn ? `${style.yMargin}px ${0}px ${style.yMargin}px ${0}px` : `${style.yMargin}px ${0}px`,
margin: "auto",
width: "max-content", //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
height: 'max-content',
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ab308c96d..6cc065342 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -572,6 +572,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
render() {
+ Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 9c3c9c07c..9baa250a6 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -29,6 +29,7 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
else {
this.props.script("");
}
+
return (
<div className="collectionViewBaseChrome-viewSpecsMenu-row">
<input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
@@ -36,7 +37,7 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
onChange={(e) => runInAction(() => this._key = e.target.value)}
placeholder="KEY" />
<button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
- style={{ background: PastelSchemaPalette.get(this._contains ? "green" : "red") }}
+ style={{ background: this._contains ? "#77dd77" : "#ff6961" }}
onClick={() => runInAction(() => this._contains = !this._contains)}>
{this._contains ? "CONTAINS" : "DOES NOT CONTAIN"}
</button>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 0780320d6..8dac785e1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -65,8 +65,20 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return (this.props as any).ContentScaling && this.fitToBox && !this.isAnnotationOverlay ? (this.props as any).ContentScaling() : 1;
}
+ ComputeContentBounds(boundsList: { x: number, y: number, width: number, height: number }[]) {
+ let bounds = boundsList.reduce((bounds, b) => {
+ var [sptX, sptY] = [b.x, b.y];
+ let [bptX, bptY] = [sptX + b.width, sptY + b.height];
+ return {
+ x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
+ r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
+ };
+ }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
+ return bounds;
+ }
+
@computed get contentBounds() {
- let bounds = this.fitToBox && !this.isAnnotationOverlay ? Doc.ComputeContentBounds(DocListCast(this.props.Document.data)) : undefined;
+ let bounds = this.fitToBox && !this.isAnnotationOverlay ? this.ComputeContentBounds(this.elements.filter(e => e.bounds).map(e => e.bounds!)) : undefined;
return {
panX: bounds ? (bounds.x + bounds.r) / 2 : this.Document.panX || 0,
panY: bounds ? (bounds.y + bounds.b) / 2 : this.Document.panY || 0,
@@ -151,6 +163,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let dropY = NumCast(de.data.dropDocument.y);
dragDoc.x = x + NumCast(dragDoc.x) - dropX;
dragDoc.y = y + NumCast(dragDoc.y) - dropY;
+ de.data.targetContext = this.props.Document;
+ dragDoc.targetContext = this.props.Document;
this.bringToFront(dragDoc);
}
}
@@ -426,7 +440,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return result.result === undefined ? {} : result.result;
}
- private viewDefToJSX(viewDef: any): JSX.Element | undefined {
+ private viewDefToJSX(viewDef: any): { ele: JSX.Element, bounds?: { x: number, y: number, width: number, height: number } } | undefined {
if (viewDef.type === "text") {
const text = Cast(viewDef.text, "string");
const x = Cast(viewDef.x, "number");
@@ -434,25 +448,27 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
const width = Cast(viewDef.width, "number");
const height = Cast(viewDef.height, "number");
const fontSize = Cast(viewDef.fontSize, "number");
- if ([text, x, y].some(val => val === undefined)) {
+ if ([text, x, y, width, height].some(val => val === undefined)) {
return undefined;
}
- return <div className="collectionFreeform-customText" style={{
- transform: `translate(${x}px, ${y}px)`,
- width, height, fontSize
- }}>{text}</div>;
+ return {
+ ele: <div className="collectionFreeform-customText" style={{
+ transform: `translate(${x}px, ${y}px)`,
+ width, height, fontSize
+ }}>{text}</div>, bounds: { x: x!, y: y!, width: width!, height: height! }
+ };
}
}
@computed.struct
- get views() {
+ get elements() {
let curPage = FieldValue(this.Document.curPage, -1);
const initScript = this.Document.arrangeInit;
const script = this.Document.arrangeScript;
let state: any = undefined;
const docs = this.childDocs;
- let elements: JSX.Element[] = [];
+ let elements: { ele: JSX.Element, bounds?: { x: number, y: number, width: number, height: number } }[] = [];
if (initScript) {
const initResult = initScript.script.run({ docs, collection: this.Document });
if (initResult.success) {
@@ -460,7 +476,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
const { state: scriptState, views } = result;
state = scriptState;
if (Array.isArray(views)) {
- elements = views.reduce<JSX.Element[]>((prev, ele) => {
+ elements = views.reduce<typeof elements>((prev, ele) => {
const jsx = this.viewDefToJSX(ele);
jsx && prev.push(jsx);
return prev;
@@ -468,15 +484,18 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
}
}
- let docviews = docs.reduce((prev, doc) => {
- if (!(doc instanceof Doc)) return prev;
+ let docviews = docs.filter(doc => doc instanceof Doc).reduce((prev, doc) => {
var page = NumCast(doc.page, -1);
+ let bounds: { x?: number, y?: number, width?: number, height?: number };
if ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1) {
let minim = BoolCast(doc.isMinimized);
if (minim === undefined || !minim) {
const pos = script ? this.getCalculatedPositions(script, { doc, index: prev.length, collection: this.Document, docs, state }) : {};
state = pos.state === undefined ? state : pos.state;
- prev.push(<CollectionFreeFormDocumentView key={doc[Id]} x={pos.x} y={pos.y} width={pos.width} height={pos.height} {...this.getChildDocumentViewProps(doc)} />);
+ prev.push({
+ ele: <CollectionFreeFormDocumentView key={doc[Id]} x={pos.x} y={pos.y} width={pos.width} height={pos.height} {...this.getChildDocumentViewProps(doc)} />,
+ bounds: (pos.x !== undefined && pos.y !== undefined && pos.width !== undefined && pos.height !== undefined) ? { x: pos.x, y: pos.y, width: pos.width, height: pos.height } : undefined
+ });
}
}
return prev;
@@ -487,6 +506,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return docviews;
}
+ @computed.struct
+ get views() {
+ return this.elements.map(ele => ele.ele);
+ }
+
@action
onCursorMove = (e: React.PointerEvent) => {
super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 1c767e012..67bed284f 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -293,15 +293,16 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
d.page = -1;
return d;
});
+ newCollection.chromeStatus = "disabled";
let summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
newCollection.proto!.summaryDoc = summary;
selected = [newCollection];
newCollection.x = bounds.left + bounds.width;
summary.proto!.subBulletDocs = new List<Doc>(selected);
- //summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
summary.templates = new List<string>([Templates.Bullet.Layout]);
- let container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, title: "-summary-" });
+ let container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" });
container.viewType = CollectionViewType.Stacking;
+ container.autoHeight = true;
this.props.addLiveTextDocument(container);
// });
} else if (e.key === "S") {
@@ -312,6 +313,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
d.page = -1;
return d;
});
+ newCollection.chromeStatus = "disabled";
let summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
newCollection.proto!.summaryDoc = summary;
selected = [newCollection];
@@ -319,6 +321,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
//this.props.addDocument(newCollection, false);
summary.proto!.summarizedDocs = new List<Doc>(selected);
summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
+ summary.autoHeight = true;
this.props.addLiveTextDocument(summary);
}
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index d2c23fdab..e2c559c9a 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -70,7 +70,7 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
render() {
return (
<div className="buttonBox-outerDiv" onContextMenu={this.onContextMenu}>
- <button className="buttonBox-mainButton" onClick={this.onClick}>{this.Document.text || "Button"}</button>
+ <button className="buttonBox-mainButton" onClick={this.onClick}>{this.Document.text || this.Document.title || "Button"}</button>
</div>
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9f0945c6b..4b5cf3a43 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -440,7 +440,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
e.stopPropagation();
let annotationDoc = de.data.annotationDocument;
annotationDoc.linkedToDoc = true;
+ de.data.targetContext = this.props.ContainingCollectionView!.props.Document;
let targetDoc = this.props.Document;
+ targetDoc.targetContext = de.data.targetContext;
let annotations = await DocListCastAsync(annotationDoc.annotations);
if (annotations) {
annotations.forEach(anno => {
@@ -449,7 +451,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc);
if (pdfDoc) {
- DocUtils.MakeLink(annotationDoc, targetDoc, undefined, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
+ DocUtils.MakeLink(annotationDoc, targetDoc, this.props.ContainingCollectionView!.props.Document, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
}
}
if (de.data instanceof DragManager.LinkDragData) {
diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx
index 3570531b2..acf1aced3 100644
--- a/src/client/views/nodes/FaceRectangles.tsx
+++ b/src/client/views/nodes/FaceRectangles.tsx
@@ -20,7 +20,7 @@ export interface RectangleTemplate {
export default class FaceRectangles extends React.Component<FaceRectanglesProps> {
render() {
- let faces = DocListCast(Doc.GetProto(this.props.document).faces);
+ let faces = DocListCast(this.props.document.faces);
let templates: RectangleTemplate[] = faces.map(faceDoc => {
let rectangle = Cast(faceDoc.faceRectangle, Doc) as Doc;
let style = {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0f51ca2ce..fc0cc98aa 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -329,7 +329,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
fieldExtDoc.annotations = new List<Doc>(targetAnnotations);
}
- let link = DocUtils.MakeLink(this.props.Document, region);
+ let link = DocUtils.MakeLink(this.props.Document, region, doc);
if (link) {
cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
linkId = link[Id];
@@ -443,6 +443,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
if (targetContext) {
DocumentManager.Instance.jumpToDocument(targetContext, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+ } else if (jumpToDoc) {
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+
}
}
});
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d4e0eaf98..dbe545048 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -25,9 +25,12 @@ import { Docs, DocumentType } from '../../documents/Documents';
import { DocServer } from '../../DocServer';
import { Font } from '@react-pdf/renderer';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { CognitiveServices } from '../../cognitive_services/CognitiveServices';
+import { CognitiveServices, Service, Tag, Confidence } from '../../cognitive_services/CognitiveServices';
import FaceRectangles from './FaceRectangles';
import { faEye } from '@fortawesome/free-regular-svg-icons';
+import { ComputedField } from '../../../new_fields/ScriptField';
+import { CompileScript } from '../../util/Scripting';
+import { thisExpression } from 'babel-types';
var requestImageSize = require('../../util/request-image-size');
var path = require('path');
const { Howl } = require('howler');
@@ -230,20 +233,56 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
funcs.push({ description: "Rotate", event: this.rotate, icon: "expand-arrows-alt" });
let modes: ContextMenuProps[] = [];
- let dataDoc = Doc.GetProto(this.props.Document);
- modes.push({ description: "Generate Tags", event: () => CognitiveServices.Image.generateMetadata(dataDoc), icon: "tag" });
- modes.push({ description: "Find Faces", event: () => CognitiveServices.Image.extractFaces(dataDoc), icon: "camera" });
+ modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" });
+ modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" });
ContextMenu.Instance.addItem({ description: "Image Funcs...", subitems: funcs, icon: "asterisk" });
ContextMenu.Instance.addItem({ description: "Analyze...", subitems: modes, icon: "eye" });
}
}
+ extractFaces = () => {
+ let converter = (results: any) => {
+ let faceDocs = new List<Doc>();
+ results.map((face: CognitiveServices.Image.Face) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!));
+ return faceDocs;
+ };
+ CognitiveServices.Image.Manager.analyzer(this.extensionDoc, ["faces"], this.url, Service.Face, converter);
+ }
+
+ generateMetadata = (threshold: Confidence = Confidence.Excellent) => {
+ let converter = (results: any) => {
+ let tagDoc = new Doc;
+ let tagsList = new List();
+ results.tags.map((tag: Tag) => {
+ tagsList.push(tag.name);
+ let sanitized = tag.name.replace(" ", "_");
+ let script = `return (${tag.confidence} >= this.confidence) ? ${tag.confidence} : "${ComputedField.undefined}"`;
+ let computed = CompileScript(script, { params: { this: "Doc" } });
+ computed.compiled && (tagDoc[sanitized] = new ComputedField(computed));
+ });
+ this.extensionDoc.generatedTags = tagsList;
+ tagDoc.title = "Generated Tags Doc";
+ tagDoc.confidence = threshold;
+ return tagDoc;
+ };
+ CognitiveServices.Image.Manager.analyzer(this.extensionDoc, ["generatedTagsDoc"], this.url, Service.ComputerVision, converter);
+ }
+
@action
onDotDown(index: number) {
this.Document.curPage = index;
}
+ @computed get fieldExtensionDoc() {
+ return Doc.resolvedFieldDataDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, "true");
+ }
+
+ @computed private get url() {
+ let data = Cast(Doc.GetProto(this.props.Document).data, ImageField);
+ return data ? data.url.href : undefined;
+ }
+
dots(paths: string[]) {
let nativeWidth = FieldValue(this.Document.nativeWidth, 1);
let dist = Math.min(nativeWidth / paths.length, 40);
@@ -398,7 +437,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
style={{ color: [DocListCast(this.extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={faFileAudio} size="sm" />
</div>
{/* {this.lightbox(paths)} */}
- <FaceRectangles document={this.props.Document} color={"#0000FF"} backgroundColor={"#0000FF"} />
+ <FaceRectangles document={this.extensionDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
</div>);
}
} \ No newline at end of file
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index ed7081b1d..513f9fed6 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -9,6 +9,8 @@ import { List } from "../../../new_fields/List";
import PDFMenu from "./PDFMenu";
import { DocumentManager } from "../../util/DocumentManager";
import { PresentationView } from "../presentationview/PresentationView";
+import { LinkManager } from "../../util/LinkManager";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
interface IAnnotationProps {
anno: Doc;
@@ -110,11 +112,15 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
}
@action
- onPointerDown = (e: React.PointerEvent) => {
+ onPointerDown = async (e: React.PointerEvent) => {
if (e.button === 0) {
- let targetDoc = Cast(this.props.document.target, Doc, null);
+ let targetDoc = await Cast(this.props.document.target, Doc);
if (targetDoc) {
- DocumentManager.Instance.jumpToDocument(targetDoc, false);
+ let context = await Cast(targetDoc.targetContext, Doc);
+ if (context) {
+ DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined,
+ ((doc) => this.props.parent.props.parent.props.addDocTab(context!, context!.proto, e.ctrlKey ? "onRight" : "inTab")));
+ }
}
}
if (e.button === 2) {
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index c205617b4..c5b2a1dda 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -175,7 +175,7 @@ export default class Page extends React.Component<IPageProps> {
}
let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc);
if (pdfDoc) {
- DocUtils.MakeLink(annotationDoc, targetDoc, undefined, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
+ DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
}
}
}