office-ui-fabric-react#Stack TypeScript Examples

The following examples show how to use office-ui-fabric-react#Stack. 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: Compare.tsx    From AIPerf with MIT License 7 votes vote down vote up
render(): React.ReactNode {
        const { cancelFunc } = this.props;

        return (
            <Modal
                isOpen={true}
                containerClassName={contentStyles.container}
                className="compare-modal"
            >
                <div>
                    <div className={contentStyles.header}>
                        <span>Compare trials</span>
                        <IconButton
                            styles={iconButtonStyles}
                            iconProps={{ iconName: 'Cancel' }}
                            ariaLabel="Close popup modal"
                            onClick={cancelFunc}
                        />
                    </div>
                    <Stack className="compare-modal-intermediate">
                        {this.intermediate()}
                        <Stack className="compare-yAxis"># Intermediate result</Stack>
                    </Stack>
                    <Stack>{this.initColumn()}</Stack>
                </div>
            </Modal>
        );
    }
Example #2
Source File: ErrorMessageBar.tsx    From hypertrons-crx with Apache License 2.0 6 votes vote down vote up
ErrorMessageBar: React.FC<ErrorMessageBarProps> = ({
  errorCode = ErrorCode.UNKNOWN,
  url = HYPERTRONS_CRX_NEW_ISSUE,
}) => {
  const [inited, setInited] = useState(false);
  const [settings, setSettings] = useState(new Settings());

  useEffect(() => {
    const initSettings = async () => {
      const temp = await loadSettings();
      setSettings(temp);
      setInited(true);
    };
    if (!inited) {
      initSettings();
    }
  }, [inited, settings]);

  return (
    <Stack>
      <Stack.Item align="center">
        <MessageBar
          messageBarType={MessageBarType.error}
          isMultiline={false}
          dismissButtonAriaLabel="Close"
        >
          {getMessageByLocale('global_error_message', settings.locale)}
          {errorCode}.
          <Link href={url} target="_blank" underline>
            {getMessageByLocale('global_clickToshow', settings.locale)} Issue.
          </Link>
        </MessageBar>
      </Stack.Item>
    </Stack>
  );
}
Example #3
Source File: FairnessPage.tsx    From art with MIT License 6 votes vote down vote up
render() {
        return (
<Stack className="main" role="main">
                <NavBar />
                <div className="page-wrap" style={{ position: "relative", top: "80px", width: "100%", overflow: "hidden"}}>
                    <div className="explore__banner-text-2">Before we get started:</div>
                    <div className="explore__solid">
                            <Stack horizontal horizontalAlign="center" verticalAlign="center" wrap>
                                <div className="explore__disclaimer-text">
                                 Art, culture, and heritage are sensitive subjects that require respect.
                                 This work aims to celebrate culture and diversity and explore art in a new way.
                                 AI has known biases and the results or artworks within this tool do not reflect 
                                 the views of Microsoft, MIT, or the authors. We ask users to be respectfull of other's cultures and to use this tool responsibly. 
                                 Some artworks or matches might not be approporiate for all ages, or might be culturally inappropriate.
                                 We have released this tool as-is, and encourage users to read our <a href="https://github.com/microsoft/art/blob/master/transparency_note.md">transparency note</a> for more info. Thanks!  </div>
                            </Stack>

                            <Stack horizontalAlign="center" style={{paddingTop: "2%"}}>
                                    <button className="explore__buttons button"  onClick={() => {
                                        this.props.history.push("/app");
                                        logEvent("Agree", {});

                                    }}>I Understand</button>
                            </Stack>
                            
                    </div>              
                </div>
            </Stack>
        )
    }
Example #4
Source File: index.tsx    From azure-serverless-workshop with MIT License 6 votes vote down vote up
App: React.FunctionComponent = () => {
  return (
    <Stack
      horizontalAlign="center"
      verticalAlign="center"
      verticalFill
      styles={{
        root: {
          width: "960px",
          margin: "0 auto",
          textAlign: "center",
          color: "#605e5c",
        },
      }}
      gap={15}>
      {auth.handleLoginCallback()}
      <Stack.Item align="end">
        <LoginActionButton />
      </Stack.Item>
      <Stack.Item align="start">
        <Text styles={titleStyle}>
          Welcome to Fabrikam Drone Status App
        </Text>
      </Stack.Item>
      <Stack.Item align="start">
        <Text styles={descStyle}>
        This sample demonstrates how to authenticate a serverless API.
        </Text>
      </Stack.Item>
      <Stack.Item align="start">
        <RestrictedContent />
      </Stack.Item>
    </Stack>
  )
}
Example #5
Source File: DefaultMetricPoint.tsx    From AIPerf with MIT License 6 votes vote down vote up
render(): React.ReactNode {
        const graph = this.generateGraph();
        const accNodata = (graph === EmptyGraph ? 'No data' : '');
        const onEvents = { 'dataZoom': this.metricDataZoom };

        return (
            <div>
                <Stack horizontalAlign="end" className="default-metric">
                    <Toggle label="Optimization curve"
                        inlineLabel
                        onChange={this.loadDefault}
                    />
                </Stack>
                <div className="default-metric-graph">
                    <ReactEcharts
                        option={graph}
                        style={{
                            width: '100%',
                            height: 402,
                            margin: '0 auto',
                        }}
                        theme="my_theme"
                        notMerge={true} // update now
                        onEvents={onEvents}
                    />
                    <div className="default-metric-noData">{accNodata}</div>
                </div>
            </div>
        );
    }
Example #6
Source File: GenericObjectEditor.tsx    From sp-site-designs-studio with MIT License 6 votes vote down vote up
export function GenericArrayEditor(arrayEditorProps: IGenericObjectEditorProps) {

    const onRemoved = ((index) => {
        arrayEditorProps.onObjectChanged(arrayEditorProps.object.filter((_, i) => i != index));
    });

    const onAdded = (() => {
        arrayEditorProps.onObjectChanged([...(arrayEditorProps.object || []), getDefaulValueFromSchema(arrayEditorProps.schema)]);
    });

    const onUpdated = ((index, newValue) => {
        arrayEditorProps.onObjectChanged(arrayEditorProps.object.map((o, i) => i == index ? newValue : o));
    });

    const renderItems = () => {
        if (!arrayEditorProps.object) {
            return null;
        }

        const items = arrayEditorProps.object as any[];
        return items.map((item, index) => <>
            <Stack horizontal>
                <PropertyEditor key={index} value={item} schema={arrayEditorProps.schema} onChange={o => onUpdated(index, o)} />
                <IconButton iconProps={{ iconName: 'Delete' }} onClick={() => onRemoved(index)} />
            </Stack>
        </>);
    };

    return <>
        {renderItems()}
        <IconButton iconProps={{ iconName: 'Add' }} onClick={onAdded} />
    </>;
}
Example #7
Source File: Title1.tsx    From AIPerf with MIT License 6 votes vote down vote up
render(): React.ReactNode {
        const { text, icon, bgcolor } = this.props;
        return (
            <Stack horizontal className="panelTitle" style={{ backgroundColor: bgcolor }}>
                <img src={require(`../../static/img/icon/${icon}`)} alt="icon" />
                <span>{text}</span>
            </Stack>
        );
    }
Example #8
Source File: SpfxFluentuiMessagebar.tsx    From SPFx with Mozilla Public License 2.0 6 votes vote down vote up
public render(): React.ReactElement<ISpfxFluentuiMessagebarProps> {
    return (
      <div className={styles.spfxFluentuiMessagebar}>
        {(this.state.InfoMessage) ? <div><InfoMessage /><br /></div> : ''}
        {(this.state.ErrorMessage) ? <div><ErrorMessage /><br /></div> : ''}
        {(this.state.AccessMessage) ? <div><AccessMessage /><br /></div> : ''}
        {(this.state.WarningMessage) ? <div><WarningMessage /><br /></div> : ''}
        {(this.state.SuccessQuestion) ? <div><SuccessQuestion /><br /></div> : ''}
        {(this.state.WarningQuestion) ? <div><WarningQuestion /><br /></div> : ''}
        {(this.state.WarningLongMessage) ? <div><WarningLongMessage /><br /></div> : ''}
        <br />
        <br />
        <Stack horizontal tokens={stackTokens}>
          <PrimaryButton text="Show Info Message" onClick={() => this._showMessageClicked('InfoMessage')} />
          <PrimaryButton text="Show Error Message" onClick={() => this._showMessageClicked('ErrorMessage')} />
          <PrimaryButton text="Show Access Message" onClick={() => this._showMessageClicked('AccessMessage')} />
        </Stack>
        <br />
        <br />
        <Stack horizontal tokens={stackTokens}>
          <PrimaryButton text="Show Warning Message" onClick={() => this._showMessageClicked('WarningMessage')} />
          <PrimaryButton text="Show Success with Question Message" onClick={() => this._showMessageClicked('SuccessQuestion')} />
          <PrimaryButton text="Show Warning with Question Message" onClick={() => this._showMessageClicked('WarningQuestion')} />
        </Stack>
        <br />
        <br />
        <Stack horizontal tokens={stackTokens}>
          <PrimaryButton text="Show Long Message" onClick={() => this._showMessageClicked('WarningLongMessage')} />
          <PrimaryButton text="Show info message and hide after 5 sec" onClick={this._showandhideMessageClicked} />
          <DefaultButton text="Hide All Message" onClick={this._hideMessageClicked} />
        </Stack>

      </div>
    );
  }
