office-ui-fabric-react#StackItem TypeScript Examples

The following examples show how to use office-ui-fabric-react#StackItem. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ProgressItem.tsx    From AIPerf with MIT License 6 votes vote down vote up
render(): React.ReactNode {
        const { who, percent, description, maxString, bgclass } = this.props;
        return (
            <div>
                <Stack horizontal className={`probar ${bgclass}`}>
                    <div className="name">{who}</div>
                    <div className="showProgress" style={{ width: '80%' }}>
                        <ProgressIndicator
                            barHeight={30}
                            percentComplete={percent}
                        />
                        <Stack horizontal className="boundary">
                            <StackItem grow={30}>0</StackItem>
                            <StackItem className="right" grow={70}>{maxString}</StackItem>
                        </Stack>
                    </div>
                    <div className="description" style={{ width: '20%' }}>{description}</div>
                </Stack>
                <br />
            </div>
        );
    }
Example #2
Source File: NavCon.tsx    From AIPerf with MIT License 5 votes vote down vote up
render(): React.ReactNode {
        const { isvisibleLogDrawer, isvisibleExperimentDrawer, version,
            refreshText, refreshFrequency } = this.state;
        const aboutProps: IContextualMenuProps = {
            items: [
                {
                    key: 'feedback',
                    text: 'Feedback',
                    iconProps: { iconName: 'OfficeChat' },
                    onClick: this.openGithub
                },
                {
                    key: 'help',
                    text: 'Document',
                    iconProps: { iconName: 'TextDocument' },
                    onClick: this.openDocs
                },
                {
                    key: 'version',
                    text: `Version ${version}`,
                    iconProps: { iconName: 'VerifiedBrand' },
                    onClick: this.openGithubNNI
                }
            ]
        };
        return (
            <Stack horizontal className="nav">
                <StackItem grow={30} styles={{ root: { minWidth: 300, display: 'flex', verticalAlign: 'center' } }}>
                    <span className="desktop-logo">{NNILOGO}</span>
                    <span className="left-right-margin">{OVERVIEWTABS}</span>
                    <span>{DETAILTABS}</span>
                </StackItem>
                <StackItem grow={70} className="navOptions">
                    <Stack horizontal horizontalAlign="end" tokens={stackTokens} styles={stackStyle}>
                        {/* refresh button danyi*/}
                        {/* TODO: fix bug */}
                        {/* <CommandBarButton
                            iconProps={{ iconName: 'sync' }}
                            text="Refresh"
                            onClick={this.props.refreshFunction}
                        /> */}
                        <div className="nav-refresh">
                            <CommandBarButton
                                iconProps={refreshFrequency === '' ? disableUpdates : timeIcon}
                                text={refreshText}
                                menuProps={this.refreshProps}
                            />
                            <div className="nav-refresh-num">{refreshFrequency}</div>
                        </div>
                        <CommandBarButton
                            iconProps={downLoadIcon}
                            text="Download"
                            menuProps={this.menuProps}
                        />
                        <CommandBarButton
                            iconProps={infoIconAbout}
                            text="About"
                            menuProps={aboutProps}
                        />
                    </Stack>
                </StackItem>
                {/* the drawer for dispatcher & nnimanager log message */}
                {isvisibleLogDrawer && <LogDrawer closeDrawer={this.closeLogDrawer} />}
                <ExperimentDrawer isVisble={isvisibleExperimentDrawer} closeExpDrawer={this.closeExpDrawer} />
            </Stack>
        );
    }
