Skip to content

Commit

Permalink
feat: support adding model to recent models from compose page (micros…
Browse files Browse the repository at this point in the history
…oft#510)

* feat: support adding model to recent models from compose page

* fix: resolve tslint issues

* docs: add manual test case

* fix: change text of add to recent models button
  • Loading branch information
stew-ro authored Aug 24, 2020
1 parent 2402cba commit 65fc92b
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 22 deletions.
37 changes: 37 additions & 0 deletions docs/manual_testing/manual-test-runbook.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
# Test Runbook

## **Feat: support adding models to project's recent models from the model compose page**

> ### Feature description ###
- add a "add to recent models" button in the model information view after double clicking a model

> ### Use Case ###
**As** a user
**I want** add a model from the model compose page to myu recent models
**So** that I can anaylze with that model

> ### Acceptance criteria ###
#### Scenario One ####

**Given** I'm on the model compose page
**When** I double click on any model that has a ready status
**Then** I should see it's model information and an add to recent projects button

#### Scenario Two ####

**Given** I'm on the model compose page and have double clicked on a model
**When** I click the add to recent projects button and then go to the analyze page
**Then** I should see the added model as the current model to analyze with

#### Scenario Three ####

**Given** I'm on the model compose page and have double clicked on a model
**When** I click the add to recent projects button, then go to the analyze page, and analyze a document
**Then** I should see the analysis results using the model added

#### Scenario Four ####

**Given** I've added multiple models to my projects recent models from the model compose page
**When** I go the analyze page and click change model
**Then** I should see up to the 5 most recent models

## **Feat: add composedNames popup for each model**

> ### Feature description ###
Expand Down
9 changes: 6 additions & 3 deletions src/common/localization/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ export const english: IAppStrings = {
addComposeModelName: "Add compose model name...",
NotEnoughModels: " Should have at least more than one selected model to compose a new model",
modelsCannotBeIncluded: "Warning: These models will not be included in composed model!",
modelCannotBeIncluded: "Warning: This model will not be included in composed model!"
modelCannotBeIncluded: "Warning: This model will not be included in composed model!",
addModelToRecentModels: "Model [${modelID}] added to recent models",
recentModelsAlreadyContainsModel: "Recent models already contains model [${modelID}]",
},
commandBar: {
ariaLabel: "Please use command bar to compose models",
Expand Down Expand Up @@ -198,9 +200,10 @@ export const english: IAppStrings = {
defaultLocalFileInput: "Browse for a file...",
defaultURLInput: "Paste or type URL...",
},
recentModelsView:{
recentModelsView: {
header: "Select a model to analyze with",
checkboxAriaLabel: "Select model checkbox"
checkboxAriaLabel: "Select model checkbox",
addToRecentModels: "Select to analyze with",
},
projectMetrics: {
title: "Project Metrics",
Expand Down
3 changes: 3 additions & 0 deletions src/common/localization/es-cl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ export const spanish: IAppStrings = {
NotEnoughModels: "Debe tener más de un modelo seleccionado para componer un nuevo modelo",
modelsCannotBeIncluded: "Advertencia: ¡estos modelos no se incluirán en el modelo compuesto!",
modelCannotBeIncluded: "Advertencia: ¡Este modelo no se incluirá en el modelo compuesto!",
addModelToRecentModels: "Modelo [${modelID}] agregado a modelos recientes",
recentModelsAlreadyContainsModel: "Los modelos recientes ya contienen el modelo [${modelID}]",
},
commandBar: {
ariaLabel: "Utilice la barra de comandos para componer modelos",
Expand Down Expand Up @@ -201,6 +203,7 @@ export const spanish: IAppStrings = {
recentModelsView: {
header: "Seleccionar modelo para analizar con",
checkboxAriaLabel: "Seleccione la casilla de verificación del modelo",
addToRecentModels: "Seleccionar para analizar con"
},
projectMetrics: {
title: "Métricas del proyecto",
Expand Down
3 changes: 3 additions & 0 deletions src/common/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ export interface IAppStrings {
NotEnoughModels: string;
modelsCannotBeIncluded: string;
modelCannotBeIncluded: string;
addModelToRecentModels: string,
recentModelsAlreadyContainsModel: string,
}
commandBar: {
ariaLabel: string;
Expand Down Expand Up @@ -200,6 +202,7 @@ export interface IAppStrings {
recentModelsView: {
header: string;
checkboxAriaLabel: string;
addToRecentModels: string;
}
projectMetrics: {
title: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class CondensedList extends React.Component<ICondensedListProps>
{newLinkTo &&
<Link to={newLinkTo} className="float-right add-button" role="button" title={newLinkToTitle}
id="addConnection">
<FontIcon iconName="Add" />
<FontIcon iconName="AddTo" />
</Link>
}
</div>
Expand Down
77 changes: 63 additions & 14 deletions src/react/components/pages/modelCompose/composeModelView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import { strings } from "../../../../common/strings";
import { IModel } from "./modelCompose";
import { getAppInsights } from '../../../../services/telemetryService';
import "./modelCompose.scss";
import { IRecentModel } from "../../../../models/applicationState";


export interface IComposeModelViewProps {
onComposeConfirm: (composeModelName: string) => void;
addToRecentModels: (modelToAdd: IRecentModel) => void;
}

export interface IComposeModelViewState {
Expand Down Expand Up @@ -179,25 +181,72 @@ export default class ComposeModelView extends React.Component<IComposeModelViewP
</div>
</>
}
{
!this.state.composing &&
{!this.state.composing &&
<>
<h5 style={{whiteSpace: 'pre'}}>{"Model " + this.state.items["modelId"] + " " + (this.state.items["modelName"] ? `(${this.state.items["modelName"]})` : "") + "\ncreated on " + new Date(this.state.items["createdDateTime"]).toLocaleString() + "\nincludes following models:"}</h5>
<DetailsList
items={this.state.items["composedTrainResults"]}
columns={modelDetailsColumns}
compact={true}
setKey="none"
selectionMode={SelectionMode.none}
isHeaderVisible={true}
layoutMode={DetailsListLayoutMode.justified}
/>
<div className="modal-buttons-container">
<h4>
Model information
</h4>
<div className="model-information-container">
<h6 className="mr-2 model-information-prop">
{"Model ID: "}
</h6>
{this.state.items["modelId"]}
</div>
{this.state.items["modelName"] &&
<div className="model-information-container">
<h6 className="mr-2 model-information-prop">
Model name:
</h6> {this.state.items["modelName"]}
</div>
}
<div className="model-information-container">
<h6 className="mr-2 model-information-prop">
Created date:
</h6>
{new Date(this.state.items["createdDateTime"]).toLocaleString()}
</div>
{this.state.items?.["composedTrainResults"]?.length > 0 &&
<>
<h6 className="mb-0">
Composed of:
</h6>
<div className="mr-4 ml-4 mb-2 composed-of-list">
<DetailsList
items={this.state.items["composedTrainResults"]}
columns={modelDetailsColumns}
compact={true}
setKey="none"
selectionMode={SelectionMode.none}
isHeaderVisible={true}
layoutMode={DetailsListLayoutMode.justified}
/>
</div>
</>
}
<div className="modal-buttons-container mt-4">
<PrimaryButton
className="mr-3"
theme={getPrimaryGreenTheme()}
onClick={() => {
this.props.addToRecentModels({
modelInfo: {
isComposed: Boolean(this.state.items["composedTrainResults"]),
modelId: this.state.items["modelId"],
createdDateTime: this.state.items["createdDateTime"],
modelName: this.state.items?.["modelName"],
}
})
}}
>
{strings.recentModelsView.addToRecentModels}
</PrimaryButton>
<PrimaryButton
className="modal-cancel"
theme={getPrimaryGreyTheme()}
onClick={this.close}
>Close</PrimaryButton>
>
Close
</PrimaryButton>
</div>
</>}
</Modal>
Expand Down
13 changes: 13 additions & 0 deletions src/react/components/pages/modelCompose/modelCompose.scss
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,16 @@ h4 {
background: transparent;
}
}

.model-information-container {
display: flex;
flex-flow: row wrap;
}

.model-information-prop {
min-width: 100px;
}

.composed-of-list .ms-DetailsHeader {
padding-top: 6px;
}
41 changes: 38 additions & 3 deletions src/react/components/pages/modelCompose/modelCompose.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { IColumn,
ScrollbarVisibility,
IDetailsRowProps } from "@fluentui/react";
import "./modelCompose.scss";
import { strings } from "../../../../common/strings";
import { strings, interpolate } from "../../../../common/strings";
import { getDarkGreyTheme, getDefaultDarkTheme } from "../../../../common/themes";
import { ModelComposeCommandBar } from "./composeCommandBar";
import { bindActionCreators } from "redux";
Expand Down Expand Up @@ -340,8 +340,9 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
</ScrollablePane>
</div>
<ComposeModelView
ref={this.composeModalRef}
onComposeConfirm={this.onComposeConfirm}
ref={this.composeModalRef}
onComposeConfirm={this.onComposeConfirm}
addToRecentModels={this.addToRecentModels}
/>
</Customizer>
</Fabric>
Expand Down Expand Up @@ -389,6 +390,8 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
}
}
this.composeModalRef.current.open(composedModelInfo, false, false);
} else if (model.status === constants.statusCodeReady) {
this.composeModalRef.current.open(composedModelInfo, false, false);
}
}

Expand Down Expand Up @@ -637,6 +640,38 @@ export default class ModelComposePage extends React.Component<IModelComposePageP
this.handleModelsCompose(selections, composeModelName);
}

private addToRecentModels = async (modelToAdd: IRecentModel) => {
const recentModelRecords: IRecentModel[] = this.props.project.recentModelRecords ?
[...this.props.project.recentModelRecords] : [];

if (recentModelRecords.find((recentModel) => recentModel.modelInfo.modelId === modelToAdd.modelInfo.modelId)) {
if (modelToAdd.modelInfo.modelName) {
toast.success(interpolate(strings.modelCompose.modelView.recentModelsAlreadyContainsModel, {modelID: modelToAdd.modelInfo.modelName}));
} else {
toast.success(interpolate(strings.modelCompose.modelView.recentModelsAlreadyContainsModel, {modelID: modelToAdd.modelInfo.modelId}));
}
this.composeModalRef.current.close();
return;
}
recentModelRecords.unshift({...modelToAdd} as IRecentModel);
if (recentModelRecords.length > constants.recentModelRecordsCount) {
recentModelRecords.pop();
}

const updatedProject = {
...this.props.project,
recentModelRecords,
predictModelId: modelToAdd.modelInfo.modelId,
};
this.composeModalRef.current.close();
if (modelToAdd.modelInfo.modelName) {
toast.success(interpolate(strings.modelCompose.modelView.addModelToRecentModels, {modelID: modelToAdd.modelInfo.modelName}));
} else {
toast.success(interpolate(strings.modelCompose.modelView.addModelToRecentModels, {modelID: modelToAdd.modelInfo.modelId}));
}
await this.props.actions.saveProject(updatedProject, false, false);
}

private passSelectedItems = (Items: any[]) => {
this.cannotBeIncludedItems = Items.filter((item: IModel) => item.status !== constants.statusCodeReady);
this.selectedItems = Items.filter((item: IModel) => item.status === constants.statusCodeReady);
Expand Down
2 changes: 1 addition & 1 deletion src/react/components/pages/train/trainRecord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FontIcon } from "@fluentui/react";

export interface ITrainRecordProps {
accuracies?: object;
averageAccuracy: number;
averageAccuracy?: number;
modelInfo: {
isComposed?: boolean;
modelId: string;
Expand Down

0 comments on commit 65fc92b

Please sign in to comment.