office-ui-fabric-react#Pivot TypeScript Examples
The following examples show how to use
office-ui-fabric-react#Pivot.
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: OpenRow.tsx From AIPerf with MIT License | 5 votes |
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 #2
Source File: ExperimentDrawer.tsx From AIPerf with MIT License | 4 votes |
render(): React.ReactNode {
const { isVisble, closeExpDrawer } = this.props;
const { experiment, expDrawerHeight } = this.state;
return (
<Stack className="logDrawer">
<Panel
isOpen={isVisble}
hasCloseButton={false}
styles={{ root: { height: expDrawerHeight, paddingTop: 15 } }}
>
<Pivot style={{ minHeight: 190 }} className="log-tab-body">
<PivotItem headerText="Experiment Parameters">
<div className="just-for-log">
<MonacoEditor
width="100%"
// 92 + marginTop[16]
height={expDrawerHeight - 108}
language="json"
value={experiment}
options={DRAWEROPTION}
/>
</div>
<Stack horizontal className="buttons">
<StackItem grow={50} className="download">
<PrimaryButton
text="Download"
onClick={this.downExperimentParameters}
/>
</StackItem>
<StackItem grow={50} className="close">
<DefaultButton
text="Close"
onClick={closeExpDrawer}
/>
</StackItem>
</Stack>
</PivotItem>
</Pivot>
</Panel>
</Stack>
);
}
Example #3
Source File: LogDrawer.tsx From AIPerf with MIT License | 4 votes |
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 #4
Source File: TrialsDetail.tsx From AIPerf with MIT License | 4 votes |
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 #5
Source File: SiteScriptSamplePicker.tsx From sp-site-designs-studio with MIT License | 4 votes |
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 #6
Source File: SiteScriptEditor.tsx From sp-site-designs-studio with MIT License | 3 votes |
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 >;
}