Example #9
Source File: LoadProgress.tsx    From NetworkViewPCF with MIT License 6 votes vote down vote up
render() {
    const { progressText, isLoading, cancelRequested, isPaused } = this.props.vm;
    return (
      <>
        <Transition in={isLoading || isPaused} timeout={500} classNames="my-node">
          {state =>
            state != "exited" && (
              <Stack style={progressBoxStyle} className={this.getTransitionClass(state)}>
                <Stack.Item>{progressText}</Stack.Item>
                {isLoading && (
                  <Stack.Item>
                    {!cancelRequested && <DefaultButton text="Cancel" onClick={this.onCancel}></DefaultButton>}
                  </Stack.Item>
                )}
                {isPaused && (
                  <Stack.Item>
                    {!cancelRequested && <DefaultButton text="Resume" onClick={this.onResume}></DefaultButton>}
                  </Stack.Item>
                )}
              </Stack>
            )
          }
        </Transition>
      </>
    );
  }
Example #10
Source File: Killjob.tsx    From AIPerf with MIT License 6 votes vote down vote up
render(): React.ReactNode {
        const { isCalloutVisible } = this.state;
        const prompString = 'Are you sure to cancel this trial?';
        return (
            <div>
                <div className={styles.buttonArea} ref={(menuButton): any => (this.menuButtonElement = menuButton)}>
                    <PrimaryButton className="detail-button-operation" onClick={this.openPromot} title="kill">{blocked}</PrimaryButton>
                </div>
                {isCalloutVisible ? (
                    <div>
                        <FocusTrapCallout
                            role="alertdialog"
                            className={styles.callout}
                            gapSpace={0}
                            target={this.menuButtonElement}
                            onDismiss={this.onDismiss}
                            setInitialFocus={true}
                        >
                            <div className={styles.header}>
                                <p className={styles.title}>Kill trial</p>
                            </div>
                            <div className={styles.inner}>
                                <div>
                                    <p className={styles.subtext}>{prompString}</p>
                                </div>
                            </div>
                            <FocusZone>
                                <Stack className={styles.buttons} gap={8} horizontal>
                                    <DefaultButton onClick={this.onDismiss}>No</DefaultButton>
                                    <PrimaryButton onClick={this.onKill}>Yes</PrimaryButton>
                                </Stack>
                            </FocusZone>
                        </FocusTrapCallout>
                    </div>
                ) : null}
            </div>
        );
    }
Example #11
Source File: SpfxFluentuiPanel.tsx    From SPFx with Mozilla Public License 2.0 5 votes vote down vote up
public render(): React.ReactElement<ISpfxFluentuiPanelProps> {
    let buttonStyles = { root: { marginRight: 8 } };
    const onRenderFooterContent = () => (
      <div>
        <PrimaryButton onClick={this._saveclick} styles={buttonStyles}>
          Save
        </PrimaryButton>
        <DefaultButton onClick={this._cancelclick}>Cancel</DefaultButton>
      </div>
    );

    return (
      <div className={styles.spfxFluentuiPanel}>
        <Stack tokens={stackTokens} verticalAlign="end">
          <Stack horizontal tokens={stackTokens} verticalAlign="end">
            <Dropdown className={styles.Dropdown}
              placeholder="Select a Project"
              label="Projects"
              options={this.state.projects}
            />
            <DefaultButton text="Project" iconProps={addIcon} onClick={() => this.setState({ showpanel: true, projectname: '' })} />
          </Stack>
        </Stack>
        {this.state.showpanel &&
          <Panel
            headerText={"New Project Name"}
            isOpen={true}
            isBlocking={false}
            closeButtonAriaLabel="Close"
            onRenderFooterContent={onRenderFooterContent}>
            <TextField placeholder={'Enter a new project name'} onChanged={(strproject) => this.setState({ projectname: strproject })}></TextField>
          </Panel>
        }

      </div>
    );
  }
Example #12
Source File: Adder.tsx    From sp-site-designs-studio with MIT License 5 votes vote down vote up
Adder = (props: IAdderProps) => {

    const [isSelecting, setIsSelecting] = useState<boolean>(false);
    const [searchCriteria, setSearchCriteria] = useState<string>('');
    const addButtonRef = useRef<HTMLDivElement>();
    const searchBoxRef = useRef<ITextField>();

    useEffect(() => {
        if (isSelecting && searchBoxRef && searchBoxRef.current) {
            searchBoxRef.current.focus();
        }
    });

    const onSelected = (item: IAddableItem) => {
        props.onSelectedItem(item);
        setIsSelecting(false);
        setSearchCriteria('');
    };

    const onSearchCriteriaChanged = (ev, criteria) => {
        setSearchCriteria(criteria);
    };


    return <div className={styles.Adder}>
        <button className={`${styles.button} ${isSelecting ? styles.isSelecting : ""}`} onClick={() => setIsSelecting(true)}>
            <div ref={addButtonRef} className={styles.plusIcon}>
                <Icon iconName="Add" />
            </div>
        </button>
        {isSelecting && <Callout
            role="alertdialog"
            gapSpace={0}
            target={addButtonRef.current}
            onDismiss={() => setIsSelecting(false)}
            setInitialFocus={true}
            directionalHint={DirectionalHint.bottomCenter}
        >
            <div className={styles.row}>
                <div className={styles.fullWidth}>
                    <Stack horizontal>
                        <div className={styles.iconSearch}>
                            <Icon iconName="Search" />
                        </div>
                        <TextField
                            key="ItemSearchBox"
                            borderless
                            componentRef={searchBoxRef}
                            placeholder={props.searchBoxPlaceholderText || "Search an item..."} onChange={onSearchCriteriaChanged} />
                    </Stack>
                </div>
            </div>
            {renderItemsList(props.items, searchCriteria && searchCriteria.toLowerCase(), onSelected, props.noAvailableItemsText)}
        </Callout>}
    </div>;
}
Example #13
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 #14
Source File: ResultBox.tsx    From art with MIT License 5 votes vote down vote up
render() {
    let museumName = this.props.data.Museum === "met" ? "The Met" : "The Rijks";

    return (

      <Card className="grid-card" onMouseEnter={() => this.setState({ hover: true })} onMouseLeave={() => this.setState({ hover: false })}>
        <Card.Item className="grid-card__link">
          <div onClick={() => {
            if (isBeta) {
              window.location.href = urlEncodeArt(this.props.data.id);
            } else {
              this.openModal()
            };
          }}> 
            <LazyLoad
              throttle={250}
              height={200}
              offset={1000}
              placeholder={<CircularProgress style={{ color: '#6A6A6A' }} />}
            >
              <Image className="grid-card__img" alt="thumbnail" src={this.props.data.Thumbnail_Url} imageFit={ImageFit.contain} />
            </LazyLoad>
          </div>
          <Popup
            open={this.state.open}
            closeOnDocumentClick
            onClose={this.closeModal}
          >
            <div className="modal">
              <button className="close" onClick={this.closeModal}>
                &times;
              </button>
              {betaMessageDiv}
            </div>
          </Popup>

        </Card.Item>
        <Card.Item>
          <div className="grid-card__title" style={{ marginTop: -10, textAlign: "center" }}>{!this.props.data.Title ?
            "Untitled Piece" :
            this.props.data.Title.length < 55 ? this.props.data.Title : this.props.data.Title.substring(0, 55) + "..."}</div>
        </Card.Item>
        <Card.Item >
          <div className="grid-card__text" style={{ marginTop: -10, textAlign: "center" }}>{!this.props.data.Artist ? "No known artist" : this.props.data.Artist}</div>
        </Card.Item>
        <Card.Item>
          <CSSTransition in={this.state.hover} timeout={0} classNames="grid-card__slide">
            <Stack horizontal className="grid-card__buttons">
              <a
                href={this.props.data.Museum_Page}
                onClick={() => this.props.handleTrackEvent("Source", { "Location": "SearchPage", "ArtLink": this.props.data.Link_Resource })}
                className="grid-card__button_link"
                target="_blank"
                rel="noopener noreferrer">View Source at {museumName}</a>
              <div className="grid-card__button_sep"></div>
            </Stack>
          </CSSTransition>
        </Card.Item>
      </Card>
    );
  }
Example #15
Source File: ErrorPage.tsx    From hypertrons-crx with Apache License 2.0 5 votes vote down vote up
ErrorPage: React.FC<ErrorPageProps> = ({ errorCode }) => {
  const [inited, setInited] = useState(false);
  const [settings, setSettings] = useState(new Settings());

  useEffect(() => {
    const initSettings = async () => {
      const temp = await loadSettings();
      setSettings(temp);
      setInited(true);
    };
    if (!inited) {
      initSettings();
    }
  }, [inited, settings]);

  const errMessageObj = getMessageByLocale(
    `global_error_message_${errorCode}`,
    settings.locale
  );

  const onButtonClick = () => {
    history.go(-1);
  };

  return (
    <Stack
      tokens={stackTokens}
      style={{
        width: '250px',
        margin: 'auto',
      }}
    >
      <Stack.Item>
        <FontIcon iconName="PageRemove" style={{ fontSize: 30 }} />
      </Stack.Item>
      <Stack.Item>
        <h3>{errMessageObj.status}</h3>
      </Stack.Item>
      <Stack.Item>
        <strong>{errMessageObj.measure.text}</strong>
        <ul style={{ margin: '15px 0 0 15px' }}>
          {errMessageObj.measure.tips.map((tip: string) => {
            return <li>{tip}</li>;
          })}
        </ul>
      </Stack.Item>
      <Stack.Item>
        <Link href={HYPERTRONS_CRX_NEW_ISSUE} target="_blank" underline>
          {getMessageByLocale('global_sendFeedback', settings.locale)}
        </Link>
      </Stack.Item>
      <Stack.Item>
        <DefaultButton
          text={getMessageByLocale('global_btn_goBack', settings.locale)}
          iconProps={navigateBackIcon}
          onClick={onButtonClick}
        />
      </Stack.Item>
    </Stack>
  );
}
Example #16
Source File: RecordDetails.tsx    From NetworkViewPCF with MIT License 5 votes vote down vote up
render() {
    const { node, link } = this.props;
    return (
      <>
        {node && (
          <Stack styles={{ root: { padding: 10 } }}>
            <Stack.Item>{node.settings.displayName}</Stack.Item>
            <Stack.Item>
              <Stack horizontal verticalAlign="center">
                <Stack.Item>
                  <Link onClick={this.openRecord}>{node.name}</Link>
                </Stack.Item>
                <IconButton iconProps={{ iconName: "OpenInNewWindow" }} onClick={this.openRecord}></IconButton>
              </Stack>
            </Stack.Item>
          </Stack>
        )}
        {link && (
          <Stack styles={{ root: { padding: 10 } }}>
            <Stack horizontal tokens={{ childrenGap: 8 }} verticalAlign="center">
              <Stack.Item>{(link.source as RecordNode).settings.displayName}</Stack.Item>
              <Stack.Item>
                <Icon iconName="NavigateBackMirrored"></Icon>
              </Stack.Item>
              <Stack.Item>{(link.target as RecordNode).settings.displayName}</Stack.Item>
            </Stack>
            {link.intersect && (
              <>
                <Stack.Item>{link.intersect.settings.displayName}</Stack.Item>
                <Stack.Item>
                  {link.intersect.data?.formattedValues && link.intersect.data.formattedValues["_record1roleid_value"]}{" "}
                  {link.intersect.data?.formattedValues && link.intersect.data.formattedValues["_record2roleid_value"]}
                </Stack.Item>
              </>
            )}
          </Stack>
        )}
      </>
    );
  }
Example #17
Source File: SigninPage.tsx    From msteams-meetings-template with MIT License 5 votes vote down vote up
function SigninPageComponent(props: Partial<SigninPageProps>) {
  const onSignIn = props.onSignIn ?? (() => {});

  return (
    <>
      <div className="microsoftLogo">
        <svg xmlns="http://www.w3.org/2000/svg" width="108" height="24">
          <path
            d="M44.836 4.6v13.8h-2.4V7.583H42.4L38.119 18.4h-1.588L32.142 7.583h-.029V18.4H29.9V4.6h3.436L37.3 14.83h.058L41.545 4.6zm2 1.049a1.268 1.268 0 01.419-.967 1.413 1.413 0 011-.39 1.392 1.392 0 011.02.4 1.3 1.3 0 01.4.958 1.248 1.248 0 01-.414.953 1.428 1.428 0 01-1.01.385A1.4 1.4 0 0147.25 6.6a1.261 1.261 0 01-.409-.948M49.41 18.4h-2.329V8.507h2.329zm7.064-1.694a3.213 3.213 0 001.145-.241 4.811 4.811 0 001.155-.635V18a4.665 4.665 0 01-1.266.481 6.886 6.886 0 01-1.554.164 4.707 4.707 0 01-4.918-4.908 5.641 5.641 0 011.4-3.932 5.055 5.055 0 013.955-1.545 5.414 5.414 0 011.324.168 4.431 4.431 0 011.063.39v2.233a4.763 4.763 0 00-1.1-.611 3.184 3.184 0 00-1.15-.217 2.919 2.919 0 00-2.223.9 3.37 3.37 0 00-.847 2.416 3.216 3.216 0 00.813 2.338 2.936 2.936 0 002.209.837m8.92-8.371a2.952 2.952 0 01.5.039 2.1 2.1 0 01.375.1v2.358a2.04 2.04 0 00-.534-.255 2.646 2.646 0 00-.852-.12 1.808 1.808 0 00-1.448.722 3.467 3.467 0 00-.592 2.223v4.99h-2.324V8.507h2.329v1.559h.038a2.729 2.729 0 01.963-1.266 2.611 2.611 0 011.545-.457m1 5.254a5.358 5.358 0 011.392-3.887 5.1 5.1 0 013.85-1.434 4.742 4.742 0 013.623 1.381 5.212 5.212 0 011.3 3.729 5.257 5.257 0 01-1.386 3.83 5.019 5.019 0 01-3.772 1.424 4.935 4.935 0 01-3.652-1.352 4.987 4.987 0 01-1.349-3.688m2.425-.077a3.535 3.535 0 00.7 2.368 2.505 2.505 0 002.011.818 2.345 2.345 0 001.934-.818 3.783 3.783 0 00.664-2.425 3.651 3.651 0 00-.688-2.411 2.389 2.389 0 00-1.929-.813 2.44 2.44 0 00-1.988.852 3.707 3.707 0 00-.707 2.43m11.2-2.416a1 1 0 00.318.785 5.426 5.426 0 001.4.717 4.767 4.767 0 011.959 1.256 2.6 2.6 0 01.563 1.689 2.715 2.715 0 01-1.068 2.239 4.558 4.558 0 01-2.9.847 6.978 6.978 0 01-1.362-.149 6.047 6.047 0 01-1.265-.38v-2.29a5.733 5.733 0 001.367.7 4 4 0 001.328.26 2.365 2.365 0 001.164-.221.79.79 0 00.375-.741 1.029 1.029 0 00-.39-.813 5.768 5.768 0 00-1.477-.765 4.564 4.564 0 01-1.829-1.213 2.655 2.655 0 01-.539-1.713 2.706 2.706 0 011.063-2.2 4.243 4.243 0 012.765-.86 6.663 6.663 0 011.164.115 5.161 5.161 0 011.078.3v2.214a4.974 4.974 0 00-1.078-.529 3.6 3.6 0 00-1.222-.221 1.781 1.781 0 00-1.034.26.824.824 0 00-.371.712m5.241 2.493a5.358 5.358 0 011.386-3.89 5.1 5.1 0 013.849-1.434 4.743 4.743 0 013.624 1.381 5.212 5.212 0 011.3 3.729 5.259 5.259 0 01-1.386 3.83 5.02 5.02 0 01-3.773 1.424 4.934 4.934 0 01-3.652-1.352 4.987 4.987 0 01-1.348-3.688m2.425-.077a3.537 3.537 0 00.7 2.368 2.506 2.506 0 002.011.818 2.345 2.345 0 001.934-.818 3.783 3.783 0 00.664-2.425 3.651 3.651 0 00-.688-2.411 2.39 2.39 0 00-1.93-.813 2.439 2.439 0 00-1.987.852 3.707 3.707 0 00-.707 2.43m15.464-3.109H99.7V18.4h-2.359v-7.988h-1.655V8.507h1.655V7.13a3.423 3.423 0 011.015-2.555 3.561 3.561 0 012.6-1 5.807 5.807 0 01.751.043 2.993 2.993 0 01.577.13v2.016a2.422 2.422 0 00-.4-.164 2.107 2.107 0 00-.664-.1 1.407 1.407 0 00-1.126.457 2.017 2.017 0 00-.394 1.356v1.194h3.469V6.283l2.339-.712v2.936h2.358v1.906h-2.358v4.629a1.951 1.951 0 00.332 1.29 1.326 1.326 0 001.044.375 1.557 1.557 0 00.486-.1 2.294 2.294 0 00.5-.231V18.3a2.737 2.737 0 01-.736.231 5.029 5.029 0 01-1.015.106 2.887 2.887 0 01-2.209-.784 3.341 3.341 0 01-.736-2.363z"
            fill="#737373"
          />
          <path fill="#f25022" d="M0 0h10.931v10.931H0z" />
          <path fill="#7fba00" d="M12.069 0H23v10.931H12.069z" />
          <path fill="#00a4ef" d="M0 12.069h10.931V23H0z" />
          <path fill="#ffb900" d="M12.069 12.069H23V23H12.069z" />
        </svg>
      </div>

      <Stack
        className="container"
        horizontalAlign="center"
        verticalAlign="center"
        verticalFill
        tokens={{
          childrenGap: 35
        }}
      >
        <img
          className="splashImage"
          src={signInImage}
          alt={translate('signin.logo')}
        />
        <Text variant="xLargePlus" styles={boldStyle} className="signinHeader">
          <FormattedMessage id="signin.header" />
        </Text>

        <Text variant="medium" className="uTextCenter signinSubHeader">
          <FormattedMessage id="signin.subheader.lead" />
        </Text>
        <Text variant="medium" className="uTextCenter signinSubHeader">
          <FormattedMessage id="signin.subheader.signin" />
        </Text>

        <PrimaryButton
          className="teamsButton"
          onClick={() => onSignIn()}
          ariaLabel={translate('signin.button.ariaLabel')}
        >
          <FormattedMessage id="signin.button" />
        </PrimaryButton>
      </Stack>
    </>
  );
}
Example #18
Source File: OpenRow.tsx    From AIPerf with MIT License 5 votes vote down vote up
render(): React.ReactNode {
        const { isHidenInfo, typeInfo, info } = this.state;
        const trialId = this.props.trialId;
        const trial = TRIALS.getTrial(trialId);
        const trialLink: string = `${MANAGER_IP}/trial-jobs/${trialId}`;
        const logPathRow = trial.info.logPath || 'This trial\'s log path is not available.';
        const multiProgress = trial.info.hyperParameters === undefined ? 0 : trial.info.hyperParameters.length;
        return (
            <Stack className="openRow">
                <Stack className="openRowContent">
                    <Pivot>
                        <PivotItem headerText="Parameters" key="1" itemIcon="TestParameter">
                            {
                                EXPERIMENT.multiPhase
                                    ?
                                    <Stack className="link">
                                        {
                                            `
                                        Trails for multiphase experiment will return a set of parameters,
                                        we are listing the latest parameter in webportal.
                                        For the entire parameter set, please refer to the following "
                                        `
                                        }
                                        <a href={trialLink} rel="noopener noreferrer" target="_blank">{trialLink}</a>{`".`}
                                        <div>Current Phase: {multiProgress}.</div>
                                    </Stack>
                                    :
                                    null
                            }
                            {
                                trial.info.hyperParameters !== undefined
                                    ?
                                    <Stack id="description">
                                        <Stack className="bgHyper">
                                            <JSONTree
                                                hideRoot={true}
                                                shouldExpandNode={(): boolean => true}  // default expandNode
                                                getItemString={(): null => null}  // remove the {} items
                                                data={trial.description.parameters}
                                            />
                                        </Stack>
                                        <Stack horizontal className="copy">
                                            <PrimaryButton
                                                onClick={this.copyParams.bind(this, trial)}
                                                text="Copy as json"
                                                styles={{ root: { width: 128, marginRight: 10 } }}
                                            />
                                            {/* copy success | failed message info */}
                                            {!isHidenInfo && <MessageInfo typeInfo={typeInfo} info={info} />}
                                        </Stack>
                                    </Stack>
                                    :
                                    <Stack className="logpath">
                                        <span className="logName">Error: </span>
                                        <span className="error">{`This trial's parameters are not available.'`}</span>
                                    </Stack>
                            }
                        </PivotItem>
                        <PivotItem headerText="Log" key="2" itemIcon="M365InvoicingLogo">
                            {
                                // FIXME: this should not be handled in web UI side
                                EXPERIMENT.trainingServicePlatform !== 'local'
                                    ?
                                    <PaiTrialLog
                                        logStr={logPathRow}
                                        id={trialId}
                                        logCollection={EXPERIMENT.logCollectionEnabled}
                                    />
                                    :
                                    <TrialLog logStr={logPathRow} id={trialId} />
                            }
                        </PivotItem>
                    </Pivot>
                </Stack >
            </Stack>
        );
    }
