From 05850603d51a6786c8b6e8b4a553db020df56158 Mon Sep 17 00:00:00 2001 From: stew-ro <60453211+stew-ro@users.noreply.github.com> Date: Thu, 9 Jul 2020 11:59:08 -0700 Subject: [PATCH] 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 --- src/common/constants.ts | 2 +- src/common/mockFactory.ts | 1 + src/models/applicationState.ts | 13 +++++ .../pages/modelCompose/modelCompose.tsx | 49 +++++++++++-------- .../components/pages/train/trainPage.tsx | 11 ++++- .../components/pages/train/trainRecord.tsx | 13 +++-- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/common/constants.ts b/src/common/constants.ts index 6bb614cae..ea9a149f0 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -32,7 +32,7 @@ export const constants = { convertedImageFormat: "image/jpeg", convertedImageQuality: 0.7, convertedThumbnailQuality: 0.2, - + recentModelRecordsCount: 5, apiModelsPath: `/formrecognizer/${apiVersion}/custom/models`, pdfjsWorkerSrc(version: string) { diff --git a/src/common/mockFactory.ts b/src/common/mockFactory.ts index a9780444e..4d4f07846 100644 --- a/src/common/mockFactory.ts +++ b/src/common/mockFactory.ts @@ -147,6 +147,7 @@ export default class MockFactory { apiUriBase: "localhost", folderPath: "", trainRecord: null, + recentModelRecords: [], predictModelId: "", }; } diff --git a/src/models/applicationState.ts b/src/models/applicationState.ts index b1748db34..1cba71c4c 100644 --- a/src/models/applicationState.ts +++ b/src/models/applicationState.ts @@ -94,6 +94,7 @@ export interface IProject { apiKey?: string | ISecureString; folderPath: string; trainRecord: ITrainRecordProps; + recentModelRecords: IRecentModel[]; predictModelId: string; } @@ -281,6 +282,18 @@ export interface IFieldInfo { 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 */ diff --git a/src/react/components/pages/modelCompose/modelCompose.tsx b/src/react/components/pages/modelCompose/modelCompose.tsx index a1c21e633..4cce0f19b 100644 --- a/src/react/components/pages/modelCompose/modelCompose.tsx +++ b/src/react/components/pages/modelCompose/modelCompose.tsx @@ -5,7 +5,7 @@ import React from "react"; import {connect} from "react-redux"; import url from "url"; 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 ServiceHelper from "../../../../services/serviceHelper"; import { IColumn, @@ -341,10 +341,8 @@ export default class ModelComposePage extends React.Component composedModelIds.indexOf(m.modelId) === -1); 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({ modelList: this.allModels, nextLink: link, @@ -377,10 +371,27 @@ export default class ModelComposePage extends React.Component { + 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 { ...this.props.project, - predictModelId: modelId, + recentModelRecords, + predictModelId: newTrainRecord.modelInfo.modelId, }; } @@ -399,7 +410,7 @@ export default class ModelComposePage extends React.Component { const composedRes = await this.getResponse(idURL); const composedModel: IModel = composedRes.data.modelInfo; - composedModel.iconName = "combine"; + composedModel.iconName = "Combine"; composedModel.key = composedModel.modelId; return composedModel; } @@ -632,18 +643,23 @@ export default class ModelComposePage extends React.Component { ncol.isSorted = false; ncol.isSortedDescending = true; }); + this.setState({ isComposing: false, - composeModelId: [composedModelId], + composeModelId: [composedModel["modelInfo"]["modelId"]], columns: newCols, }); } catch (error) { @@ -655,13 +671,6 @@ export default class ModelComposePage extends React.Component { - const location = composeRes["headers"]["location"]; - const splitGroup = location.split("/"); - return splitGroup[splitGroup.length - 1]; - } - private async post(link, payload): Promise { const baseURL = url.resolve( this.props.project.apiUriBase, diff --git a/src/react/components/pages/train/trainPage.tsx b/src/react/components/pages/train/trainPage.tsx index 5c8aa757f..5e04e5f5c 100644 --- a/src/react/components/pages/train/trainPage.tsx +++ b/src/react/components/pages/train/trainPage.tsx @@ -10,7 +10,7 @@ import IProjectActions, * as projectActions from "../../../../redux/actions/proj import IApplicationActions, * as applicationActions from "../../../../redux/actions/applicationActions"; import IAppTitleActions, * as appTitleActions from "../../../../redux/actions/appTitleActions"; import { - IApplicationState, IConnection, IProject, IAppSettings, FieldType, + IApplicationState, IConnection, IProject, IAppSettings, FieldType, IRecentModel, } from "../../../../models/applicationState"; import TrainChart from "./trainChart"; import TrainPanel from "./trainPanel"; @@ -327,8 +327,16 @@ export default class TrainPage extends React.Component { + 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 { ...this.props.project, + recentModelRecords, trainRecord: newTrainRecord, predictModelId: newTrainRecord.modelInfo.modelId, }; @@ -356,6 +364,7 @@ export default class TrainPage extends React.Component {this.props.modelInfo.modelId}

-
Model Name:
-

- {this.props.modelInfo.modelName} -

+ {this.props.modelInfo.modelName && + [ +
Model Name:
, +

+ {this.props.modelInfo.modelName} +

+ ] + }
Created date and time:

{new Date(this.props.modelInfo.createdDateTime).toLocaleString()}