Skip to content

Commit

Permalink
Merged PR 278: Merge chmason/updated-controls to master
Browse files Browse the repository at this point in the history
Changed column mapping to pivot on the dialog bottom, changed team selection dropdown, and added message for what settings will be copied.
  • Loading branch information
chrismason committed Feb 22, 2018
2 parents 4b2ffc2 + 26778c5 commit fc736f6
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 89 deletions.
2 changes: 1 addition & 1 deletion src/Kanban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class KanbanBoardToolsAction {
let hostDialogOptions: IHostDialogOptions = {
title: Constants.DefaultDialogTitle,
width: 700,
height: 500,
height: 550,
close: this._closeDialog,
resizable: true,
modal: true,
Expand Down
3 changes: 2 additions & 1 deletion src/Shared/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export const ApplySettingsLevelsLabel: string = "Apply settings at the following
export const SettingsToCopyLabel: string = "Select settings to copy";
export const EnableAdvancedMappings: string = "Customize column mappings";
export const MappingsHeader: string = "Column mappings";
export const MappingsDescription: string = "The following columns have multiple options available to move existing work items into.";
export const MappingsDescription: string = "Columns here have multiple options available to move existing work items into.";
export const NoMappingsAvailable: string = "No columns to be adjusted for this backlog level";

export const LoadingTeamsLabel: string = "Loading teams";
export const LoadingBacklogsLabel: string = "Updating backlogs";
Expand Down
5 changes: 3 additions & 2 deletions src/Views/CopySettings/Actions/CopySettingsActionsCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class CopySettingsActionsCreator {

public selectTeam(teamName: string) {
this._copySettingsActionsHub.setBacklogsLoading.invoke(true);
this.enabledAdvancedMappings(false);
this._validateUI();
this._client.loadSelectedTeam(teamName).then(() => {
let commonLevels = this._client.commonBackgroundLevels;
Expand Down Expand Up @@ -58,7 +59,7 @@ export class CopySettingsActionsCreator {
}

public enabledAdvancedMappings(enabled: boolean) {
this._copySettingsActionsHub.setCanDoAdvancedMapping.invoke(this._canEnableAdvancedMapping() && !enabled);
this._copySettingsActionsHub.setCanDoAdvancedMapping.invoke(this._canEnableAdvancedMapping());
this._copySettingsActionsHub.setShowAdvancedMapping.invoke(enabled);
this._validateUI();
}
Expand Down Expand Up @@ -102,7 +103,7 @@ export class CopySettingsActionsCreator {

private _canEnableAdvancedMapping(): boolean {
let state = this._getState();
return state.copySettingsState.selectedBacklogLevels.length > 0;
return state.copySettingsState.selectedBacklogLevels && state.copySettingsState.selectedBacklogLevels.length > 0;
}

private _copyArray(array: any[]): any[] {
Expand Down
4 changes: 4 additions & 0 deletions src/Views/CopySettings/Components/AdvancedItemMapping.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.lastItem {
padding-bottom: 66px;
}

.pivotContent {
margin-top: 15px;
}
91 changes: 40 additions & 51 deletions src/Views/CopySettings/Components/AdvancedItemMapping.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from "react";

import { Panel, PanelType } from "office-ui-fabric-react/lib/Panel";
import { GroupedList, IGroup, IGroupDividerProps } from "office-ui-fabric-react/lib/GroupedList";
import { css } from "office-ui-fabric-react/lib/Utilities";
import { Dropdown, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown";
import { IBoardColumnDifferences, IColumnMapping } from "src/Views/CopySettings/Models/CopySettingsInterfaces";
import { Pivot, PivotItem } from "office-ui-fabric-react/lib/Pivot";
import { List } from "office-ui-fabric-react/lib/List";
import * as Constants from "src/Shared/Constants";

import "./AdvancedItemMapping.scss";
Expand All @@ -27,58 +27,59 @@ export class AdvancedItemMapping extends React.Component<IAdvancedItemMappingPro
}

public render() {
let groups: IGroup[] = [];
let mappingItems: IColumnMapping[] = [];
let startIndex = 0;
if (!this.props.mappings) {
if (!this.props.mappings || !this.props.show) {
return null;
}

let mappingsOfInterest: IBoardColumnDifferences[] = [];

this.props.mappings.forEach(mapping => {
if (this.props.selectedLevels.indexOf(mapping.backlog) >= 0) {
let multipleMappings = mapping.mappings.filter(m => m.potentialMatches.length > 1);
mappingItems = mappingItems.concat(multipleMappings);
groups.push({
key: mapping.backlog,
name: mapping.backlog,
startIndex: startIndex,
count: multipleMappings.length
});
startIndex = startIndex + multipleMappings.length;
mappingsOfInterest.push(mapping);
}
});
this._itemsCount = mappingItems.length;
return (
<div>
<Panel
hasCloseButton={true}
isOpen={this.props.show}
type={PanelType.extraLarge}
headerText={this.props.headerText}
isLightDismiss={false}
onDismiss={this._onPanelDismissed}>
<div>
<div className={css("formContent", "ms-font-m")}>
{Constants.MappingsDescription}
</div>
<div>
<GroupedList
items={mappingItems}
groups={groups}
onRenderCell={this._onRenderCell}
groupProps={
{
onRenderHeader: this._onRenderGroupHeader
}
}
/>
</div>
</div>
</Panel>
<div className={css("ms-font-m")}>
{Constants.MappingsDescription}
</div>
<div>
<Pivot>
{mappingsOfInterest.map((mapping, mapIndex, allMappings) => {
return (
<PivotItem linkText={mapping.backlog}>
{this._renderPivotContent(mapping)}
</PivotItem>
);
})}
</Pivot>
</div>
</div>
);
}

private _onRenderCell = (nestingDepth: number, item: IColumnMapping, itemIndex: number) => {
private _renderPivotContent(mapping: IBoardColumnDifferences): JSX.Element {
let content: JSX.Element;

let multipleMappings = mapping.mappings.filter(m => m.potentialMatches.length > 1);
if (multipleMappings.length === 0) {
content =
<div className={css("pivotContent", "ms-font-m")}>
{Constants.NoMappingsAvailable}
</div>;
} else {
content =
<List
items={multipleMappings}
onRenderCell={this._onRenderCell} />;
}
return content;
}

private _onRenderCell = (item: IColumnMapping, itemIndex: number) => {
let dropdownOptions: IDropdownOption[] = [];
item.potentialMatches.forEach(match => {
dropdownOptions.push({
Expand All @@ -105,16 +106,4 @@ export class AdvancedItemMapping extends React.Component<IAdvancedItemMappingPro
private _onMappingChanged = (item: IDropdownOption) => {
this.props.onMappingChanged(item.key.toString(), item.data.toString());
}

private _onRenderGroupHeader = (props: IGroupDividerProps): JSX.Element => {
return (
<div className={css("ms-font-xl")}>
{props.group.name}
</div>
);
}

private _onPanelDismissed = (): void => {
this.props.onClosed();
}
}
19 changes: 10 additions & 9 deletions src/Views/CopySettings/Components/CopySettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import { CopySettingsActionsHub } from "src/Views/CopySettings/Actions/CopySetti
import { CopySettingsStoreHub, CopyState } from "src/Views/CopySettings/Stores/CopySettingsStoreHub";
import { AdvancedItemMapping } from "src/Views/CopySettings/Components/AdvancedItemMapping";
import { SelectBacklogLevels } from "src/Views/CopySettings/Components/SelectBacklogLevels";
import { SettingsToCopy } from "src/Views/CopySettings/Components/SettingsToCopy";
import { SelectTeam } from "src/Views/CopySettings/Components/SelectTeam";
import * as Constants from "src/Shared/Constants";
import { ServicesClient } from "src/Shared/ServicesClient";
import { PrimaryButton } from "office-ui-fabric-react/lib/Button";
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
import { Telemetry } from "src/TelemetryClientSettings";

export interface ICopySettingsViewProps {
Expand Down Expand Up @@ -52,7 +53,6 @@ export class CopySettingsView extends React.Component<ICopySettingsViewProps, Co

public componentWillUpdate(nextProps: ICopySettingsViewProps, nextState: CopyState) {
this._copySettingsActionsCreator.updateViewState(nextProps.sharedState.dialogState.view);
// this._servicesClient.setViewState(nextProps.sharedState.dialogState.view);
}

public render() {
Expand All @@ -77,15 +77,16 @@ export class CopySettingsView extends React.Component<ICopySettingsViewProps, Co
availableLevels={this.state.copySettingsState.commonBacklogLevels}
selectedLevels={this.state.copySettingsState.selectedBacklogLevels}
isLoading={this.state.copySettingsState.backlogsLoading}
selectedSettings={this.state.copySettingsState.settingsToCopy}
label={Constants.ApplySettingsLevelsLabel}
onBacklogLevelSelected={this._onSelectBacklogLevel} />
</div>
<div className="formContent">
<PrimaryButton
onClick={this._onOpenAdvancedMappings}
disabled={!this._copySettingsStoreHub.copySettingsStore.state.canToggleMappings}>
{Constants.EnableAdvancedMappings}
</PrimaryButton>
<Toggle
checked={this.state.copySettingsState.showAdvancedMappings}
onChanged={this._onOpenAdvancedMappings}
label={Constants.EnableAdvancedMappings}
disabled={!this._copySettingsStoreHub.copySettingsStore.state.canToggleMappings || this.state.copySettingsState.backlogsLoading} />
</div>
<div>
<AdvancedItemMapping
Expand Down Expand Up @@ -116,9 +117,9 @@ export class CopySettingsView extends React.Component<ICopySettingsViewProps, Co
this._copySettingsActionsCreator.selectBacklogLevel(level, isSelected);
}

private _onOpenAdvancedMappings = () => {
private _onOpenAdvancedMappings = (checked: boolean) => {
Telemetry.Client().trackEvent(Constants.TelemetryAdvancedMapping);
this._copySettingsActionsCreator.enabledAdvancedMappings(true);
this._copySettingsActionsCreator.enabledAdvancedMappings(checked);
}

private _onAdvancedMappingClosed = () => {
Expand Down
10 changes: 9 additions & 1 deletion src/Views/CopySettings/Components/SelectBacklogLevels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import * as React from "react";
import { Dropdown, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown";
import { Spinner, SpinnerType } from "office-ui-fabric-react/lib/Spinner";
import { Label } from "office-ui-fabric-react/lib/Label";
import { SettingsToCopy } from "src/Views/CopySettings/Components/SettingsToCopy";
import * as Constants from "src/Shared/Constants";

export interface ISelectBacklogLevelsProps {
availableLevels: string[];
selectedLevels: string[];
label: string;
selectedSettings: string[];
isLoading: boolean;
onBacklogLevelSelected: (team: string, isSelected: boolean) => void;
}
Expand Down Expand Up @@ -55,7 +57,13 @@ export class SelectBacklogLevels extends React.Component<ISelectBacklogLevelsPro
}
return (
<div>
{content}
<div>
{content}
</div>
<div>
<SettingsToCopy
selectedSettings={this.props.selectedSettings} />
</div>
</div>
);
}
Expand Down
59 changes: 39 additions & 20 deletions src/Views/CopySettings/Components/SelectTeam.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from "react";

import * as CoreContracts from "TFS/Core/Contracts";
import { Dropdown, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown";
import { Spinner, SpinnerType } from "office-ui-fabric-react/lib/Spinner";
import { Label } from "office-ui-fabric-react/lib/Label";
import { SelectionMode } from "office-ui-fabric-react";
import { PickList, PickListDropdown, IPickListSelection, IPickListItem } from "vss-ui/PickList";
import * as Constants from "src/Shared/Constants";

export interface ISelectTeamProps {
Expand All @@ -15,22 +16,26 @@ export interface ISelectTeamProps {
placeHolder?: string;
}

export class SelectTeam extends React.Component<ISelectTeamProps, {}> {
export interface ITeamsPickerState {
selectedItems: IPickListItem[];
}

export class SelectTeam extends React.Component<ISelectTeamProps, ITeamsPickerState> {
constructor(props: ISelectTeamProps) {
super(props);

this.state = {
selectedItems: []
};
}

public render() {
let options: IDropdownOption[] = [];
if (this.props.availableTeams) {
this.props.availableTeams.map(team => {
const teamOption: IDropdownOption = {
key: team.id,
text: team.name
};
options.push(teamOption);
});
}
const options: IPickListItem[] = this.props.availableTeams.map((team, index) => {
return {
name: team.name,
key: team.id
};
});
let content: JSX.Element = null;
if (this.props.label !== "" && options.length === 0) {
content =
Expand All @@ -44,12 +49,21 @@ export class SelectTeam extends React.Component<ISelectTeamProps, {}> {
</div>;
} else if (this.props.label !== "" && options.length > 0) {
content =
<Dropdown
placeHolder={Constants.SelectTeamPlaceholder}
label={this.props.label}
options={options}
disabled={options.length === 0 || this.props.disabled}
onChanged={this._selectedTeamChanged} />;
<div>
<div>
<Label>{this.props.label}</Label>
</div>
<div>
<PickListDropdown
isSearchable={true}
selectionMode={SelectionMode.single}
getPickListItems={() => options}
selectedItems={this.state.selectedItems}
getListItem={(item) => item as IPickListItem}
onSelectionChanged={this._selectedTeamChanged}
/>
</div>
</div>;
}
return (
<div>
Expand All @@ -58,7 +72,12 @@ export class SelectTeam extends React.Component<ISelectTeamProps, {}> {
);
}

private _selectedTeamChanged = (item: IDropdownOption) => {
this.props.onSelectTeam(item.text);
private _selectedTeamChanged = (selection: IPickListSelection) => {
const items = (selection.selectedItems || []) as IPickListItem[];
let team = items[0];
this.props.onSelectTeam(team.name);
this.setState({
selectedItems: items
});
}
}
20 changes: 20 additions & 0 deletions src/Views/CopySettings/Components/SettingsToCopy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from "react";
import { css } from "office-ui-fabric-react/lib/Utilities";

export interface ISettingsToCopyProps {
selectedSettings: string[];
}

export class SettingsToCopy extends React.Component<ISettingsToCopyProps, {}> {
public render() {
return (
<div>
The following styles will be copied: {this.props.selectedSettings.map((value, index, values) => {
let content = index < values.length - 1 ?
<span><span className={css("boldFont")}>{value}</span>, </span> : <span><span className={css("boldFont")}>{value}</span>.</span>;
return content;
})}
</div>
);
}
}
1 change: 1 addition & 0 deletions src/Views/CopySettings/Models/CopySettingsInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface CopySettingsState {
canToggleMappings: boolean;
showAdvancedMappings: boolean;
currentMappings: IBoardColumnDifferences[];
settingsToCopy: string[];
}

export interface IBacklogBoardSettings {
Expand Down

0 comments on commit fc736f6

Please sign in to comment.