feat: track five most recent project models (#395)
* feat: track most recent 5 models for project * refactor: set recent model records count in constants * style: remove empty line whitespaces * style: remove eol whitespaces
This commit is contained in:
Родитель
abc63767e9
Коммит
05850603d5
|
@ -32,7 +32,7 @@ export const constants = {
|
||||||
convertedImageFormat: "image/jpeg",
|
convertedImageFormat: "image/jpeg",
|
||||||
convertedImageQuality: 0.7,
|
convertedImageQuality: 0.7,
|
||||||
convertedThumbnailQuality: 0.2,
|
convertedThumbnailQuality: 0.2,
|
||||||
|
recentModelRecordsCount: 5,
|
||||||
apiModelsPath: `/formrecognizer/${apiVersion}/custom/models`,
|
apiModelsPath: `/formrecognizer/${apiVersion}/custom/models`,
|
||||||
|
|
||||||
pdfjsWorkerSrc(version: string) {
|
pdfjsWorkerSrc(version: string) {
|
||||||
|
|
|
@ -147,6 +147,7 @@ export default class MockFactory {
|
||||||
apiUriBase: "localhost",
|
apiUriBase: "localhost",
|
||||||
folderPath: "",
|
folderPath: "",
|
||||||
trainRecord: null,
|
trainRecord: null,
|
||||||
|
recentModelRecords: [],
|
||||||
predictModelId: "",
|
predictModelId: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ export interface IProject {
|
||||||
apiKey?: string | ISecureString;
|
apiKey?: string | ISecureString;
|
||||||
folderPath: string;
|
folderPath: string;
|
||||||
trainRecord: ITrainRecordProps;
|
trainRecord: ITrainRecordProps;
|
||||||
|
recentModelRecords: IRecentModel[];
|
||||||
predictModelId: string;
|
predictModelId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,6 +282,18 @@ export interface IFieldInfo {
|
||||||
fields: IField[];
|
fields: IField[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IRecentModel {
|
||||||
|
readonly composedTrainResults?: object;
|
||||||
|
readonly accuracies?: object;
|
||||||
|
readonly averageAccuracy?: number;
|
||||||
|
readonly modelInfo: {
|
||||||
|
readonly isComposed: boolean;
|
||||||
|
readonly modelId: string;
|
||||||
|
readonly createdDateTime: string;
|
||||||
|
readonly modelName: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of supported error codes
|
* Enum of supported error codes
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,7 +5,7 @@ import React from "react";
|
||||||
import {connect} from "react-redux";
|
import {connect} from "react-redux";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import { IProject, IConnection, IAppSettings, IApplicationState, AppError, ErrorCode } from "../../../../models/applicationState";
|
import { IProject, IConnection, IAppSettings, IApplicationState, AppError, ErrorCode, IRecentModel } from "../../../../models/applicationState";
|
||||||
import { constants } from "../../../../common/constants";
|
import { constants } from "../../../../common/constants";
|
||||||
import ServiceHelper from "../../../../services/serviceHelper";
|
import ServiceHelper from "../../../../services/serviceHelper";
|
||||||
import { IColumn,
|
import { IColumn,
|
||||||
|
@ -341,10 +341,8 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
const composedModels = this.reloadComposedModel(this.state.composedModelList);
|
const composedModels = this.reloadComposedModel(this.state.composedModelList);
|
||||||
|
|
||||||
let composedModelIds = [];
|
let composedModelIds = [];
|
||||||
let predictModelFlag = false;
|
|
||||||
if (this.state.composeModelId.length !== 0) {
|
if (this.state.composeModelId.length !== 0) {
|
||||||
composedModelIds = this.getComposedIds();
|
composedModelIds = this.getComposedIds();
|
||||||
predictModelFlag = true;
|
|
||||||
if (composedModelIds.indexOf(this.state.composeModelId[0]) === -1) {
|
if (composedModelIds.indexOf(this.state.composeModelId[0]) === -1) {
|
||||||
const idURL = constants.apiModelsPath + "/" + this.state.composeModelId[0];
|
const idURL = constants.apiModelsPath + "/" + this.state.composeModelId[0];
|
||||||
composedModels.push(await this.getComposeModelByURl(idURL));
|
composedModels.push(await this.getComposeModelByURl(idURL));
|
||||||
|
@ -359,10 +357,6 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
models = models.filter((m) => composedModelIds.indexOf(m.modelId) === -1);
|
models = models.filter((m) => composedModelIds.indexOf(m.modelId) === -1);
|
||||||
|
|
||||||
this.allModels = composedModels.concat(models);
|
this.allModels = composedModels.concat(models);
|
||||||
if (predictModelFlag) {
|
|
||||||
const updatedProject = this.buildUpdatedProject(this.state.composeModelId[0]);
|
|
||||||
await this.props.actions.saveProject(updatedProject, false, false);
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
modelList: this.allModels,
|
modelList: this.allModels,
|
||||||
nextLink: link,
|
nextLink: link,
|
||||||
|
@ -377,10 +371,27 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUpdatedProject = (modelId: string): IProject => {
|
private buildUpdatedProject = (composedModel: object): IProject => {
|
||||||
|
const newTrainRecord = {
|
||||||
|
modelInfo: {
|
||||||
|
createdDateTime: composedModel["modelInfo"]["createdDateTime"],
|
||||||
|
modelId: composedModel["modelInfo"]["modelId"],
|
||||||
|
modelName: composedModel["modelInfo"]["modelName"],
|
||||||
|
isComposed: true,
|
||||||
|
},
|
||||||
|
composedTrainResults: composedModel["composedTrainResults"]
|
||||||
|
} as IRecentModel;
|
||||||
|
const recentModelRecords: IRecentModel[] = this.props.project.recentModelRecords ?
|
||||||
|
[...this.props.project.recentModelRecords] : [];
|
||||||
|
recentModelRecords.unshift(newTrainRecord);
|
||||||
|
if (recentModelRecords.length > constants.recentModelRecordsCount) {
|
||||||
|
recentModelRecords.pop();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...this.props.project,
|
...this.props.project,
|
||||||
predictModelId: modelId,
|
recentModelRecords,
|
||||||
|
predictModelId: newTrainRecord.modelInfo.modelId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +410,7 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
private getComposeModelByURl = async (idURL) => {
|
private getComposeModelByURl = async (idURL) => {
|
||||||
const composedRes = await this.getResponse(idURL);
|
const composedRes = await this.getResponse(idURL);
|
||||||
const composedModel: IModel = composedRes.data.modelInfo;
|
const composedModel: IModel = composedRes.data.modelInfo;
|
||||||
composedModel.iconName = "combine";
|
composedModel.iconName = "Combine";
|
||||||
composedModel.key = composedModel.modelId;
|
composedModel.key = composedModel.modelId;
|
||||||
return composedModel;
|
return composedModel;
|
||||||
}
|
}
|
||||||
|
@ -632,18 +643,23 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
modelIds: idList,
|
modelIds: idList,
|
||||||
modelName: name,
|
modelName: name,
|
||||||
};
|
};
|
||||||
|
|
||||||
const link = constants.apiModelsPath + "/compose";
|
const link = constants.apiModelsPath + "/compose";
|
||||||
const composeRes = await this.post(link, payload);
|
const composeRes = await this.post(link, payload);
|
||||||
await this.waitUntilModelIsReady(composeRes["headers"]["location"]);
|
const composedModel = await this.waitUntilModelIsReady(composeRes["headers"]["location"]);
|
||||||
const composedModelId = this.getComposeModelId(composeRes);
|
|
||||||
|
const updatedProject = this.buildUpdatedProject(composedModel);
|
||||||
|
await this.props.actions.saveProject(updatedProject, false, false);
|
||||||
|
|
||||||
const newCols = this.state.columns;
|
const newCols = this.state.columns;
|
||||||
newCols.forEach((ncol) => {
|
newCols.forEach((ncol) => {
|
||||||
ncol.isSorted = false;
|
ncol.isSorted = false;
|
||||||
ncol.isSortedDescending = true;
|
ncol.isSortedDescending = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isComposing: false,
|
isComposing: false,
|
||||||
composeModelId: [composedModelId],
|
composeModelId: [composedModel["modelInfo"]["modelId"]],
|
||||||
columns: newCols,
|
columns: newCols,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -655,13 +671,6 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get the model Id of new composed model */
|
|
||||||
private getComposeModelId = (composeRes: any): string => {
|
|
||||||
const location = composeRes["headers"]["location"];
|
|
||||||
const splitGroup = location.split("/");
|
|
||||||
return splitGroup[splitGroup.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
private async post(link, payload): Promise<any> {
|
private async post(link, payload): Promise<any> {
|
||||||
const baseURL = url.resolve(
|
const baseURL = url.resolve(
|
||||||
this.props.project.apiUriBase,
|
this.props.project.apiUriBase,
|
||||||
|
|
|
@ -10,7 +10,7 @@ import IProjectActions, * as projectActions from "../../../../redux/actions/proj
|
||||||
import IApplicationActions, * as applicationActions from "../../../../redux/actions/applicationActions";
|
import IApplicationActions, * as applicationActions from "../../../../redux/actions/applicationActions";
|
||||||
import IAppTitleActions, * as appTitleActions from "../../../../redux/actions/appTitleActions";
|
import IAppTitleActions, * as appTitleActions from "../../../../redux/actions/appTitleActions";
|
||||||
import {
|
import {
|
||||||
IApplicationState, IConnection, IProject, IAppSettings, FieldType,
|
IApplicationState, IConnection, IProject, IAppSettings, FieldType, IRecentModel,
|
||||||
} from "../../../../models/applicationState";
|
} from "../../../../models/applicationState";
|
||||||
import TrainChart from "./trainChart";
|
import TrainChart from "./trainChart";
|
||||||
import TrainPanel from "./trainPanel";
|
import TrainPanel from "./trainPanel";
|
||||||
|
@ -327,8 +327,16 @@ export default class TrainPage extends React.Component<ITrainPageProps, ITrainPa
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUpdatedProject = (newTrainRecord: ITrainRecordProps): IProject => {
|
private buildUpdatedProject = (newTrainRecord: ITrainRecordProps): IProject => {
|
||||||
|
const recentModelRecords: IRecentModel[] = this.props.project.recentModelRecords ?
|
||||||
|
[...this.props.project.recentModelRecords] : [];
|
||||||
|
recentModelRecords.unshift({...newTrainRecord, isComposed: false} as IRecentModel);
|
||||||
|
if (recentModelRecords.length > constants.recentModelRecordsCount) {
|
||||||
|
recentModelRecords.pop();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...this.props.project,
|
...this.props.project,
|
||||||
|
recentModelRecords,
|
||||||
trainRecord: newTrainRecord,
|
trainRecord: newTrainRecord,
|
||||||
predictModelId: newTrainRecord.modelInfo.modelId,
|
predictModelId: newTrainRecord.modelInfo.modelId,
|
||||||
};
|
};
|
||||||
|
@ -356,6 +364,7 @@ export default class TrainPage extends React.Component<ITrainPageProps, ITrainPa
|
||||||
modelId: response["modelInfo"]["modelId"],
|
modelId: response["modelInfo"]["modelId"],
|
||||||
createdDateTime: response["modelInfo"]["createdDateTime"],
|
createdDateTime: response["modelInfo"]["createdDateTime"],
|
||||||
modelName: response["modelInfo"]["modelName"],
|
modelName: response["modelInfo"]["modelName"],
|
||||||
|
isComposed: false,
|
||||||
},
|
},
|
||||||
averageAccuracy: response["trainResult"]["averageModelAccuracy"],
|
averageAccuracy: response["trainResult"]["averageModelAccuracy"],
|
||||||
accuracies: this.buildAccuracies(response["trainResult"]["fields"]),
|
accuracies: this.buildAccuracies(response["trainResult"]["fields"]),
|
||||||
|
|
|
@ -8,6 +8,7 @@ export interface ITrainRecordProps {
|
||||||
accuracies?: object;
|
accuracies?: object;
|
||||||
averageAccuracy: number;
|
averageAccuracy: number;
|
||||||
modelInfo: {
|
modelInfo: {
|
||||||
|
isComposed?: boolean;
|
||||||
modelId: string;
|
modelId: string;
|
||||||
createdDateTime: string;
|
createdDateTime: string;
|
||||||
modelName: string;
|
modelName: string;
|
||||||
|
@ -26,10 +27,14 @@ export default class TrainRecord extends React.Component<ITrainRecordProps, ITra
|
||||||
<p>
|
<p>
|
||||||
{this.props.modelInfo.modelId}
|
{this.props.modelInfo.modelId}
|
||||||
</p>
|
</p>
|
||||||
<h6> Model Name: </h6>
|
{this.props.modelInfo.modelName &&
|
||||||
<p>
|
[
|
||||||
{this.props.modelInfo.modelName}
|
<h6> Model Name: </h6>,
|
||||||
</p>
|
<p>
|
||||||
|
{this.props.modelInfo.modelName}
|
||||||
|
</p>
|
||||||
|
]
|
||||||
|
}
|
||||||
<h6> Created date and time: </h6>
|
<h6> Created date and time: </h6>
|
||||||
<p>
|
<p>
|
||||||
{new Date(this.props.modelInfo.createdDateTime).toLocaleString()}
|
{new Date(this.props.modelInfo.createdDateTime).toLocaleString()}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче