Skip to content

Commit

Permalink
feat(nav-bar-functionality): Store expanded nav state in AssessmentSt…
Browse files Browse the repository at this point in the history
…ore and toggle nav link expansion state (#2768)

* Add callback for test header links

* Add message for expanding test

* Add assessment action for expanding test

* Store currently expanded test when action is triggered

* set isExpanded flag in test links

* rename/change messages and actions to only expand a test

* add message for collapsing test nav

* collapse test nav in store

* add separate action for collapsing nav
  • Loading branch information
pownkel authored Jun 1, 2020
1 parent c7f1b11 commit 0f7cd4e
Show file tree
Hide file tree
Showing 18 changed files with 271 additions and 9 deletions.
18 changes: 18 additions & 0 deletions src/DetailsView/actions/details-view-action-message-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ChangeInstanceStatusPayload,
ChangeRequirementStatusPayload,
EditFailureInstancePayload,
ExpandTestNavPayload,
OnDetailsViewOpenPayload,
OnDetailsViewPivotSelected,
RemoveFailureInstancePayload,
Expand Down Expand Up @@ -195,6 +196,23 @@ export class DetailsViewActionMessageCreator extends DevToolActionMessageCreator
});
}

public expandTestNav(visualizationType: VisualizationType): void {
const payload: ExpandTestNavPayload = {
selectedTest: visualizationType,
};

this.dispatcher.dispatchMessage({
messageType: Messages.Assessment.ExpandTestNav,
payload: payload,
});
}

public collapseTestNav(): void {
this.dispatcher.dispatchMessage({
messageType: Messages.Assessment.CollapseTestNav,
});
}

