public render()

in src/EpicRoadmap/react/Components/EpicRoadmapGrid.tsx [65:340]


    public render(): JSX.Element {
        const {
            rawState,
            gridView: {
                emptyHeaderRow,
                iterationHeader,
                iterationShadow,
                workItems,
                separators,
                shadowForWorkItemId,
                iterationDisplayOptions,
                teamIterations,
                teamFieldDisplayItems,
                teamFieldHeaderItem
            },
            isSubGrid
        } = this.props;

        const columnHeading = iterationHeader.map((iteration, index) => {
            const style = getRowColumnStyle(iteration.dimension);
            return (
                <div className="columnheading" style={style}>
                    <IterationRenderer teamIterations={teamIterations} iteration={iteration.teamIteration} />
                </div>
            );

        });

        const shadows = iterationShadow.map((shadow, index) => {
            return (
                <IterationDropTarget
                    {...shadow}
                    isOverrideIterationInProgress={!!rawState.workItemOverrideIteration}
                    onOverrideIterationOver={this.props.dragHoverOverIteration.bind(this)}
                    changeIteration={this.props.changeIteration.bind(this)}
                    markInProgress={this.props.markInProgress.bind(this)}
                >
                    &nbsp;
                </IterationDropTarget>
            );
        });

        let workItemShadowCell = null;
        if (shadowForWorkItemId > 0) {
            const workItem = workItems.filter(w => w.workItem.id === shadowForWorkItemId)[0];
            workItemShadowCell = (
                <WorkItemShadow dimension={workItem.dimension} twoRows={workItem.settingsState.showWorkItemDetails} />
            );
        }

        const teamFieldCards = teamFieldDisplayItems.map(tfdi => <TeamFieldCard dimension={tfdi.dimension} teamField={tfdi.teamField} />);

        const workItemCells = workItems.filter(w => w.workItem.id).map(w => {
            const props: IWorkItemRendererProps = {
                id: w.workItem.id,
                title: w.workItem.title,
                color: w.workItem.color,
                isRoot: w.workItem.isRoot,
                assignedTo: w.workItem.workItem.fields["System.AssignedTo"],
                iterationDuration: w.workItem.iterationDuration,
                dimension: w.dimension,
                onClick: this.props.launchWorkItemForm,
                showDetails: this.props.showDetails,
                overrideIterationStart: this.props.overrideIterationStart,
                overrideIterationEnd: this.props.overrideIterationEnd,
                allowOverrideIteration: w.allowOverrideIteration,
                isSubGrid: isSubGrid,
                progressIndicator: w.progressIndicator,
                crop: w.crop,
                workItemStateColor: w.workItem.workItemStateColor,
                settingsState: w.settingsState,
                efforts: w.workItem.efforts,
                childrernWithNoEfforts: w.workItem.childrenWithNoEfforts,
                isComplete: w.workItem.isComplete,
                successors: w.workItem.successors,
                predecessors: w.workItem.predecessors,
                highlightPredecessorIcon: w.workItem.highlightPredecessorIcon,
                highlighteSuccessorIcon: w.workItem.highlighteSuccessorIcon,
                onHighlightDependencies: this.props.onHighlightDependencies,
                onDismissDependencies: this.props.onDismissDependencies,
                teamFieldName: this.props.teamFieldName
            }
            return (
                <DraggableWorkItemRenderer
                    {...props}
                />
            );
        });

        const childRowsSeparator = separators.map(d => {
            return (
                <ChildRowsSeparator {...d} />
            );
        });


        const extraColumns = this.props.gridView.hideParents ? [] : ['200px'];
        let min = '200px';
        if (isSubGrid) {
            min = '150px';
        }
        const gridStyle = getTemplateColumns(extraColumns, shadows.length, `minmax(${min}, 300px)`);

        let childDialog = null;
        if (!this.props.isSubGrid && this.props.rawState.workItemsToShowInfoFor.length > 0) {
            childDialog = (
                <RoadmapTimelineDialog
                    {...this.props}
                    isSubGrid={true}
                />
            );
        }


        let leftButton = <span className="non-button"></span>;
        if (iterationDisplayOptions && iterationDisplayOptions.startIndex > 0) {
            leftButton = (
                <IconButton
                    className="button"
                    onClick={() => this.props.shiftDisplayIterationLeft(teamIterations.length)}
                    iconProps={
                        {
                            iconName: "ChevronLeftSmall"
                        }
                    }
                >
                </IconButton>
            );
        }

        let rightButton = <span className="non-button"></span>;
        if (iterationDisplayOptions && iterationDisplayOptions.endIndex < (iterationDisplayOptions.totalIterations - 1)) {
            rightButton = (
                <IconButton
                    className="button"
                    onClick={() => this.props.shiftDisplayIterationRight(teamIterations.length)}
                    iconProps={
                        {
                            iconName: "ChevronRightSmall"
                        }
                    }
                >
                </IconButton>
            );
        }

        let displayOptions = null;
        let commandHeading = [];

        if (!isSubGrid && (iterationDisplayOptions || columnHeading.length > 3)) {
            let displayIterationCount = 0;
            if (iterationDisplayOptions) {
                displayIterationCount = iterationDisplayOptions.count;
            } else {
                displayIterationCount = teamIterations.length;
            }
            displayOptions = (
                <div className="iteration-options">
                    <div className="iteration-options-label">View Sprints: </div>
                    <InputNum
                        value={displayIterationCount}
                        min={1}
                        max={teamIterations.length}
                        step={1}
                        onChange={this._onViewChanged}
                    >
                    </InputNum>
                </div>
            );

            if (emptyHeaderRow.length === 1) {
                // Special case only one column
                let rowColumnStyle = getRowColumnStyle(emptyHeaderRow[0]);
                const commands = (
                    <div style={rowColumnStyle} className="single-column-commands">
                        <div className="command-left-section">
                            {leftButton}
                        </div>
                        <div className="command-right-section">
                            {rightButton}
                        </div>
                    </div>
                );

                commandHeading.push(commands);

            } else {
                // Add left button to first empty heading cell
                let rowColumnStyle = getRowColumnStyle(emptyHeaderRow[0]);
                const firstHeaderColumnCommand = (
                    <div style={rowColumnStyle} className="first-header-column-command">
                        {leftButton}
                    </div>
                );
                commandHeading.push(firstHeaderColumnCommand);

                // Add display options and right button on last empty heading cell
                rowColumnStyle = getRowColumnStyle(emptyHeaderRow[emptyHeaderRow.length - 1]);
                const lastHeaderColumnCommand = (
                    <div style={rowColumnStyle} className="last-header-column-command">
                        {rightButton}
                    </div>
                );
                commandHeading.push(lastHeaderColumnCommand);
            }
        }
        let progressTrackingCriteriaElement = null;
        const {
            showWorkItemDetails,
            progressTrackingCriteria
        } = this.props.rawState.settingsState;
        if (!isSubGrid && showWorkItemDetails) {
            const selectedKey = progressTrackingCriteria === ProgressTrackingCriteria.ChildWorkItems ? "child" : "efforts";
            progressTrackingCriteriaElement = (
                <div className="progress-options">
                    <div className="progress-options-label">Track Progress Using: </div>
                    <ComboBox
                        className="progress-options-dropdown"
                        selectedKey={selectedKey}
                        allowFreeform={false}
                        autoComplete='off'
                        options={
                            [
                                { key: 'child', text: 'Completed Stories' },
                                { key: 'efforts', text: 'Completed Efforts' }
                            ]
                        }
                        onChanged={this._onProgressTrackingCriteriaChanged}
                    >
                    </ComboBox>
                </div>
            );
        }

        const commands = !isSubGrid && (
            <div className="header-commands">
                {displayOptions}

                <Checkbox
                    className="show-work-item-details-checkbox"
                    label={"Show Details"}
                    onChange={this._onShowWorkItemDetailsChanged}
                    checked={this.props.rawState.settingsState.showWorkItemDetails} />

                {progressTrackingCriteriaElement}
            </div>
        );

        const teamFieldHeader = <TeamFieldHeader dimension={teamFieldHeaderItem} />

        const grid = (
            <div className="feature-timeline-main-container">
                <div className="container" style={gridStyle}>
                    {commandHeading}
                    {teamFieldHeader}
                    {columnHeading}
                    {shadows}
                    {workItemShadowCell}
                    {workItemCells}
                    {childRowsSeparator}
                    {teamFieldCards}
                    {childDialog}
                </div>
            </div>
        );

        return (
            <div className="root-container" >
                {commands}
                {<div className="header-gap" ></div>}
                {grid}
            </div >

        );

    }