Example #3
Source File: NetworkViewPCF.tsx    From NetworkViewPCF with MIT License 5 votes vote down vote up
render() {
    const { vm, width, height } = this.props;
    const { fullScreen } = vm;
    let correctedWidth = width;
    if (!fullScreen) correctedWidth = width - 22;
    const { currentLink, currentNode, calloutTarget, serviceProvider } = this.props.vm;
    console.debug("NetworkView:render");
    // https://github.com/vasturiano/react-force-graph
    return (
      <>
        <Stack
          style={{
            boxShadow: "inset 0 0 10px #000000",
            background: "radial-gradient(circle, rgba(255,255,255,1) 0%,  rgba(220,228,236,1) 100%)",
            width: correctedWidth,
          }}
        >
          <Stack verticalFill={false} style={{ position: "absolute", zIndex: 99999 }}>
            {!vm.errorText && (
              <StackItem shrink>
                <IconButton onClick={this.onFullScreen} iconProps={{ iconName: "FullScreen" }}></IconButton>
                <IconButton onClick={this.zoomToFit} iconProps={{ iconName: "Zoom" }}></IconButton>
              </StackItem>
            )}
            <StackItem styles={{ root: { paddingLeft: 20 } }}>
              <LoadProgress vm={vm} />
            </StackItem>
            {vm.errorText && (
              <StackItem shrink styles={{ root: { width: width - 80, padding: 10, margin: 20 } }}>
                <MessageBar messageBarType={MessageBarType.blocked} isMultiline={true}>
                  {vm.errorText}
                </MessageBar>
              </StackItem>
            )}
          </Stack>

          <ForceGraph2D
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            ref={this.gref as any}
            width={width}
            height={height}
            graphData={vm.data}
            nodeLabel={this.nodeLabel}
            nodeCanvasObject={this.renderNode}
            linkCanvasObject={this.linkCanvasObject}
            enableZoomPanInteraction={true}
            onNodeHover={this.onHoverNode}
            onNodeClick={this.onNodeClick}
            onLinkHover={this.onLinkHover}
            onLinkClick={this.onLinkClick}
            onZoomEnd={this.onZoomEnd}
          />
        </Stack>

        {(currentNode || currentLink) && (
          <Callout
            target={calloutTarget}
            onDismiss={this.onCalloutDismiss}
            directionalHint={DirectionalHint.bottomCenter}
            setInitialFocus={true}
          >
            <RecordDetails node={currentNode} link={currentLink} serviceProvider={serviceProvider} />
            {currentLink &&
              currentLink.otherLinks &&
              currentLink.otherLinks.map((link, index) => (
                <>
                  <RecordDetails link={link} serviceProvider={serviceProvider} />
                </>
              ))}
          </Callout>
        )}
      </>
    );
  }