public sendPivotItemClicked(pivotKey: string, ev?: React.MouseEvent<HTMLElement>): void {
const telemetry = this.telemetryFactory.forDetailsViewNavPivotActivated(ev, pivotKey);

Expand Down
16 changes: 15 additions & 1 deletion src/DetailsView/components/left-nav/assessment-left-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ export type AssessmentLeftNavProps = {
assessmentsProvider: AssessmentsProvider;
assessmentsData: DictionaryStringTo<ManualTestStatusData>;
featureFlagStoreData: FeatureFlagStoreData;
expandedTest: VisualizationType | undefined;
};

export type AssessmentLeftNavLink = {
status: ManualTestStatus;
} & BaseLeftNavLink;

export type ReflowAssessmentLeftNavLink = {
testType: VisualizationType;
status: ManualTestStatus;
} & BaseLeftNavLink;

export type TestGettingStartedNavLink = {
testType: VisualizationType;
} & BaseLeftNavLink;
Expand All @@ -55,7 +61,14 @@ export type onTestGettingStartedClick = (
) => void;

export const AssessmentLeftNav = NamedFC<AssessmentLeftNavProps>('AssessmentLeftNav', props => {
const { deps, selectedKey, assessmentsProvider, assessmentsData, featureFlagStoreData } = props;
const {
deps,
selectedKey,
assessmentsProvider,
assessmentsData,
featureFlagStoreData,
expandedTest,
} = props;

const { navLinkHandler, leftNavLinkBuilder } = deps;

Expand All @@ -77,6 +90,7 @@ export const AssessmentLeftNav = NamedFC<AssessmentLeftNavProps>('AssessmentLeft
assessmentsProvider,
assessmentsData,
1,
expandedTest,
),
);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const DetailsViewLeftNav = NamedFC<DetailsViewLeftNavProps>('DetailsViewL
data => data.testStepStatus,
)}
featureFlagStoreData={featureFlagStoreData}
expandedTest={assessmentStoreData.assessmentNavState.expandedTestType}
/>
</div>
);
Expand Down
19 changes: 15 additions & 4 deletions src/DetailsView/components/left-nav/left-nav-link-builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { gettingStartedSubview } from 'common/types/store-data/assessment-result
import {
onTestGettingStartedClick,
onTestRequirementClick,
ReflowAssessmentLeftNavLink,
TestGettingStartedNavLink,
TestRequirementLeftNavLink,
} from 'DetailsView/components/left-nav/assessment-left-nav';
Expand Down Expand Up @@ -137,12 +138,20 @@ export class LeftNavLinkBuilder {
assessmentsProvider: AssessmentsProvider,
assessmentsData: DictionaryStringTo<ManualTestStatusData>,
startingIndex: number,
expandedTest: VisualizationType | undefined,
): BaseLeftNavLink[] {
const assessments = assessmentsProvider.all();
let index = startingIndex;

const allTestLinks = map(assessments, assessment => {
const test = this.buildAssessmentLink(deps, assessment, index, assessmentsData);
const isExpanded = assessment.visualizationType === expandedTest;
const test = this.buildAssessmentLink(
deps,
assessment,
index,
assessmentsData,
isExpanded,
);
index++;
return test;
});
Expand All @@ -155,7 +164,8 @@ export class LeftNavLinkBuilder {
assessment: Assessment,
index: number,
assessmentsData: DictionaryStringTo<ManualTestStatusData>,
) => {
isExpanded: boolean,
): ReflowAssessmentLeftNavLink => {
const {
getStatusForTest,
outcomeTypeSemanticsFromTestStatus,
Expand All @@ -175,7 +185,7 @@ export class LeftNavLinkBuilder {
VisualizationType[assessment.visualizationType],
index,
navLinkRenderer.renderAssessmentTestLink,
() => {},
navLinkHandler.onTestHeadingClick,
);

const gettingStartedLink = this.buildGettingStartedLink(
Expand All @@ -202,7 +212,8 @@ export class LeftNavLinkBuilder {
status,
title: `${index}: ${name} (${narratorTestStatus})`,
links: [gettingStartedLink, ...requirementLinks],
isExpanded: true,
isExpanded: isExpanded,
testType: assessment.visualizationType,
};

return testLink;
Expand Down
12 changes: 12 additions & 0 deletions src/DetailsView/components/left-nav/nav-link-handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import {
ReflowAssessmentLeftNavLink,
TestGettingStartedNavLink,
TestRequirementLeftNavLink,
} from 'DetailsView/components/left-nav/assessment-left-nav';
Expand Down Expand Up @@ -56,4 +57,15 @@ export class NavLinkHandler {
this.detailsViewActionMessageCreator.selectGettingStarted(event, item.testType);
this.detailsViewActionMessageCreator.changeRightContentPanel('TestView');
};

public onTestHeadingClick = (
event: React.MouseEvent<HTMLElement>,
item: ReflowAssessmentLeftNavLink,
) => {
if (item.isExpanded) {
this.detailsViewActionMessageCreator.collapseTestNav();
} else {
this.detailsViewActionMessageCreator.expandTestNav(item.testType);
}
};
}
4 changes: 4 additions & 0 deletions src/background/actions/action-payloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export interface SelectGettingStartedPayload extends BaseActionPayload {
selectedTest: VisualizationType;
}

export interface ExpandTestNavPayload extends BaseActionPayload {
selectedTest: VisualizationType;
}

export interface AssessmentToggleActionPayload extends ToggleActionPayload {
requirement: string;
}
Expand Down
17 changes: 17 additions & 0 deletions src/background/actions/assessment-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ChangeInstanceStatusPayload,
ChangeRequirementStatusPayload,
EditFailureInstancePayload,
ExpandTestNavPayload,
OnDetailsViewOpenPayload,
RemoveFailureInstancePayload,
SelectGettingStartedPayload,
Expand All @@ -47,6 +48,14 @@ export class AssessmentActionCreator {
AssessmentMessages.SelectGettingStarted,
this.onSelectGettingStarted,
);
this.interpreter.registerTypeToPayloadCallback(
AssessmentMessages.ExpandTestNav,
this.onExpandTestNav,
);
this.interpreter.registerTypeToPayloadCallback(
AssessmentMessages.CollapseTestNav,
this.onCollapseTestNav,
);
this.interpreter.registerTypeToPayloadCallback(
getStoreStateMessage(StoreNames.AssessmentStore),
this.onGetAssessmentCurrentState,
Expand Down Expand Up @@ -246,6 +255,14 @@ export class AssessmentActionCreator {
);
};

private onExpandTestNav = (payload: ExpandTestNavPayload): void => {
this.assessmentActions.expandTestNav.invoke(payload);
};

private onCollapseTestNav = (): void => {
this.assessmentActions.collapseTestNav.invoke(null);
};

private onScanUpdate = (payload: ScanUpdatePayload): void => {
const telemetryEventName = 'ScanUpdate' + capitalize(payload.key);
this.telemetryEventHandler.publishTelemetry(telemetryEventName, payload);
Expand Down
3 changes: 3 additions & 0 deletions src/background/actions/assessment-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ChangeInstanceStatusPayload,
ChangeRequirementStatusPayload,
EditFailureInstancePayload,
ExpandTestNavPayload,
RemoveFailureInstancePayload,
SelectTestSubviewPayload,
ToggleActionPayload,
Expand All @@ -22,6 +23,8 @@ import {

export class AssessmentActions {
public readonly selectTestSubview = new Action<SelectTestSubviewPayload>();
public readonly expandTestNav = new Action<ExpandTestNavPayload>();
public readonly collapseTestNav = new Action<null>();
public readonly changeInstanceStatus = new Action<ChangeInstanceStatusPayload>();
public readonly changeRequirementStatus = new Action<ChangeRequirementStatusPayload>();
public readonly addFailureInstance = new Action<AddFailureInstancePayload>();
Expand Down
18 changes: 17 additions & 1 deletion src/background/stores/assessment-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import {
} from 'injected/analyzers/analyzer';
import { forEach, isEmpty, pickBy } from 'lodash';
import { DictionaryStringTo } from 'types/common-types';
import { AddResultDescriptionPayload, SelectTestSubviewPayload } from '../actions/action-payloads';
import {
AddResultDescriptionPayload,
ExpandTestNavPayload,
SelectTestSubviewPayload,
} from '../actions/action-payloads';
import { AssessmentDataConverter } from '../assessment-data-converter';
import { InitialAssessmentStoreDataGenerator } from '../initial-assessment-store-data-generator';
import {
Expand Down Expand Up @@ -108,6 +112,8 @@ export class AssessmentStore extends BaseStoreImpl<AssessmentStoreData> {
this.assessmentActions.resetData.addListener(this.onResetData);
this.assessmentActions.resetAllAssessmentsData.addListener(this.onResetAllAssessmentsData);
this.assessmentActions.selectTestSubview.addListener(this.onSelectTestSubview);
this.assessmentActions.expandTestNav.addListener(this.onExpandTestNav);
this.assessmentActions.collapseTestNav.addListener(this.onCollapseTestNav);
this.assessmentActions.changeInstanceStatus.addListener(this.onChangeInstanceStatus);
this.assessmentActions.changeRequirementStatus.addListener(this.onChangeStepStatus);
this.assessmentActions.undoRequirementStatusChange.addListener(this.onUndoStepStatusChange);
Expand Down Expand Up @@ -370,6 +376,16 @@ export class AssessmentStore extends BaseStoreImpl<AssessmentStoreData> {
this.emitChanged();
};

private onExpandTestNav = (payload: ExpandTestNavPayload): void => {
this.state.assessmentNavState.expandedTestType = payload.selectedTest;
this.emitChanged();
};

private onCollapseTestNav = (): void => {
this.state.assessmentNavState.expandedTestType = null;
this.emitChanged();
};

private onScanCompleted = (payload: ScanCompletedPayload<any>): void => {
const test = payload.testType;
const step = payload.key;
Expand Down
2 changes: 2 additions & 0 deletions src/common/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ export class Messages {
public static readonly Assessment = {
SelectTestRequirement: `${messagePrefix}/details-view/requirement/select`,
SelectGettingStarted: `${messagePrefix}/details-view/select-getting-started`,
ExpandTestNav: `${messagePrefix}/details-view/expand-test-nav`,
CollapseTestNav: `${messagePrefix}/details-view/collapse-test-nav`,
AssessmentScanCompleted: `${messagePrefix}/assessment/scanComplete`,
TabbedElementAdded: `${messagePrefix}/assessment/tab-stops/element-added`,
TrackingCompleted: `${messagePrefix}/assessment/tab-stops/recording-completed`,
Expand Down
1 change: 1 addition & 0 deletions src/common/types/store-data/assessment-result-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface TestStepResult {
export interface AssessmentNavState {
selectedTestSubview: RequirementName | GettingStarted;
selectedTestType: VisualizationType;
expandedTestType?: VisualizationType;
}

export interface HeadingsAssessmentProperties {
Expand Down
5 changes: 5 additions & 0 deletions src/tests/unit/common/assessment-store-data-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export class AssessmentsStoreDataBuilder extends BaseDataBuilder<AssessmentStore
return this;
}

public withExpandedTest(visualizationType: VisualizationType): AssessmentsStoreDataBuilder {
this.data.assessmentNavState.expandedTestType = visualizationType;
return this;
}

public withTargetTab(
id: number,
url: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,37 @@ describe('DetailsViewActionMessageCreatorTest', () => {
);
});

test('expandTestNav', () => {
const view = VisualizationType.Headings;

const expectedMessage = {
messageType: Messages.Assessment.ExpandTestNav,
payload: {
selectedTest: view,
},
};

testSubject.expandTestNav(view);

dispatcherMock.verify(
dispatcher => dispatcher.dispatchMessage(It.isValue(expectedMessage)),
Times.once(),
);
});

test('collapseTestNav', () => {
const expectedMessage = {
messageType: Messages.Assessment.CollapseTestNav,
};

testSubject.collapseTestNav();

dispatcherMock.verify(
dispatcher => dispatcher.dispatchMessage(It.isValue(expectedMessage)),
Times.once(),
);
});

test('setFeatureFlag', () => {
const event = eventStubFactory.createKeypressEvent() as any;
const telemetry: FeatureFlagToggleTelemetryData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.
import { AssessmentsProvider } from 'assessments/types/assessments-provider';
import { FeatureFlags } from 'common/feature-flags';
import { VisualizationType } from 'common/types/visualization-type';
import { shallow } from 'enzyme';
import * as React from 'react';
import { IMock, Mock, MockBehavior } from 'typemoq';
Expand All @@ -27,6 +28,7 @@ describe('AssessmentLeftNav', () => {
let navLinkHandlerMock: NavLinkHandler;
let assessmentsProviderStub: AssessmentsProvider;
let assessmentsDataStub: DictionaryStringTo<ManualTestStatusData>;
const expandedTest: VisualizationType = 1;

beforeEach(() => {
assessmentsDataStub = {};
Expand All @@ -50,6 +52,7 @@ describe('AssessmentLeftNav', () => {
assessmentsProvider: assessmentsProviderStub,
assessmentsData: assessmentsDataStub,
featureFlagStoreData: {},
expandedTest,
};

leftNavLinkBuilderMock
Expand All @@ -75,6 +78,7 @@ describe('AssessmentLeftNav', () => {
assessmentsProviderStub,
assessmentsDataStub,
1,
expandedTest,
),
)
.returns(() => [linkStub]);
Expand Down
Loading

0 comments on commit 0f7cd4e

Please sign in to comment.