Example #19
Source File: CopyMeetingPage.tsx    From msteams-meetings-template with MIT License 5 votes vote down vote up
function CopyMeetingPageComponent(props: CopyMeetingPageProps) {
  return (
    <>
      <Header />
      <Stack
        className="container"
        verticalFill
        tokens={{
          childrenGap: 35
        }}
      >
        <Stack.Item align="center" className="meetingCardContainer">
          <svg
            className="meetingSuccess"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 48 48"
          >
            <path
              d="M24 0c2.2 0 4.3.3 6.4.9 2 .6 3.9 1.4 5.7 2.4 1.8 1 3.4 2.3 4.9 3.8 1.5 1.5 2.7 3.1 3.8 4.9 1 1.8 1.8 3.7 2.4 5.7.6 2 .9 4.2.9 6.4s-.3 4.3-.9 6.3c-.6 2-1.4 3.9-2.4 5.7-1 1.8-2.3 3.4-3.8 4.9-1.5 1.5-3.1 2.7-4.9 3.8-1.8 1-3.7 1.9-5.7 2.4-2 .6-4.1.9-6.4.9-2.2 0-4.3-.3-6.3-.9-2-.6-3.9-1.4-5.7-2.4-1.8-1-3.4-2.3-4.9-3.8-1.5-1.5-2.7-3.1-3.8-4.9-1-1.8-1.9-3.7-2.4-5.7C.3 28.3 0 26.2 0 24s.3-4.3.9-6.4c.6-2 1.4-3.9 2.4-5.7 1-1.8 2.3-3.4 3.8-4.9 1.5-1.5 3.1-2.7 4.9-3.8 1.8-1 3.7-1.9 5.7-2.4S21.8 0 24 0zm7.9 17.1c-.6 0-1.2.2-1.6.7l-8.5 8.5-3-3c-.4-.4-1-.7-1.6-.7-.3 0-.6.1-.8.2-.3.1-.5.3-.7.5s-.4.4-.5.7c-.2.3-.2.5-.2.8 0 .6.2 1.2.7 1.6l4.6 4.6c.4.4 1 .7 1.6.7.6 0 1.2-.2 1.6-.7l10.1-10.1c.4-.5.7-1 .7-1.6 0-.3-.1-.6-.2-.8-.1-.3-.3-.5-.5-.7s-.4-.4-.7-.5c-.4-.2-.7-.2-1-.2z"
              fill="#599c00"
            />
          </svg>

          <Text block variant="xLarge" className="meetingCardHeader">
            <FormattedMessage id="copyMeetingPage.header" />
          </Text>
          <div
            className="meetingCardBody"
            id="copy"
            dangerouslySetInnerHTML={{ __html: props.meeting?.preview ?? '' }}
          />
          <PrimaryButton
            className="teamsButton copyButton"
            onClick={() => props.onCopyToClipboard(props.meeting)}
            ariaLabel={translate('copyMeetingPage.copy.ariaLabel')}
          >
            <FormattedMessage id="copyMeetingPage.copy" />
          </PrimaryButton>
        </Stack.Item>
      </Stack>
    </>
  );
}
Example #20
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 #21
Source File: SiteScriptSamplePicker.tsx    From sp-site-designs-studio with MIT License 4 votes vote down vote up
SiteScriptSamplePicker = (props: ISiteScriptSamplePickerProps) => {
    const [appContext, execute] = useAppContext<IApplicationState, any>();
    const samplesService = appContext.serviceScope.consume(SiteScriptSamplesServiceKey);

    const [repo, setRepo] = useState<{
        availableRepositories: ISiteScriptSamplesRepository[];
        currentRepository: ISiteScriptSamplesRepository;
    }>({
        availableRepositories: [],
        currentRepository: null
    });
    const [selectedSampleKey, setSelectedSampleKey] = useState<string>(null);
    const [availableSamples, setAvailableSamples] = useState<ISiteScriptSample[]>([]);
    const [isLoadingAllSamples, setIsLoadingAllSamples] = useState<boolean>(true);
    const [isLoadingSampleDetails, setIsLoadingSampleDetails] = useState<boolean>(false);
    const [searchCriteria, setSearchCriteria] = useState<string>('');

    const getSamples = async (repository: ISiteScriptSamplesRepository) => {
        repository = repository || repo.currentRepository;
        return repository ? await samplesService.getSamples(repository) : [];
    };

    const initialLoad = async () => {
        try {
            const availableRepositories = await samplesService.getAvailableRepositories();
            // Select the first available repository and get the samples from it
            const currentRepository = availableRepositories && availableRepositories.length > 0 ? availableRepositories[0] : null;
            setRepo({ currentRepository, availableRepositories });

            const foundSamples = await getSamples(currentRepository);
            setAvailableSamples(foundSamples);
            setIsLoadingAllSamples(false);
        } catch (error) {
            setIsLoadingAllSamples(false);
            // TODO Determine the reason of the error
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: "All samples cannot be loaded...",
                    userMessageType: MessageBarType.error
                }
            });
        }

    };

    const justMounted = useRef<boolean>(false);
    useEffect(() => {
        initialLoad();
        justMounted.current = true;
    }, []);

    const loadSampleData = async (sample: ISiteScriptSample) => {
        try {
            setIsLoadingSampleDetails(true);
            const loadedSample = await samplesService.getSample(sample);
            setIsLoadingSampleDetails(false);
            return loadedSample;
        } catch (error) {
            setIsLoadingSampleDetails(false);
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: "Sample cannot be loaded...",
                    userMessageType: MessageBarType.error
                }
            });
            return null;
        }
    };

    const selectSample = async (sample: ISiteScriptSample) => {
        setSelectedSampleKey(sample.key);
        const loadedSample = await loadSampleData(sample);
        if (props.onSelectedSample) {
            props.onSelectedSample(loadedSample);
        }
    };

    const renderSampleItem = (item: ISelectableSiteScriptSample, finalSize: ISize, isCompact: boolean): JSX.Element => {

        return <div
            data-is-focusable={true}
            role="listitem"
            aria-label={item.sample.key}
            className={item.selected ? styles.selectedSample : ''}
        >
            <DocumentCard
                type={isCompact ? DocumentCardType.compact : DocumentCardType.normal}
                onClick={(ev: React.SyntheticEvent<HTMLElement>) => selectSample(item.sample)}>
                <div className={styles.iconBox}>
                    <div className={styles.icon}>
                        <Icon iconName="Script" />
                    </div>
                </div>
                <DocumentCardDetails>
                    <DocumentCardTitle
                        title={item.sample.key}
                        shouldTruncate={true}
                    />
                </DocumentCardDetails>
            </DocumentCard>
        </div>;
    };

    return <div className={styles.row}>
        {isLoadingAllSamples && <div className={styles.column}>
            <ProgressIndicator label="Loading..." />
        </div>}
        {!isLoadingAllSamples && <div className={`${selectedSampleKey ? styles.column6 : styles.column}`}>
            <Stack tokens={{ childrenGap: 3 }}>
                <SearchBox underlined value={searchCriteria} onChange={setSearchCriteria} placeholder={"Search a sample..."} />
                <div className={styles.sampleGallery}>
                    <GridLayout
                        ariaLabel="List of Site Scripts samples."
                        items={availableSamples
                            .filter(s => !searchCriteria || s.key.toLowerCase().indexOf(searchCriteria.toLowerCase()) > -1)
                            .map(s => ({ sample: s, selected: s.key == selectedSampleKey }))}
                        onRenderGridItem={renderSampleItem}
                    />
                </div>
            </Stack>
        </div>}
        {selectedSampleKey && <div className={`${styles.column6}`}>
            <div key="sample-readme">
                {isLoadingSampleDetails ? <ProgressIndicator label="Loading..." />
                    : <div>
                        {props.selectedSample &&
                            <div>
                                <Pivot>
                                    <PivotItem itemKey="readme" headerText="README">
                                        {props.selectedSample.readmeHtml
                                            ? <div className={styles.readmeViewer} dangerouslySetInnerHTML={{ __html: props.selectedSample.readmeHtml }} />
                                            : <MessageBar messageBarType={MessageBarType.warning}>
                                                {"README of this sample cannot be displayed..."}
                                            </MessageBar>}
                                    </PivotItem>
                                    <PivotItem itemKey="json" headerText="JSON">
                                        {props.selectedSample.jsonContent
                                            ? <div>
                                                {props.selectedSample.hasPreprocessedJsonContent && <MessageBar messageBarType={MessageBarType.warning}>
                                                    {"The JSON of this sample has been preprocessed..."}<br />
                                                    {`Visit`}<a href={props.selectedSample.webSite} target="_blank">{`this page`}</a> {` to view the original sample`}
                                                </MessageBar>}
                                                <CodeEditor
                                                    height="70vh"
                                                    language="json"
                                                    options={{
                                                        readOnly: true,
                                                        folding: true,
                                                        renderIndentGuides: true,
                                                        minimap: {
                                                            enabled: false
                                                        }
                                                    }}
                                                    value={props.selectedSample.jsonContent}
                                                />
                                            </div>
                                            : <MessageBar messageBarType={MessageBarType.warning}>
                                                {"A usable JSON file cannot be found in this sample..."}<br />
                                                {`Visit`}<a href={props.selectedSample.webSite} target="_blank">{`this page`}</a> {` to explore this sample`}
                                            </MessageBar>}
                                    </PivotItem>
                                </Pivot>
                            </div>
                        }
                    </div>}
            </div>
        </div>}
    </div>;
}
Example #22
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 #23
Source File: SiteScriptDesigner.tsx    From sp-site-designs-studio with MIT License 4 votes vote down vote up
SiteScriptActionDesignerBlock = (props: ISiteScriptActionDesignerBlockProps) => {

    const [appContext] = useAppContext<IApplicationState, ActionType>();

    // Get service references
    const siteScriptSchemaService = appContext.serviceScope.consume(SiteScriptSchemaServiceKey);
    const rendering = appContext.serviceScope.consume(RenderingServiceKey);
    const [seeMore, setSeeMore] = useState<boolean>(false);
    const [isSortingSubactions, setIsSortingSubactions] = useState<boolean>(false);


    const getActionDescription = () => siteScriptSchemaService.getActionDescription(props.siteScriptAction, props.parentSiteScriptAction);
    const getActionLabel = () => siteScriptSchemaService.getActionTitle(props.siteScriptAction, props.parentSiteScriptAction);
    const getAddableActions = () => {
        const groupLabel = `${getActionLabel()} - Subactions`;
        return {
            [groupLabel]: siteScriptSchemaService.getAvailableSubActions(props.siteScriptAction).map(a => ({
                group: groupLabel,
                iconName: "SetAction",
                key: a.verb,
                text: a.label,
                item: a
            } as IAddableItem))
        };
    };

    const toggleEdit = () => {
        props.onSiteScriptContentUIChanged(props.siteScriptContentUI.toggleEditing(props.siteScriptAction));
    };

    const onActionUpdated = (siteScriptAction: ISiteScriptActionUIWrapper) => {
        props.onSiteScriptContentUIChanged(props.siteScriptContentUI.replaceAction(siteScriptAction));
    };

    const onActionAdded = (verb: string, parentSiteScriptAction?: ISiteScriptActionUIWrapper) => {
        const newAction = parentSiteScriptAction
            ? siteScriptSchemaService.getNewSubActionFromVerb(parentSiteScriptAction.verb, verb)
            : siteScriptSchemaService.getNewActionFromVerb(verb);
        const updatedContentUI = parentSiteScriptAction
            ? props.siteScriptContentUI.addSubAction(parentSiteScriptAction, newAction)
            : props.siteScriptContentUI.addAction(newAction);
        props.onSiteScriptContentUIChanged(updatedContentUI);
    };

    const onActionRemoved = (removedAction: ISiteScriptActionUIWrapper, parentSiteScriptAction?: ISiteScriptActionUIWrapper) => {
        const updatedContentUI = parentSiteScriptAction
            ? props.siteScriptContentUI.removeSubAction(parentSiteScriptAction, removedAction)
            : props.siteScriptContentUI.removeAction(removedAction);
        props.onSiteScriptContentUIChanged(updatedContentUI);
    };

    const renderSummaryContent = (() => {
        const summaryValues = siteScriptSchemaService.getPropertiesAndValues(props.siteScriptAction, props.parentSiteScriptAction);
        if (!seeMore) {
            const previewSummary = summaryValues.slice(0, SEE_PROPERTIES_DEFAULT_COUNT);
            const displaySeeMoreLink = summaryValues.length >= SEE_PROPERTIES_DEFAULT_COUNT && !seeMore;
            return <ul>
                {previewSummary.map((pv, index) => <li key={`${props.siteScriptAction.$uiKey}_prop_${index}`}>{pv.property}: <strong title={pv.value}>{(!pv.value && pv.value !== false) ? "Not set" : getTrimmedText(pv.value, SUMMARY_VALUE_MAX_LEN)}</strong></li>)}
                {displaySeeMoreLink && <li key={`${props.siteScriptAction.$uiKey}_more_prop`}><Link onClick={() => setSeeMore(true)}>...</Link></li>}
            </ul>;
        } else {
            return <ul>
                {summaryValues.map((pv, index) => <li key={`${props.siteScriptAction.$uiKey}_prop_${index}`}>{pv.property}: <strong title={pv.value}>{!pv.value ? "Not set" : getTrimmedText(pv.value, SUMMARY_VALUE_MAX_LEN)}</strong></li>)}
            </ul>;
        }
    });

    const DragHandle = SortableHandle(() =>
        <div>
            <Icon iconName={props.index === (props.actionsCount - 1) ? "SortUp" : props.index === 0 ? "SortDown" : "Sort"} />
        </div>
    );

    const onSubActionSortChanged = (args: ISortEndEventArgs) => {
        props.onSiteScriptContentUIChanged(props.siteScriptContentUI.reorderSubActions(props.siteScriptAction.$uiKey, args.newIndex, args.oldIndex));
    };


    const toggleSortingSubactions = () => {
        if (!isSortingSubactions) {
            setTimeout(() => {
                props.onSiteScriptContentUIChanged(props.siteScriptContentUI.clearEditing([props.parentSiteScriptAction.$uiKey]));
            }, 0);
        }
        setIsSortingSubactions(!isSortingSubactions);
    };

    const renderScriptSubAction = (scriptActionUI: ISiteScriptActionUIWrapper, index: number) => {

        const scriptActionBlock = <SiteScriptActionDesignerBlock key={scriptActionUI.$uiKey}
            siteScriptAction={scriptActionUI}
            parentSiteScriptAction={props.siteScriptAction}
            siteScriptContentUI={props.siteScriptContentUI}
            onSiteScriptContentUIChanged={props.onSiteScriptContentUIChanged}
            isSorting={isSortingSubactions}
            index={index}
            actionsCount={(props.siteScriptAction
                && props.siteScriptAction.subactions
                && props.siteScriptAction.subactions.length) || 0}
        />;

        if (isSortingSubactions) {
            const SortableItem = SortableElement(() => scriptActionBlock);
            return <SortableItem key={scriptActionUI.$uiKey} index={index} />;
        } else {
            return scriptActionBlock;
        }
    };

    const renderScriptSubActionsList = () => {
        if (!props.siteScriptAction.subactions) {
            return null;
        }

        if (isSortingSubactions) {
            const SortableListContainer = SortableContainer(({ items }) => {
                return <div>{items.map(renderScriptSubAction)}</div>;
            });

            return <SortableListContainer
                items={props.siteScriptAction.subactions}
                // onSortStart={(args) => this._onSortStart(args)}
                onSortEnd={(args: any) => onSubActionSortChanged(args)}
                lockToContainerEdges={true}
                useDragHandle={false}
            />;
        } else {
            return <div>{props.siteScriptAction.subactions.map(renderScriptSubAction)}</div>;
        }
    };



    const hasSubActions = siteScriptSchemaService.hasSubActions(props.siteScriptAction);
    const isEditing = props.siteScriptContentUI.editingActionKeys.indexOf(props.siteScriptAction.$uiKey) >= 0;
    return <div className={`${styles.siteScriptAction} ${isEditing ? styles.isEditing : ""} ${props.isSorting ? styles.isSorting : ''}`}>
        <h4 title={getActionDescription()}>
            {props.isSorting && <span className={styles.sortIndex}>{props.index + 1}</span>}
            <span className={styles.actionLabelText}>{getActionLabel()}</span>
        </h4>
        <div className={styles.tools}>
            <Stack horizontal tokens={{ childrenGap: 3 }}>
                {!isEditing && props.isSorting && <DragHandle />}
                {!props.isSorting && <IconButton iconProps={{ iconName: isEditing ? "Accept" : "Edit" }} onClick={() => toggleEdit()} />}
                {!props.isSorting && !isEditing && <IconButton iconProps={{ iconName: "Delete" }} onClick={() => onActionRemoved(props.siteScriptAction, props.parentSiteScriptAction)} />}
            </Stack>
        </div>
        <div className={`${styles.summary} ${!isEditing || isSortingSubactions ? styles.isNotEditing : styles.isEditing}`}>
            {renderSummaryContent()}
        </div>
        {isEditing && <div className={`${styles.properties} ${isEditing ? styles.isEditing : ""}`}>
            {rendering.renderActionProperties(props.siteScriptAction,
                props.parentSiteScriptAction,
                (o) => onActionUpdated({ ...props.siteScriptAction, ...o } as ISiteScriptActionUIWrapper), ['verb', 'subactions', '$uiKey', '$isEditing'])}
            {hasSubActions && <div className={styles.subactions}>
                <div className={styles.row}>
                    <div className={styles.column10}>
                        <Label>Subactions</Label>
                    </div>
                    <div className={styles.column2}>
                        {props.siteScriptAction.subactions && props.siteScriptAction.subactions.length > 1 && <IconButton iconProps={{ iconName: "Sort" }}
                            // styles={{ root: { position: "absolute", top: -32, right: 9 } }}
                            checked={isSortingSubactions}
                            onClick={toggleSortingSubactions} />}
                    </div>
                </div>
                {renderScriptSubActionsList()}
                {!isSortingSubactions && <Adder items={getAddableActions()}
                    searchBoxPlaceholderText="Search a sub action..."
                    onSelectedItem={(item) => onActionAdded(item.key, props.siteScriptAction)} />}
            </div>}
        </div>}
    </div>;
}
Example #24
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 #25
Source File: MeetingPage.tsx    From msteams-meetings-template with MIT License 4 votes vote down vote up
function DateTimePicker(props: DateTimePickerProps) {
  function getDatePickerStrings(): IDatePickerStrings {
    const localeData = moment.localeData();
    return {
      months: localeData.months(),
      shortMonths: localeData.monthsShort(),
      days: localeData.weekdays(),
      shortDays: localeData.weekdaysMin(),
      goToToday: translate('datePicker.goToToday'),
      prevMonthAriaLabel: translate('datePicker.previousMonth.ariaLabel'),
      nextMonthAriaLabel: translate('datePicker.nextMonth.ariaLabel'),
      prevYearAriaLabel: translate('datePicker.previousYear.ariaLabel'),
      nextYearAriaLabel: translate('datePicker.nextYear.ariaLabel'),
      closeButtonAriaLabel: translate('datePicker.close.ariaLabel'),
    };
  }

  function onDayPicked(date: Date | null | undefined) {
    const currentDateTime = moment(props.dateTime);

    const offsetFromStartOfDay = currentDateTime.diff(
      moment(currentDateTime).startOf('day')
    );
    const newDateTime = moment(date ?? currentDateTime)
      .startOf('day')
      .add(offsetFromStartOfDay);

    props.onTimeUpdated(newDateTime);
  }

  function onTimePicked(
    event: React.FormEvent<IComboBox>,
    option?: IComboBoxOption,
    index?: number,
    value?: string
  ) {
    const currentDateTimeStartOfDay = moment(props.dateTime).startOf('day');

    let newDateTime: moment.Moment;
    if (option) {
      const offsetFromStartOfDay = moment.duration(option.key, 'minutes');
      newDateTime = currentDateTimeStartOfDay.add(offsetFromStartOfDay);
    } else {
      // User entered a free-form string, try to parse it as a time
      const enteredTime = moment(value, timePickerFormat);
      if (enteredTime.isValid()) {
        const offsetFromStartOfDay = enteredTime.diff(
          moment(enteredTime).startOf('day')
        );
        newDateTime = currentDateTimeStartOfDay.add(offsetFromStartOfDay);
      } else {
        newDateTime = moment(props.dateTime);
      }
    }

    props.onTimeUpdated(newDateTime);
  }

  function onFormatDate(dateToFormat?: Date): string {
    return moment(dateToFormat).format(datePickerFormat);
  }

  function onParseDateFromString(value: string): Date {
    return moment(value, datePickerFormat).toDate();
  }

  const timeSuggestions = _.range(0, 1440, 30).map(minutes => {
    // if the selection is before the min value
    const projectedEndTime = moment(props.dateTime)
      .startOf('day')
      .add(moment.duration(minutes, 'minutes'));
    const isDisabled = moment(props.minDate).isAfter(projectedEndTime);
    const timeTag = moment()
      .startOf('day')
      .minutes(minutes)
      .format(timePickerFormat);
    const projectedDuration = moment.duration(
      moment(projectedEndTime).diff(props.minDate)
    );
    const projectedDurationString = _.trim(formatDuration(projectedDuration));

    return {
      key: minutes,
      text:
        props.includeDuration &&
        !isDisabled &&
        projectedDurationString.length > 0
          ? `${timeTag} (${projectedDurationString})`
          : timeTag,
      disabled: isDisabled
    };
  });

  return (
    <Stack horizontal>
      <DatePicker
        className="newMeetingDatePicker"
        borderless
        firstDayOfWeek={moment.localeData().firstDayOfWeek() as DayOfWeek}
        strings={getDatePickerStrings()}
        value={props.dateTime?.toDate()}
        formatDate={onFormatDate}
        parseDateFromString={onParseDateFromString}
        onSelectDate={onDayPicked}
        minDate={props.minDate?.toDate()}
      />
      <ComboBox
        className="newMeetingComboBox"
        styles={{ root: { maxHeight: '500px' } }}
        useComboBoxAsMenuWidth={!props.includeDuration}
        scrollSelectedToTop={true}
        allowFreeform={true}
        autoComplete="on"
        options={timeSuggestions}
        onChange={onTimePicked}
        text={props.dateTime?.format(timePickerFormat)}
      />
      {props.iconName === 'ReplyAlt' ? (
        <FontIcon className="newMeetingPickerIcon" iconName={props.iconName} />
      ) : (
        <Text className="newMeetingPickerIncrement" variant="smallPlus">
          {formatDuration(
            moment.duration(moment(props.dateTime).diff(moment(props.minDate)))
          )}
        </Text>
      )}
    </Stack>
  );
}
Example #26
Source File: ExplorePage.tsx    From art with MIT License 4 votes vote down vote up
render() {
        return (
            <Stack className="main" role="main">
                <NavBar />
                <div className="page-wrap" style={{ position: "relative", top: "-20px", width: "100%", overflow: "hidden" }}>
                    <HideAt breakpoint="mediumAndBelow">
                        <div className="explore__background-banner">
                            <img className="explore__parallax" alt={"Banner comparing two artworks"} src={bannerImage} />
                            <div className="explore__banner-text">Explore the hidden connections between art of different cultures and media.</div>
                        </div>
                        <div className="explore__solid">
                            <Stack horizontal horizontalAlign="center" verticalAlign="center" wrap>
                                <div className="explore__pick-image-text">Pick an image to get started:</div>
                                <ListCarousel
                                    items={defaultArtworks}
                                    selectorCallback={(am) => {
                                        this.props.history.push("/app/" + encodeURIComponent('?id=' + am.id!));
                                        this.executeQueryWithDefaults(am.id!)
                                    }}
                                    selectedArtwork={this.state.queryArtwork} />
                            </Stack>
                        </div>
                        <div style={{ backgroundColor: "white" }}><Separator /></div>
                        <div ref={this.startRef} className="explore__compare-block explore__solid">
                            <Stack horizontal>
                                <Stack.Item className={halfStack} grow={1}>
                                    <QueryArtwork artwork={this.state.queryArtwork} />
                                </Stack.Item>
                                <Stack.Item className={halfStack} grow={1}>
                                    <ResultArtwork artwork={this.state.chosenArtwork} />
                                </Stack.Item>
                            </Stack>
                        </div>
                    </HideAt>
                    <ShowAt breakpoint="mediumAndBelow">
                        <div className="explore__solid">
                            <Stack horizontal horizontalAlign="center" verticalAlign="center" wrap>
                                <div className="explore__pick-image-text">Pick an image to get started:</div>
                                <ListCarousel
                                    items={defaultArtworks}
                                    selectorCallback={(am) => {
                                        this.props.history.push("/app/" + encodeURIComponent('?id=' + am.id!));
                                        this.executeQueryWithDefaults(am.id!)
                                    }}
                                    selectedArtwork={this.state.chosenArtwork!} />
                            </Stack>
                        </div>
                        <Separator />
                        <div className="explore__compare-block explore__solid">
                            <Stack horizontal horizontalAlign="center" wrap>
                                <Stack.Item grow={1}>
                                    <QueryArtwork artwork={this.state.queryArtwork} />
                                </Stack.Item>
                                <Stack.Item grow={1}>
                                    <ResultArtwork artwork={this.state.chosenArtwork} />
                                </Stack.Item>
                            </Stack>
                        </div>
                    </ShowAt>
                    <div className="explore__solid">
                        <Stack horizontalAlign="center">
                            <Stack horizontal horizontalAlign="center">
                                <button
                                    onClick={() => {
                                        if (isBeta) {
                                            this.props.history.push("/app/" + encodeURIComponent('?id=' + this.state.chosenArtwork.id!));
                                            this.executeQueryWithDefaults(this.state.chosenArtwork.id!);
                                            logEvent("Matches", { "Location": "ResultImage" });
                                        } else {
                                            this.openModal()
                                        };
                                    }}
                                    className="explore__buttons button">Use Match as Query</button>
                                <Popup
                                    open={this.state.open}
                                    closeOnDocumentClick
                                    onClose={this.closeModal}
                                >
                                    <div className="modal">
                                        <button className="close" onClick={this.closeModal}>
                                            &times;
                                        </button>
                                        {betaMessageDiv}
                                    </div>
                                </Popup>
                            </Stack>
                        </Stack>

                        <Separator />
                        <div className="explore__big-text">Choose Different Cultures and Media:</div>
                        <Stack horizontal horizontalAlign="start" verticalAlign="center" wrap>
                            <Options
                                value={this.state.cultureFilter}
                                choices={cultures}
                                changeConditional={this.changeCulture} />
                            <ListCarousel
                                items={this.state.cultureItems!}
                                selectorCallback={this.setResultArtwork}
                                selectedArtwork={this.state.chosenArtwork!} />
                        </Stack>
                        <Separator />
                        <Stack horizontal horizontalAlign="start" verticalAlign="center" wrap>
                            <Options
                                value={this.state.mediumFilter}
                                choices={media}
                                changeConditional={this.changeMedium} />
                            <ListCarousel
                                items={this.state.mediumItems!}
                                selectorCallback={this.setResultArtwork}
                                selectedArtwork={this.state.chosenArtwork!} />
                        </Stack>
                        <Separator />
                        <Stack horizontal horizontalAlign="center">
                            <SubmitControl placeholder="Search the collection for other artworks" />
                        </Stack>
                        <Stack horizontalAlign="center">
                            <div className="explore__big-text">Learn More:</div>
                            <HideAt breakpoint="small">
                                <div className="explore__horizontal-img-container">
                                    <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2007.07177" >
                                        <button className="explore__buttons button">Read The Paper</button></a>
                                    <a target="_blank" rel="noopener noreferrer" href="https://note.microsoft.com/MSR-Webinar-Visual-Analogies-Registration-Live.html" >
                                        <button className="explore__buttons button">Watch The Webinar</button></a>
                                    <a target="_blank" rel="noopener noreferrer" href="https://github.com/microsoft/art" >
                                        <button className="explore__buttons button">Github</button></a>
                                </div>
                            </HideAt>
                            <ShowAt breakpoint="small">
                                <a target="_blank" rel="noopener noreferrer" href="https://arxiv.org/abs/2007.07177" >
                                    <button className="explore__buttons button">Read The Paper</button></a>
                                <a target="_blank" rel="noopener noreferrer" href="https://note.microsoft.com/MSR-Webinar-Visual-Analogies-Registration-Live.html" >
                                    <button className="explore__buttons button">Watch The Webinar</button></a>
                                <a target="_blank" rel="noopener noreferrer" href="https://github.com/microsoft/art" >
                                    <button className="explore__buttons button">Github</button></a>
                            </ShowAt>


                        </Stack>
                    </div>
                </div>
            </Stack>
        )
    }