Example #4
Source File: CustomizedTrial.tsx    From AIPerf with MIT License 4 votes vote down vote up
render(): React.ReactNode {
        const { closeCustomizeModal, visible } = this.props;
        const { isShowSubmitSucceed, isShowSubmitFailed, isShowWarning, customID, copyTrialParameter } = this.state;
        const warning = 'The parameters you set are not in our search space, this may cause the tuner to crash, Are'
            + ' you sure you want to continue submitting?';
        return (
            <Stack>
                <Dialog
                    hidden={!visible} // required field!
                    dialogContentProps={{
                        type: DialogType.largeHeader,
                        title: 'Customized trial setting',
                        subText: 'You can submit a customized trial.'
                    }}
                    modalProps={{
                        isBlocking: false,
                        styles: { main: { maxWidth: 450 } }
                    }}
                >
                    <form className="hyper-box">
                        {
                            Object.keys(copyTrialParameter).map(item => (
                                <Stack horizontal key={item} className="hyper-form">
                                    <StackItem styles={{ root: { minWidth: 100 } }} className="title">{item}</StackItem>
                                    <StackItem className="inputs">
                                        <input
                                            type="text"
                                            name={item}
                                            defaultValue={copyTrialParameter[item]}
                                            onChange={this.getFinalVal}
                                        />
                                    </StackItem>
                                </Stack>
                            )
                            )
                        }
                        {/* disable [tag] because we havn't support */}
                        {/* <Stack key="tag" horizontal className="hyper-form tag-input">
                            <StackItem grow={9} className="title">Tag</StackItem>
                            <StackItem grow={15} className="inputs">
                                <input type="text" value='Customized' />
                            </StackItem>
                        </Stack> */}
                    </form>
                    <DialogFooter>
                        <PrimaryButton text="Submit" onClick={this.addNewTrial} />
                        <DefaultButton text="Cancel" onClick={closeCustomizeModal} />
                    </DialogFooter>
                </Dialog>

                {/* clone: prompt succeed or failed */}
                <Dialog
                    hidden={!isShowSubmitSucceed}
                    onDismiss={this.closeSucceedHint}
                    dialogContentProps={{
                        type: DialogType.normal,
                        title: <div className="icon-color">{completed}<b>Submit successfully</b></div>,
                        closeButtonAriaLabel: 'Close',
                        subText: `You can find your customized trial by Trial No.${customID}`
                    }}
                    modalProps={{
                        isBlocking: false,
                        styles: { main: { minWidth: 500 } },
                    }}
                >
                    <DialogFooter>
                        <PrimaryButton onClick={this.closeSucceedHint} text="OK" />
                    </DialogFooter>
                </Dialog>

                <Dialog
                    hidden={!isShowSubmitFailed}
                    onDismiss={this.closeSucceedHint}
                    dialogContentProps={{
                        type: DialogType.normal,
                        title: <div className="icon-error">{errorBadge}Submit Failed</div>,
                        closeButtonAriaLabel: 'Close',
                        subText: 'Unknown error.'
                    }}
                    modalProps={{
                        isBlocking: false,
                        styles: { main: { minWidth: 500 } },
                    }}
                >
                    <DialogFooter>
                        <PrimaryButton onClick={this.closeFailedHint} text="OK" />
                    </DialogFooter>
                </Dialog>

                {/* hyperParameter not match search space, warning modal */}
                <Dialog
                    hidden={!isShowWarning}
                    onDismiss={this.closeSucceedHint}
                    dialogContentProps={{
                        type: DialogType.normal,
                        title: <div className="icon-error">{warining}Warning</div>,
                        closeButtonAriaLabel: 'Close',
                        subText: `${warning}`
                    }}
                    modalProps={{
                        isBlocking: false,
                        styles: { main: { minWidth: 500 } },
                    }}
                >
                    <DialogFooter>
                        <PrimaryButton onClick={this.warningConfirm} text="Confirm" />
                        <DefaultButton onClick={this.warningCancel} text="Cancel" />
                    </DialogFooter>
                </Dialog>
            </Stack>

        );
    }
Example #5
Source File: ExperimentDrawer.tsx    From AIPerf with MIT License 4 votes vote down vote up
render(): React.ReactNode {
        const { isVisble, closeExpDrawer } = this.props;
        const { experiment, expDrawerHeight } = this.state;
        return (
            <Stack className="logDrawer">
                <Panel
                    isOpen={isVisble}
                    hasCloseButton={false}
                    styles={{ root: { height: expDrawerHeight, paddingTop: 15 } }}
                >
                    <Pivot style={{ minHeight: 190 }} className="log-tab-body">
                        <PivotItem headerText="Experiment Parameters">
                            <div className="just-for-log">
                                <MonacoEditor
                                    width="100%"
                                    // 92 + marginTop[16]
                                    height={expDrawerHeight - 108}
                                    language="json"
                                    value={experiment}
                                    options={DRAWEROPTION}
                                />
                            </div>
                            <Stack horizontal className="buttons">
                                <StackItem grow={50} className="download">
                                    <PrimaryButton
                                        text="Download"
                                        onClick={this.downExperimentParameters}
                                    />
                                </StackItem>
                                <StackItem grow={50} className="close">
                                    <DefaultButton
                                        text="Close"
                                        onClick={closeExpDrawer}
                                    />
                                </StackItem>
                            </Stack>
                        </PivotItem>
                    </Pivot>
                </Panel>
            </Stack>
        );
    }
Example #6
Source File: LogDrawer.tsx    From AIPerf with MIT License 4 votes vote down vote up
render(): React.ReactNode {
        const { closeDrawer, activeTab } = this.props;
        const { nniManagerLogStr, dispatcherLogStr, isLoading, logDrawerHeight } = this.state;

        return (
            <Stack>
                <Panel
                    isOpen={true}
                    hasCloseButton={false}
                    isFooterAtBottom={true}
                >
                    <div className="log-tab-body">
                        <Pivot
                            selectedKey={activeTab}
                            style={{ minHeight: 190, paddingTop: '16px' }}
                        >
                            {/* <PivotItem headerText={this.dispatcherHTML()} key="dispatcher" onLinkClick> */}
                            <PivotItem headerText="Dispatcher Log" key="dispatcher">
                                <MonacoHTML
                                    content={dispatcherLogStr || 'Loading...'}
                                    loading={isLoading}
                                    // paddingTop[16] + tab[44] + button[32]
                                    height={logDrawerHeight - 92}
                                />
                                <Stack horizontal className="buttons">
                                    <StackItem grow={12} className="download">
                                        <PrimaryButton text="Download" onClick={this.downloadDispatcher} />
                                    </StackItem>
                                    <StackItem grow={12} className="close">
                                        <DefaultButton text="Close" onClick={closeDrawer} />
                                    </StackItem>
                                </Stack>
                            </PivotItem>
                            <PivotItem headerText="NNIManager Log" key="nnimanager">
                                {/* <TabPane tab="NNImanager Log" key="nnimanager"> */}
                                <MonacoHTML
                                    content={nniManagerLogStr || 'Loading...'}
                                    loading={isLoading}
                                    height={logDrawerHeight - 92}
                                />
                                <Stack horizontal className="buttons">
                                    <StackItem grow={12} className="download">
                                        <PrimaryButton text="Download" onClick={this.downloadNNImanager} />
                                    </StackItem>
                                    <StackItem grow={12} className="close">
                                        <DefaultButton text="Close" onClick={closeDrawer} />
                                    </StackItem>
                                </Stack>
                            </PivotItem>
                        </Pivot>
                    </div>
                </Panel>
            </Stack>
        );
    }
Example #7
Source File: TrialsDetail.tsx    From AIPerf with MIT License 4 votes vote down vote up
render(): React.ReactNode {
        const { tablePageSize, whichGraph, searchType } = this.state;
        const { columnList, changeColumn } = this.props;
        const source = TRIALS.filter(this.state.searchFilter);
        const trialIds = TRIALS.filter(this.state.searchFilter).map(trial => trial.id);
        const searchOptions = [
            { key: 'Id', text: 'Id' },
            { key: 'Trial No.', text: 'Trial No.' },
            { key: 'Status', text: 'Status' },
            { key: 'Parameters', text: 'Parameters' },
        ];
        return (
            <div>
                <div className="trial" id="tabsty">
                    <Pivot defaultSelectedKey={"0"} className="detial-title">
                        {/* <PivotItem tab={this.titleOfacc} key="1"> doesn't work*/}
                        <PivotItem headerText="Default metric" itemIcon="HomeGroup" key="1">
                            <Stack className="graph">
                                <DefaultPoint
                                    trialIds={trialIds}
                                    visible={whichGraph === '1'}
                                    trialsUpdateBroadcast={this.props.trialsUpdateBroadcast}
                                />
                            </Stack>
                        </PivotItem>
                        {/* <PivotItem tab={this.titleOfhyper} key="2"> */}
                        <PivotItem headerText="Hyper-parameter" itemIcon="Equalizer" key="2">
                            <Stack className="graph">
                                <Para
                                    dataSource={source}
                                    expSearchSpace={JSON.stringify(EXPERIMENT.searchSpace)}
                                    whichGraph={whichGraph}
                                />
                            </Stack>
                        </PivotItem>
                        {/* <PivotItem tab={this.titleOfDuration} key="3"> */}
                        <PivotItem headerText="Duration" itemIcon="BarChartHorizontal" key="3">
                            <Duration source={source} whichGraph={whichGraph} />
                        </PivotItem>
                        {/* <PivotItem tab={this.titleOfIntermediate} key="4"> */}
                        <PivotItem headerText="Intermediate result" itemIcon="StackedLineChart" key="4">
                            {/* *why this graph has small footprint? */}
                            <Intermediate source={source} whichGraph={whichGraph} />
                        </PivotItem>
                    </Pivot>
                </div>
                {/* trial table list */}
                <Stack horizontal className="panelTitle">
                    <span style={{ marginRight: 12 }}>{tableListIcon}</span>
                    <span>Trial jobs</span>
                </Stack>
                <Stack horizontal className="allList">
                    <StackItem grow={50}>
                        <DefaultButton
                            text="Compare"
                            className="allList-compare"
                            // use child-component tableList's function, the function is in child-component.
                            onClick={(): void => { if (this.tableList) { this.tableList.compareBtn(); } }}
                        />
                    </StackItem>
                    <StackItem grow={50}>
                        <Stack horizontal horizontalAlign="end" className="allList">
                            <DefaultButton
                                className="allList-button-gap"
                                text="Add column"
                                onClick={(): void => { if (this.tableList) { this.tableList.addColumn(); } }}
                            />
                            <Dropdown
                                selectedKey={searchType}
                                options={searchOptions}
                                onChange={this.updateSearchFilterType}
                                styles={{ root: { width: 150 } }}
                            />
                            <input
                                type="text"
                                className="allList-search-input"
                                placeholder={`Search by ${this.state.searchType}`}
                                onChange={this.searchTrial}
                                style={{ width: 230 }}
                                ref={(text): any => (this.searchInput) = text}
                            />
                        </Stack>

                    </StackItem>
                </Stack>
                <TableList
                    pageSize={tablePageSize}
                    tableSource={source.map(trial => trial.tableRecord)}
                    columnList={columnList}
                    changeColumn={changeColumn}
                    trialsUpdateBroadcast={this.props.trialsUpdateBroadcast}
                    // TODO: change any to specific type
                    ref={(tabList): any => this.tableList = tabList}
                />
            </div>
        );
    }
Example #8
Source File: Progress.tsx    From AIPerf with MIT License 4 votes vote down vote up
render(): React.ReactNode {
        const { bestAccuracy } = this.props;
        const { isShowLogDrawer, isCalloutVisible, isShowSucceedInfo, info, typeInfo } = this.state;

        const count = TRIALS.countStatus();
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const stoppedCount = count.get('USER_CANCELED')! + count.get('SYS_CANCELED')! + count.get('EARLY_STOPPED')!;
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const bar2 = count.get('RUNNING')! + count.get('SUCCEEDED')! + count.get('FAILED')! + stoppedCount;
        // support type [0, 1], not 98%
        const bar2Percent = bar2 / EXPERIMENT.profile.params.maxTrialNum;
        const percent = EXPERIMENT.profile.execDuration / EXPERIMENT.profile.params.maxExecDuration;
        const remaining = convertTime(EXPERIMENT.profile.params.maxExecDuration - EXPERIMENT.profile.execDuration);
        const maxDuration = convertTime(EXPERIMENT.profile.params.maxExecDuration);
        const maxTrialNum = EXPERIMENT.profile.params.maxTrialNum;
        const execDuration = convertTime(EXPERIMENT.profile.execDuration);

        return (
            <Stack className="progress" id="barBack">
                <Stack className="basic lineBasic">
                    <p>Status</p>
                    <Stack horizontal className="status">
                        <span className={`${EXPERIMENT.status} status-text`}>{EXPERIMENT.status}</span>
                        {
                            EXPERIMENT.status === 'ERROR'
                                ?
                                <div>
                                    <div className={styles.buttonArea} ref={(val): any => this.menuButtonElement = val}>
                                        <IconButton
                                            iconProps={{ iconName: 'info' }}
                                            onClick={isCalloutVisible ? this.onDismiss : this.onShow}
                                        />
                                    </div>
                                    {isCalloutVisible && (
                                        <Callout
                                            className={styles.callout}
                                            ariaLabelledBy={this.labelId}
                                            ariaDescribedBy={this.descriptionId}
                                            role="alertdialog"
                                            gapSpace={0}
                                            target={this.menuButtonElement}
                                            onDismiss={this.onDismiss}
                                            setInitialFocus={true}
                                        >
                                            <div className={styles.header}>
                                                <p className={styles.title} id={this.labelId}>Error</p>
                                            </div>
                                            <div className={styles.inner}>
                                                <p className={styles.subtext} id={this.descriptionId}>
                                                    {EXPERIMENT.error}
                                                </p>
                                                <div className={styles.actions}>
                                                    <Link className={styles.link} onClick={this.isShowDrawer}>
                                                        Learn about
                                                    </Link>
                                                </div>
                                            </div>
                                        </Callout>
                                    )}
                                </div>
                                :
                                null
                        }
                    </Stack>
                </Stack>
                <ProgressBar
                    who="Duration"
                    percent={percent}
                    description={execDuration}
                    bgclass={EXPERIMENT.status}
                    maxString={`Max duration: ${maxDuration}`}
                />
                <ProgressBar
                    who="Trial numbers"
                    percent={bar2Percent}
                    description={bar2.toString()}
                    bgclass={EXPERIMENT.status}
                    maxString={`Max trial number: ${maxTrialNum}`}
                />
                <Stack className="basic colorOfbasic mess" horizontal>
                    <StackItem grow={50}>
                        <p>Best metric</p>
                        <div>{isNaN(bestAccuracy) ? 'N/A' : bestAccuracy.toFixed(6)}</div>
                    </StackItem>
                    <StackItem>
                        {isShowSucceedInfo && <MessageInfo className="info" typeInfo={typeInfo} info={info} />}
                    </StackItem>
                </Stack>
                <Stack horizontal horizontalAlign="space-between" className="mess">
                    <span style={itemStyles} className="basic colorOfbasic">
                        <p>Spent</p>
                        <div>{execDuration}</div>
                    </span>
                    <span style={itemStyles} className="basic colorOfbasic">
                        <p>Remaining</p>
                        <div className="time">{remaining}</div>
                    </span>
                    <span style={itemStyles}>
                        {/* modify concurrency */}
                        <TooltipHost content={CONCURRENCYTOOLTIP}>
                        <p className="cursor">Concurrency<span className="progress-info">{infoIcon}</span></p>
                        </TooltipHost>
                        <ConcurrencyInput value={this.props.concurrency} updateValue={this.editTrialConcurrency} />
                    </span>
                    <span style={itemStyles} className="basic colorOfbasic"></span>
                </Stack>
                <Stack horizontal horizontalAlign="space-between" className="mess">
                    <div style={itemStyles} className="basic colorOfbasic">
                        <p>Running</p>
                        <div>{count.get('RUNNING')}</div>
                    </div>
                    <div style={itemStyles} className="basic colorOfbasic">
                        <p>Succeeded</p>
                        <div>{count.get('SUCCEEDED')}</div>
                    </div>
                    <div style={itemStyles} className="basic">
                        <p>Stopped</p>
                        <div>{stoppedCount}</div>
                    </div>
                    <div style={itemStyles} className="basic">
                        <p>Failed</p>
                        <div>{count.get('FAILED')}</div>
                    </div>
                </Stack>
                {/* learn about click -> default active key is dispatcher. */}
                {isShowLogDrawer ? (
                    <LogDrawer
                        closeDrawer={this.closeDrawer}
                        activeTab="dispatcher"
                    />
                ) : null}
            </Stack>
        );
    }
