Skip to content

Commit

Permalink
Support non-fixed version and form types in the prebuilt page. (micro…
Browse files Browse the repository at this point in the history
…soft#869)

* Add URIUtils and support non-fixed version and prebuilt types in the composed api request field.

* Add an EOF new line to the utils.

* Hide predict mode toggle in prod env.

* Refine coding style.

* refind coding style

Co-authored-by: Buddha Wang <[email protected]>
  • Loading branch information
simotw and buddhawang authored Feb 9, 2021
1 parent 35002d3 commit 248bb13
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 36 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"jszip": "^3.5.0",
"lodash": "^4.17.20",
"ol": "^5.3.3",
"path-to-regexp": "^6.2.0",
"promise.allsettled": "^1.0.2",
"rc-align": "^2.4.5",
"rc-checkbox": "^2.1.8",
Expand Down
39 changes: 39 additions & 0 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useState, useEffect } from 'react';
import {constants} from "./constants";
import _ from "lodash";
import JsZip from 'jszip';
import { match, compile } from "path-to-regexp";

// tslint:disable-next-line:no-var-requires
const tagColors = require("../react/components/common/tagColors.json");
Expand Down Expand Up @@ -507,3 +508,41 @@ export function downloadZipFile(data: zipData[], fileName: string): void {
fileLink.click();
});
}

export class URIUtils {

public static normalizePath(path: string): string {
return "/" + path.replace(/(\r\n|\n|\r)/gm, "").replace(/^\/+/, "");
}

public static matchPath(pathTemplate: string, path: string): object {
const matcher = match(pathTemplate, { decode: decodeURIComponent });
const result = matcher(path)
return (result && result.params) || {};
}

public static compilePath(pathTemplate: string, params: object): string {
const toPath = compile(pathTemplate, { encode: encodeURIComponent });
return toPath(params);
}

public static composeQueryString(params: object, blacklist = new Set<string>()) {
const kvList = [];
const connector = "&";
for (const [key, value] of Object.entries(params)) {
if (key && (value === 0 || value) && !blacklist.has(key)) {
kvList.push(`${key}=${value}`);
}
}
return kvList.join(connector);
}

public static matchQueryString(queryString: string) {
const params = {};
queryString.split("&").forEach(s => {
const [key, value] = s.split("=");
params[key] = value;
});
return params;
}
}
93 changes: 57 additions & 36 deletions src/react/components/pages/prebuiltPredict/prebuiltPredictPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { ITableHelper, ITableState, TableHelper } from "./tableHelper";
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
import { ILayoutHelper, LayoutHelper } from "./layoutHelper";
import HtmlFileReader from "../../../../common/htmlFileReader";
import {URIUtils} from "../../../../common/utils";

interface IPrebuiltTypes {
name: string;
Expand Down Expand Up @@ -104,21 +105,21 @@ export class PrebuiltPredictPage extends React.Component<IPrebuiltPredictPagePro
prebuiltTypes: IPrebuiltTypes[] = [
{
name: "Invoice",
servicePath: "/prebuilt/invoice/analyze"
servicePath: "invoice",
},
{
name: "Receipt",
servicePath: "/prebuilt/receipt/analyze",
servicePath: "receipt",
useLocale: true,
},
{
name: "Business card",
servicePath: "/prebuilt/businessCard/analyze",
servicePath: "businessCard",
useLocale: true,
},
{
name: "ID",
servicePath: "/prebuilt/idDocument/analyze"
servicePath: "idDocument",
}
];

Expand Down Expand Up @@ -174,7 +175,7 @@ export class PrebuiltPredictPage extends React.Component<IPrebuiltPredictPagePro
appTitleActions.setTitle(`${strings.prebuiltPredict.title}`);
if (prebuiltSettings && prebuiltSettings.serviceURI) {
this.setState({
predictionEndpointUrl: `/formrecognizer/${constants.prebuiltServiceVersion}${this.state.currentPrebuiltType.servicePath}?includeTextDetails=true`
predictionEndpointUrl: `/formrecognizer/${constants.prebuiltServiceVersion}/prebuilt/${this.state.currentPrebuiltType.servicePath}/analyze?includeTextDetails=true`
});
}
}
Expand Down Expand Up @@ -922,48 +923,68 @@ export class PrebuiltPredictPage extends React.Component<IPrebuiltPredictPagePro
}

private handleUpdateRequestURI = () => {
this.setState({ predictionEndpointUrl: this.getUpdateRequestURI() });
}

private getUpdateRequestURI = () => {
const { prebuiltSettings } = this.props;
const { currentPrebuiltType, predictionEndpointUrl } = this.state;
let updatedURI = "";
if (predictionEndpointUrl.includes("?")) {
const queryString = predictionEndpointUrl.split("?")[1];
if (prebuiltSettings && prebuiltSettings.serviceURI) {
const parameterArray = queryString.includes("&") ? queryString.split("&") : [queryString];
let newQueryString = "";
let connector = "";
for (const parameter of parameterArray) {
const name = parameter.split("=")[0];
if (name !== "locale" && name !== constants.pages) {
newQueryString += `${connector}${parameter}`;
}
connector = "&";
}
if (this.state.withPageRange && this.state.pageRangeIsValid) {
newQueryString += `${connector}${constants.pages}=${this.state.pageRange}`;
connector = "&";
this.setState({ predictionEndpointUrl: this.getUpdatedRequestURI() });
}

private getUpdatedRequestURI = (fromTextArea: boolean = false) => {
const { predictionEndpointUrl } = this.state;
const [path, queryString] = predictionEndpointUrl.split("?");
const newPath = this.getUpdatedPath(path, fromTextArea);
const newQueryString = this.getUpdatedQueryString(queryString);
return `${newPath}?${newQueryString}`;
}

private getUpdatedPath(path: string, fromTextArea: boolean): string {
const pathTemplate = "/formrecognizer/:prebuiltServiceVersion/prebuilt/:prebuiltType/analyze";
const normalizedPath = URIUtils.normalizePath(path);
const pathParams = URIUtils.matchPath(pathTemplate, normalizedPath);
if (fromTextArea) {
const prebuiltType = _.get(pathParams, "prebuiltType", "");
if (prebuiltType && prebuiltType !== this.state.currentPrebuiltType.servicePath) {
const ret = this.prebuiltTypes.filter(item => item.servicePath === prebuiltType);
if (ret.length === 1) {
this.setState({ currentPrebuiltType: ret[0] });
}
if (this.state.currentPrebuiltType.useLocale) {
newQueryString += `${connector}locale=${this.state.currentLocale}`;
}
} else {
pathParams["prebuiltType"] = this.state.currentPrebuiltType.servicePath;
}

return URIUtils.compilePath(pathTemplate, pathParams);
}

private getUpdatedQueryString(queryString: string): string {
let newQueryString = "";
if (queryString) {
const parameterArray = queryString.includes("&") ? queryString.split("&") : [queryString];
let connector = "";
for (const parameter of parameterArray) {
const name = parameter.split("=")[0];
if (name !== "locale" && name !== constants.pages) {
newQueryString += `${connector}${parameter}`;
}
updatedURI = `/formrecognizer/${constants.prebuiltServiceVersion}${currentPrebuiltType.servicePath}?${newQueryString}`;
connector = "&";
}
if (this.state.withPageRange && this.state.pageRangeIsValid) {
newQueryString += `${connector}${constants.pages}=${this.state.pageRange}`;
connector = "&";
}
if (this.state.currentPrebuiltType.useLocale) {
newQueryString += `${connector}locale=${this.state.currentLocale}`;
}
} else {
let apiRequest = `/formrecognizer/${constants.prebuiltServiceVersion}${this.state.currentPrebuiltType.servicePath}?includeTextDetails=true`;
newQueryString = `includeTextDetails=true`;
if (this.state.withPageRange && this.state.pageRangeIsValid) {
apiRequest += `&${constants.pages}=${this.state.pageRange}`;
newQueryString += `&${constants.pages}=${this.state.pageRange}`;
}
updatedURI = apiRequest + (this.state.currentPrebuiltType.useLocale ? `&locale=${this.state.currentLocale}` : "");
newQueryString += this.state.currentPrebuiltType.useLocale ? `&locale=${this.state.currentLocale}` : "";
}

return updatedURI;
return newQueryString;
}

private getComposedURL = () => {
const uri = this.getUpdateRequestURI();
const uri = this.getUpdatedRequestURI(true);
return this.props.prebuiltSettings.serviceURI.replace(/\/+$/, "") + "/" + uri.replace(/(\r\n|\n|\r)/gm, "").replace(/^\/+/, "");
}

Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9461,6 +9461,11 @@ path-to-regexp@^1.7.0:
dependencies:
isarray "0.0.1"

path-to-regexp@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38"
integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==

path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
Expand Down

0 comments on commit 248bb13

Please sign in to comment.