Example #27
Source File: Popup.tsx    From hypertrons-crx with Apache License 2.0 4 votes vote down vote up
Popup: React.FC = () => {
  const [settings, setSettings] = useState(new Settings());
  const [metaData, setMetaData] = useState(new MetaData());
  const [inited, setInited] = useState(false);

  useEffect(() => {
    const initSettings = async () => {
      const temp = await loadSettings();
      setSettings(temp);
      setInited(true);
    };
    if (!inited) {
      initSettings();
    }
  }, [inited, settings]);

  useEffect(() => {
    const initMetaData = async () => {
      const temp = await loadMetaData();
      setMetaData(temp);
    };
    initMetaData();
  }, []);

  const saveSettings = async (settings: Settings) => {
    setSettings(settings);
    await chromeSet('settings', settings.toJson());
  };

  if (!inited) {
    return <div />;
  }

  return (
    <Stack horizontalAlign="center">
      <Stack
        horizontalAlign="space-around"
        verticalAlign="center"
        style={{ margin: '5px', padding: '3px' }}
        tokens={{
          childrenGap: 10,
        }}
      >
        <Stack horizontalAlign="center">
          <Toggle
            label={getMessageByLocale(
              'options_enable_toggle_autoCheck',
              settings.locale
            )}
            defaultChecked={settings.isEnabled}
            onText={getMessageByLocale('global_toggle_onText', settings.locale)}
            offText={getMessageByLocale(
              'global_toggle_offText',
              settings.locale
            )}
            onChange={async (e, checked) => {
              settings.isEnabled = checked;
              await saveSettings(settings);
            }}
          />
        </Stack>
        {metaData.token !== '' && (
          <Stack
            horizontal
            verticalAlign="center"
            style={{
              margin: '5px',
              padding: '3px',
              width: '200px',
            }}
            tokens={{
              childrenGap: 5,
            }}
          >
            <Image
              width={75}
              height={75}
              src={metaData.avatar}
              imageFit={ImageFit.centerCover}
            />
            <Text
              variant="large"
              style={{ marginLeft: 25, width: 100, wordWrap: 'break-word' }}
            >
              {metaData.name}
            </Text>
          </Stack>
        )}
        {metaData.token === '' && (
          <DefaultButton
            onClick={() => {
              chrome.runtime.openOptionsPage();
            }}
            style={{
              width: 120,
            }}
          >
            {getMessageByLocale('options_token_title', settings.locale)}
          </DefaultButton>
        )}
      </Stack>
    </Stack>
  );
}
Example #28
Source File: SiteScriptEditor.tsx    From sp-site-designs-studio with MIT License 3 votes vote down vote up
SiteScriptEditor = (props: ISiteScriptEditorProps) => {
    useTraceUpdate('SiteScriptEditor', props);
    const [appContext, execute] = useAppContext<IApplicationState, ActionType>();

    // Get service references
    const siteDesignsService = appContext.serviceScope.consume(SiteDesignsServiceKey);
    const siteScriptSchemaService = appContext.serviceScope.consume(SiteScriptSchemaServiceKey);
    const exportService = appContext.serviceScope.consume(ExportServiceKey);

    const [state, dispatchState] = useReducer(SiteScriptEditorReducer, {
        siteScriptMetadata: null,
        siteScriptContent: null,
        currentExportPackage: null,
        currentExportType: "json",
        isExportUIVisible: false,
        isSaving: false,
        isAssociatingToSiteDesign: false,
        isValidCode: true,
        updatedContentFrom: null
    });
    const { siteScriptMetadata,
        siteScriptContent,
        isValidCode,
        isExportUIVisible,
        currentExportType,
        currentExportPackage,
        isAssociatingToSiteDesign,
        isSaving } = state;

    // Use refs
    const codeEditorRef = useRef<any>();
    const titleFieldRef = useRef<any>();
    const selectedSiteDesignRef = useRef<string>();


    const setLoading = (loading: boolean) => {
        execute("SET_LOADING", { loading });
    };
    // Use Effects
    useEffect(() => {
        if (!props.siteScript.Id) {
            dispatchState({ type: "SET_SITE_SCRIPT", siteScript: props.siteScript });

            if (titleFieldRef.current) {
                titleFieldRef.current.focus();
            }
            return;
        }

        setLoading(true);
        console.debug("Loading site script...", props.siteScript.Id);
        siteDesignsService.getSiteScript(props.siteScript.Id).then(loadedSiteScript => {
            dispatchState({ type: "SET_SITE_SCRIPT", siteScript: loadedSiteScript });
            console.debug("Loaded: ", loadedSiteScript);
        }).catch(error => {
            console.error(`The Site Script ${props.siteScript.Id} could not be loaded`, error);
        }).then(() => {
            setLoading(false);
        });
    }, [props.siteScript]);

    const onTitleChanged = (ev: any, title: string) => {
        const siteScript = { ...siteScriptMetadata, Title: title };
        dispatchState({ type: "UPDATE_SITE_SCRIPT_METADATA", siteScript });
    };

    let currentDescription = useRef<string>(siteScriptMetadata && siteScriptMetadata.Description);
    const onDescriptionChanging = (ev: any, description: string) => {
        currentDescription.current = description;
    };

    const onDescriptionInputBlur = (ev: any) => {
        const siteScript = { ...siteScriptMetadata, Description: currentDescription.current };
        dispatchState({ type: "UPDATE_SITE_SCRIPT_METADATA", siteScript });
    };

    const onVersionChanged = (ev: any, version: string) => {
        const versionInt = parseInt(version);
        if (!isNaN(versionInt)) {
            const siteScript = { ...siteScriptMetadata, Version: versionInt };
            dispatchState({ type: "UPDATE_SITE_SCRIPT_METADATA", siteScript });
        }
    };

    const onSiteScriptContentUpdatedFromUI = (content: ISiteScriptContent) => {
        dispatchState({ type: "UPDATE_SITE_SCRIPT_CONTENT", content, from: "UI" });
    };

    const onSave = async () => {
        dispatchState({ type: "SET_ISSAVING", isSaving: true });
        try {
            const isNewSiteScript = !siteScriptMetadata.Id;
            const toSave: ISiteScript = { ...siteScriptMetadata, Content: state.siteScriptContent };
            const updated = await siteDesignsService.saveSiteScript(toSave);
            const refreshedSiteScripts = await siteDesignsService.getSiteScripts();
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: `${siteScriptMetadata.Title} has been successfully saved.`,
                    messageType: MessageBarType.success
                }
            } as ISetUserMessageArgs);
            execute("SET_ALL_AVAILABLE_SITE_SCRIPTS", { siteScripts: refreshedSiteScripts } as ISetAllAvailableSiteScripts);
            dispatchState({ type: "SET_SITE_SCRIPT", siteScript: updated });
            if (isNewSiteScript) {
                // Ask if the new Site Script should be associated to a Site Design
                if (await Confirm.show({
                    title: `Associate to Site Design`,
                    message: `Do you want to associate the new ${(siteScriptMetadata && siteScriptMetadata.Title)} to a Site Design ?`,
                    cancelLabel: 'No',
                    okLabel: 'Yes'
                })) {
                    dispatchState({ type: "SET_ISASSOCIATINGTOSITEDESIGN", isAssociatingToSiteDesign: true });
                }
            }
        } catch (error) {
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: `${siteScriptMetadata.Title} could not be saved. Please make sure you have SharePoint administrator privileges...`,
                    messageType: MessageBarType.error
                }
            } as ISetUserMessageArgs);
            console.error(error);
        }
        dispatchState({ type: "SET_ISSAVING", isSaving: false });

    };

    const onDelete = async () => {
        if (!await Confirm.show({
            title: `Delete Site Script`,
            message: `Are you sure you want to delete ${(siteScriptMetadata && siteScriptMetadata.Title) || "this Site Script"} ?`
        })) {
            return;
        }

        dispatchState({ type: "SET_ISSAVING", isSaving: true });
        try {
            await siteDesignsService.deleteSiteScript(siteScriptMetadata);
            const refreshedSiteScripts = await siteDesignsService.getSiteScripts();
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: `${siteScriptMetadata.Title} has been successfully deleted.`,
                    messageType: MessageBarType.success
                }
            } as ISetUserMessageArgs);
            execute("SET_ALL_AVAILABLE_SITE_SCRIPTS", { siteScripts: refreshedSiteScripts } as ISetAllAvailableSiteScripts);
            execute("GO_TO", { page: "SiteScriptsList" } as IGoToActionArgs);
        } catch (error) {
            execute("SET_USER_MESSAGE", {
                userMessage: {
                    message: `${siteScriptMetadata.Title} could not be deleted. Please make sure you have SharePoint administrator privileges...`,
                    messageType: MessageBarType.error
                }
            } as ISetUserMessageArgs);
            console.error(error);
        }
        dispatchState({ type: "SET_ISSAVING", isSaving: false });
    };

    const onAssociateSiteScript = () => {
        if (selectedSiteDesignRef.current != NEW_SITE_DESIGN_KEY) {
            execute("EDIT_SITE_DESIGN", { siteDesign: { Id: selectedSiteDesignRef.current }, additionalSiteScriptIds: [siteScriptMetadata.Id] });
        } else if (selectedSiteDesignRef.current) {
            execute("EDIT_SITE_DESIGN", { siteDesign: createNewSiteDesign(), additionalSiteScriptIds: [siteScriptMetadata.Id] });
        }
    };

    const onExportRequested = (exportType?: ExportType) => {
        const toExport: ISiteScript = { ...siteScriptMetadata, Content: siteScriptContent };
        let exportPromise: Promise<ExportPackage> = null;
        switch (exportType) {
            case "PnPPowershell":
                exportPromise = exportService.generateSiteScriptPnPPowershellExportPackage(toExport);
                break;
            case "PnPTemplate":
                break; // Not yet supported
            case "o365_PS":
                exportPromise = exportService.generateSiteScriptO365CLIExportPackage(toExport, "Powershell");
                break;
            case "o365_Bash":
                exportPromise = exportService.generateSiteScriptO365CLIExportPackage(toExport, "Bash");
                break;
            case "json":
            default:
                exportPromise = exportService.generateSiteScriptJSONExportPackage(toExport);
                break;
        }

        if (exportPromise) {
            exportPromise.then(exportPackage => {
                dispatchState({ type: "SET_EXPORTPACKAGE", exportPackage, exportType });
            });
        }
    };

    let codeUpdateTimeoutHandle: any = null;
    const onCodeChanged = (updatedCode: string) => {
        if (!updatedCode) {
            return;
        }

        if (codeUpdateTimeoutHandle) {
            clearTimeout(codeUpdateTimeoutHandle);
        }

        // if (updatedContentFrom == "UI") {
        //     // Not trigger the change of state if the script content was updated from UI
        //     console.debug("The code has been modified after a change in designer. The event will not be propagated");
        //     dispatchState({ type: "UPDATE_SITE_SCRIPT", siteScript: null, from: "CODE" });
        //     return;
        // }

        codeUpdateTimeoutHandle = setTimeout(() => {
            try {
                const jsonWithIgnoredComments = updatedCode.replace(/\/\*(.*)\*\//g,'');
                if (siteScriptSchemaService.validateSiteScriptJson(jsonWithIgnoredComments)) {
                    const content = JSON.parse(jsonWithIgnoredComments) as ISiteScriptContent;
                    dispatchState({ type: "UPDATE_SITE_SCRIPT_CONTENT", content, isValidCode: true, from: "CODE" });
                } else {
                    dispatchState({ type: "UPDATE_SITE_SCRIPT_CONTENT", content: null, isValidCode: false, from: "CODE" });

                }
            } catch (error) {
                console.warn("Code is not valid site script JSON");
            }
        }, 500);
    };

    const editorDidMount = (_, editor) => {

        const schema = siteScriptSchemaService.getSiteScriptSchema();
        codeEditorRef.current = editor;
        monaco.init().then(monacoApi => {
            monacoApi.languages.json.jsonDefaults.setDiagnosticsOptions({
                schemas: [{
                    uri: 'schema.json',
                    schema
                }],

                validate: true,
                allowComments: false
            });
        }).catch(error => {
            console.error("An error occured while trying to configure code editor");
        });

        const editorModel = editor.getModel();
        console.log("Editor model: ", editorModel);

        editor.onDidChangeModelContent(ev => {
            if (codeEditorRef && codeEditorRef.current) {
                onCodeChanged(codeEditorRef.current.getValue());
            }
        });
    };

    const checkIsValidForSave: () => [boolean, string?] = () => {
        if (!siteScriptMetadata) {
            return [false, "Current Site Script not defined"];
        }

        if (!siteScriptMetadata.Title) {
            return [false, "Please set the title of the Site Script..."];
        }

        if (!isValidCode) {
            return [false, "Please check the validity of the code..."];
        }

        return [true];
    };

    const isLoading = appContext.isLoading;
    const [isValidForSave, validationMessage] = checkIsValidForSave();
    if (!siteScriptMetadata || !siteScriptContent) {
        return null;
    }

    return <div className={styles.SiteScriptEditor}>
        <div className={styles.row}>
            <div className={styles.columnLayout}>
                <div className={styles.row}>
                    <div className={styles.column11}>
                        <TextField
                            styles={{
                                field: {
                                    fontSize: "32px",
                                    lineHeight: "45px",
                                    height: "45px"
                                },
                                root: {
                                    height: "60px",
                                    marginTop: "5px",
                                    marginBottom: "5px"
                                }
                            }}
                            placeholder="Enter the name of the Site Script..."
                            borderless
                            componentRef={titleFieldRef}
                            value={siteScriptMetadata.Title}
                            onChange={onTitleChanged} />
                        {isLoading && <ProgressIndicator />}
                    </div>
                    {!isLoading && <div className={`${styles.column1} ${styles.righted}`}>
                        <Stack horizontal horizontalAlign="end" tokens={{ childrenGap: 15 }}>
                            <CommandButton disabled={isSaving} iconProps={{ iconName: "More" }} menuProps={{
                                items: [
                                    (siteScriptMetadata.Id && {
                                        key: 'deleteScript',
                                        text: 'Delete',
                                        iconProps: { iconName: 'Delete' },
                                        onClick: onDelete
                                    }),
                                    {
                                        key: 'export',
                                        text: 'Export',
                                        iconProps: { iconName: 'Download' },
                                        onClick: () => onExportRequested(),
                                        disabled: !isValidForSave
                                    }
                                ].filter(i => !!i),
                            } as IContextualMenuProps} />
                            <PrimaryButton disabled={isSaving || !isValidForSave} text="Save" iconProps={{ iconName: "Save" }} onClick={() => onSave()} />
                        </Stack>
                    </div>}
                </div>
                <div className={styles.row}>
                    {siteScriptMetadata.Id && <div className={styles.half}>
                        <div className={styles.row}>
                            <div className={styles.column8}>
                                <TextField
                                    label="Id"
                                    readOnly
                                    value={siteScriptMetadata.Id} />
                            </div>
                            <div className={styles.column4}>
                                <TextField
                                    label="Version"
                                    value={siteScriptMetadata.Version.toString()}
                                    onChange={onVersionChanged} />
                            </div>
                        </div>
                    </div>}
                    <div className={styles.half}>
                        <TextField
                            label="Description"
                            value={siteScriptMetadata.Description}
                            multiline={true}
                            rows={2}
                            borderless
                            placeholder="Enter a description for the Site Script..."
                            onChange={onDescriptionChanging}
                            onBlur={onDescriptionInputBlur}
                        />
                    </div>
                </div>
                <div className={styles.row}>
                    <div className={styles.column}>
                        <Label>Actions</Label>
                    </div>
                </div>
                <div className={styles.row}>
                    <div className={styles.designerWorkspace}>
                        <SiteScriptDesigner
                            siteScriptContent={siteScriptContent}
                            onSiteScriptContentUpdated={onSiteScriptContentUpdatedFromUI} />
                    </div>
                    <div className={styles.codeEditorWorkspace}>
                        <CodeEditor
                            height="80vh"
                            language="json"
                            options={{
                                folding: true,
                                renderIndentGuides: true,
                                minimap: {
                                    enabled: false
                                }
                            }}
                            value={toJSON(siteScriptContent)}
                            editorDidMount={editorDidMount}
                        />
                    </div>
                </div>
            </div>
        </div>
        {/* Association to a Site Design */}
        <Panel isOpen={isAssociatingToSiteDesign}
            type={PanelType.smallFixedFar}
            headerText="Associate to a Site Design"
            onRenderFooterContent={(p) => <Stack horizontalAlign="end" horizontal tokens={{ childrenGap: 10 }}>
                <PrimaryButton iconProps={{ iconName: "Check" }} text="Continue" onClick={() => onAssociateSiteScript()} />
                <DefaultButton text="Cancel" onClick={() => dispatchState({ type: "SET_ISASSOCIATINGTOSITEDESIGN", isAssociatingToSiteDesign: false })} /></Stack>}
        >
            <SiteDesignPicker serviceScope={appContext.serviceScope}
                label="Site Design"
                onSiteDesignSelected={(siteDesignId) => {
                    console.log("Selected site design: ", siteDesignId);
                    selectedSiteDesignRef.current = siteDesignId;
                }}
                hasNewSiteDesignOption
                displayPreview />
        </Panel>
        {/* Export options */}
        <Panel isOpen={isExportUIVisible}
            type={PanelType.large}
            headerText="Export Site Script"
            onRenderFooterContent={(p) => <Stack horizontalAlign="end" horizontal tokens={{ childrenGap: 10 }}>
                <PrimaryButton iconProps={{ iconName: "Download" }} text="Download" onClick={() => currentExportPackage && currentExportPackage.download()} />
                <DefaultButton text="Cancel" onClick={() => dispatchState({ type: "SET_EXPORTPACKAGE", exportPackage: null })} /></Stack>}>
            <Pivot
                selectedKey={currentExportType}
                onLinkClick={(item) => onExportRequested(item.props.itemKey as ExportType)}
                headersOnly={true}
            >
                <PivotItem headerText="JSON" itemKey="json" />
                <PivotItem headerText="PnP Powershell" itemKey="PnPPowershell" />
                {/* <PivotItem headerText="PnP Template" itemKey="PnPTemplate" /> */}
                <PivotItem headerText="O365 CLI (Powershell)" itemKey="o365_PS" />
                <PivotItem headerText="O365 CLI (Bash)" itemKey="o365_Bash" />
            </Pivot>
            {currentExportPackage && <ExportPackageViewer exportPackage={currentExportPackage} />}
        </Panel>
    </div >;
}