Example #9
Source File: MeetingPage.tsx    From msteams-meetings-template with MIT License 4 votes vote down vote up
function MeetingPageComponent(props: MeetingPageProps) {
  const [validationEnabled, setValidationEnabled] = useState(false);

  function onSubjectChanged(
    evt: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
    newValue: string | undefined
  ) {
    // The meeting objects are small, cloning is cheap enough
    // Normally would use immutable records or similar to avoid overhead.
    const nextMeeting = _.cloneDeep(props.meeting);
    nextMeeting.subject = newValue ?? '';
    props.setMeeting(nextMeeting);
  }

  function onStartDateSelected(date?: Moment) {
    const nextMeeting = _.cloneDeep(props.meeting);
    nextMeeting.startDateTime = date ?? nextMeeting.startDateTime;

    // If start >= end, adjust to be the same delta as before from the start time
    if (nextMeeting.startDateTime.isSameOrAfter(nextMeeting.endDateTime)) {
      const existingDelta = moment(props.meeting.endDateTime).diff(
        moment(props.meeting.startDateTime)
      );
      const newEndDateTime = moment(nextMeeting.startDateTime).add(
        existingDelta
      );
      if (nextMeeting.startDateTime.isSameOrAfter(newEndDateTime)) {
        newEndDateTime.add(existingDelta);
      }
      nextMeeting.endDateTime = newEndDateTime;
    }

    props.setMeeting(nextMeeting);
  }

  function onEndDateSelected(date?: Moment) {
    const nextMeeting = _.cloneDeep(props.meeting);
    const newEndDateTime = date ?? nextMeeting.endDateTime;

    // Allow the change only if it maintains start < end
    if (!nextMeeting.startDateTime.isAfter(newEndDateTime)) {
      nextMeeting.endDateTime = newEndDateTime;
    }

    props.setMeeting(nextMeeting);
  }

  function onCreate() {
    if (!!props.validationFailures.invalidTitle) {
      setValidationEnabled(true);
      return;
    }

    props.createMeeting(props.meeting);
  }

  if (props.creationInProgress) {
    return (
      <div className="spinnerContainer">
        <Spinner size={SpinnerSize.large} />
      </div>
    );
  }

  return (
    <div className="newMeetingContainer">
      <Stack
        className="container"
        verticalFill
        tokens={{
          childrenGap: 35
        }}
      >
        <Stack horizontal tokens={{ childrenGap: 15 }}>
          <StackItem grow>
            <FontIcon iconName="Calendar" className={meetingIconClass} />
            <Text variant="xLarge" styles={boldStyle}>
              <FormattedMessage id="meetingPage.header" />
            </Text>
          </StackItem>
          <StackItem align="end" className="newMeetingButtons">
            <Stack horizontal tokens={{ childrenGap: 10 }}>
              <PrimaryButton
                className="teamsButton"
                disabled={props.creationInProgress}
                onClick={() => onCreate()}
                ariaLabel={translate('meetingPage.create.ariaLabel')}
              >
                <FormattedMessage id="meetingPage.create" />
              </PrimaryButton>
              <DefaultButton
                className="teamsButtonInverted"
                disabled={props.creationInProgress}
                onClick={() => props.cancel()}
                ariaLabel={translate('meetingPage.cancel.ariaLabel')}
              >
                <FormattedMessage id="meetingPage.cancel" />
              </DefaultButton>
            </Stack>
          </StackItem>
        </Stack>
        <Stack horizontal>
          <StackItem className="newMeetingInputIcon">
            <FontIcon iconName="Edit" className={inputIconClass} />
          </StackItem>
          <StackItem grow>
            <TextField
              className="newMeetingInput"
              placeholder={translate('meetingPage.title.input')}
              value={props.meeting?.subject}
              underlined
              onChange={onSubjectChanged}
              errorMessage={
                validationEnabled
                  ? props.validationFailures.invalidTitle
                  : undefined
              }
            />
          </StackItem>
        </Stack>

        <div className="newMeetingDatePickerContainer">
          <FontIcon iconName="Clock" className={inputIconClass} />
          <div className="newMeetingPicker">
            <DateTimePicker
              dateTime={props.meeting.startDateTime}
              minDate={moment()}
              onTimeUpdated={onStartDateSelected}
              includeDuration={false}
              iconName="ReplyAlt"
            />
            <DateTimePicker
              dateTime={props.meeting.endDateTime}
              minDate={props.meeting.startDateTime}
              onTimeUpdated={onEndDateSelected}
              includeDuration={true}
            />
          </div>
        </div>

        {/* MOBILE BUTTON GROUP */}
      </Stack>
      <StackItem className="newMeetingButtonsMobile">
        <Stack horizontal tokens={{ childrenGap: 10 }}>
          <PrimaryButton
            className="teamsButton teamsButtonFullWidth"
            disabled={props.creationInProgress}
            onClick={() => onCreate()}
            ariaLabel={translate('meetingPage.create.ariaLabel')}
          >
            <FormattedMessage id="meetingPage.create" />
          </PrimaryButton>
          <DefaultButton
            className="teamsButtonInverted teamsButtonFullWidth"
            disabled={props.creationInProgress}
            onClick={() => props.cancel()}
            ariaLabel={translate('meetingPage.cancel.ariaLabel')}
          >
            <FormattedMessage id="meetingPage.cancel" />
          </DefaultButton>
        </Stack>
      </StackItem>
    </div>
  );
}