From ae3e8e1497eb172d80b12cfc980a10486adabd8b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 19:22:02 -0400 Subject: fixed templates with stacking and other nested views. --- src/client/views/collections/CollectionSchemaView.tsx | 1 + src/client/views/collections/CollectionStackingView.tsx | 2 ++ src/client/views/collections/CollectionTreeView.tsx | 1 + 3 files changed, 4 insertions(+) (limited to 'src') 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.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 (
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); -- cgit v1.2.3-70-g09d2 From 378849b4423017d8af675ceb9992e186a5407f8f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 19:41:48 -0400 Subject: made summaries go back to having no chrome. --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 1c767e012..4d659392c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -293,14 +293,14 @@ export class MarqueeView extends React.Component 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(selected); - //summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight" summary.templates = new List([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; this.props.addLiveTextDocument(container); // }); @@ -312,6 +312,7 @@ export class MarqueeView extends React.Component 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]; -- cgit v1.2.3-70-g09d2 From 2514917040d24c04a489905c7a1fe4d10013fd31 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 20:50:04 -0400 Subject: not elegant, but should compute bounds for computed layouts --- .../collectionFreeForm/CollectionFreeFormView.tsx | 36 +++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0780320d6..d2c95532e 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, @@ -446,13 +458,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } @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,23 +472,26 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const { state: scriptState, views } = result; state = scriptState; if (Array.isArray(views)) { - elements = views.reduce((prev, ele) => { + elements = views.reduce((prev, ele) => { const jsx = this.viewDefToJSX(ele); - jsx && prev.push(jsx); + jsx && prev.push({ ele: jsx }); return prev; }, elements); } } } - 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(); + prev.push({ + ele: , + 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 +502,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)); -- cgit v1.2.3-70-g09d2 From e042f916375fbe4f23288ece0dcec5b61ef2fbed Mon Sep 17 00:00:00 2001 From: yipstanley Date: Mon, 29 Jul 2019 21:20:51 -0400 Subject: annotations now open the target context --- src/client/util/DragManager.ts | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 2 ++ src/client/views/nodes/DocumentView.tsx | 4 +++- src/client/views/pdf/Annotation.tsx | 12 +++++++++--- src/client/views/pdf/Page.tsx | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src') 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/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0780320d6..179a65739 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -151,6 +151,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); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f101222ae..b37485e62 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -439,7 +439,9 @@ export class DocumentView extends DocComponent(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 => { @@ -448,7 +450,7 @@ export class DocumentView extends DocComponent(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/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index ed7081b1d..e8d1da94b 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 { } @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 { } 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)); } } } -- cgit v1.2.3-70-g09d2 From 1723fed27c615ced10b5bf9648f86f923cf61a42 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 21:23:26 -0400 Subject: added button titles. made summary's autoHeight --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 2 ++ src/client/views/nodes/ButtonBox.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4d659392c..67bed284f 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -302,6 +302,7 @@ export class MarqueeView extends React.Component summary.templates = new List([Templates.Bullet.Layout]); 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") { @@ -320,6 +321,7 @@ export class MarqueeView extends React.Component //this.props.addDocument(newCollection, false); summary.proto!.summarizedDocs = new List(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(Butt render() { return (
- +
); } -- cgit v1.2.3-70-g09d2 From 8f8e942a648f36e480af18457a86c413e2cbdf0e Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jul 2019 21:43:53 -0400 Subject: fixed pasted pdf links to contain pdf context. --- src/client/views/nodes/FormattedTextBox.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') 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(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")); + } } }); -- cgit v1.2.3-70-g09d2 From f6583e4b504a4a60f4aefc68c7a60692a92869dd Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 29 Jul 2019 22:33:35 -0400 Subject: Included extra ui elements in bounds calculation --- .../collectionFreeForm/CollectionFreeFormView.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2b2f0bcd5..8dac785e1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -440,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"); @@ -448,14 +448,16 @@ 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
{text}
; + return { + ele:
{text}
, bounds: { x: x!, y: y!, width: width!, height: height! } + }; } } @@ -474,9 +476,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const { state: scriptState, views } = result; state = scriptState; if (Array.isArray(views)) { - elements = views.reduce((prev, ele) => { + elements = views.reduce((prev, ele) => { const jsx = this.viewDefToJSX(ele); - jsx && prev.push({ ele: jsx }); + jsx && prev.push(jsx); return prev; }, elements); } -- cgit v1.2.3-70-g09d2 From ba2c6a9f3cd6d68bcf28ff3dc880b4f8b4635747 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Mon, 29 Jul 2019 23:48:35 -0400 Subject: styling changes to stacking --- src/client/views/collections/CollectionStackingView.scss | 5 +++-- .../views/collections/CollectionStackingViewFieldColumn.tsx | 8 ++++++-- src/client/views/pdf/Annotation.tsx | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') 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/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 + 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. */}
{ 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"))); + ((doc) => this.props.parent.props.parent.props.addDocTab(context!, context!.proto, e.ctrlKey ? "onRight" : "inTab"))); } } } -- cgit v1.2.3-70-g09d2 From 2468ab85d642b954e47a560e2d0739dba9674f88 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 30 Jul 2019 00:02:21 -0400 Subject: put back contains/not contains colors --- src/client/views/collections/KeyRestrictionRow.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') 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 runInAction(() => this._key = e.target.value)} placeholder="KEY" /> -- cgit v1.2.3-70-g09d2 From 5248a770123e312e1684d7147ecb7118dd6ef1e7 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 30 Jul 2019 01:24:37 -0400 Subject: tag generation and faces on extensionDoc --- src/client/cognitive_services/CognitiveServices.ts | 40 ++++-------------- src/client/views/nodes/FaceRectangles.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 49 +++++++++++++++++++--- 3 files changed, 54 insertions(+), 37 deletions(-) (limited to 'src') 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 (service: Service, manager: APIManager, data: D): Promise> => { + const ExecuteQuery = async (service: Service, manager: APIManager, data: D): Promise> => { 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(service, Manager, imageData.url.href); + let results = await ExecuteQuery(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(); - 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(Service.Handwriting, Manager, inkData); + + let results = await ExecuteQuery(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/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 { 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/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 29a76b0c8..5554475ec 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'); @@ -226,20 +229,56 @@ export class ImageBox extends DocComponent(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(); + 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); @@ -394,7 +433,7 @@ export class ImageBox extends DocComponent(ImageD style={{ color: [DocListCast(this.extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={faFileAudio} size="sm" />
{/* {this.lightbox(paths)} */} - +
); } } \ No newline at end of file -- cgit v1.2.3-70-g09d2