office-ui-fabric-react#IconButton TypeScript Examples
The following examples show how to use
office-ui-fabric-react#IconButton.
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 |
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: PeopleSearchBox.tsx From spfx-msgraph-peoplesearch with MIT License | 6 votes |
private renderBasicSearchBox(): JSX.Element {
return (
<div className={styles.searchBoxWrapper}>
<SearchBox
placeholder={strings.SearchInputPlaceholder}
theme={this.props.themeVariant as ITheme}
className={styles.searchTextField}
value={this.state.searchInputValue}
autoComplete="off"
onChange={(event, value) => this.setState({ searchInputValue: value })}
onSearch={() => this._onSearch(this.state.searchInputValue)}
onClear={() => this._onSearch('', true)}
/>
<div className={styles.searchButton}>
{this.state.searchInputValue &&
<IconButton
onClick={() => this._onSearch(this.state.searchInputValue)}
iconProps={{ iconName: 'Forward' }}
/>
}
</div>
</div>
);
}
Example #3
Source File: GenericObjectEditor.tsx From sp-site-designs-studio with MIT License | 6 votes |
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 #4
Source File: SpfxPnpIframedialogExtension.tsx From SPFx with Mozilla Public License 2.0 | 6 votes |
@override
public render(): React.ReactElement<{}> {
return (
<div className={styles.cell}>
<IconButton iconProps={emojiIcon} onClick={this._alertClicked} />
<IFrameDialog
url={this.props.FileURL}
hidden={this.state.souldhide}
onDismiss={() => this.setState({ souldhide: true })}
modalProps={{
isBlocking: false
}}
dialogContentProps={{
type: DialogType.close,
showCloseButton: true
}}
width={'1000px'}
height={'600px'} />
</div>
);
}
Example #5
Source File: SitePicker.tsx From sp-site-designs-studio with MIT License | 5 votes |
SitePicker = (props: ISitePickerProps) => {
const sitesService = props.serviceScope.consume(SitesServiceKey);
const [selectedSite, setSelectedSite] = useState<ISPSite>(null);
const [isSearching, setIsSearching] = useState<boolean>(true);
const onFilterChanged = async (filterText: string) => {
return filterText
? (await sitesService.getSiteByNameOrUrl(filterText)).map(s => ({ key: s.url, name: s.title } as ITag))
: [];
};
const onSelectedSiteChanged = (site: ISPSite) => {
setSelectedSite(site);
setIsSearching(false);
props.onSiteSelected((site && site.url) || "");
};
const onSelectedTagChanged = (tag: ITag) => {
onSelectedSiteChanged({ title: tag.name, url: tag.key, id: null });
return tag;
};
// return <div className={styles.SitePicker}>
return <div className={""/* styles.SitePicker */}>
{!isSearching
? <Stack horizontal tokens={{ childrenGap: 5 }}>
<TextField label={props.label} value={selectedSite && selectedSite.url} onChange={(_, v) => onSelectedSiteChanged({ url: v, title: '', id: '' })} />
<IconButton styles={{ root: { position: "relative", top: 30 } }} iconProps={{ iconName: "SearchAndApps" }} onClick={() => setIsSearching(true)} />
</Stack>
: <div>{props.label && <Label>{props.label}</Label>}
<Stack horizontal tokens={{ childrenGap: 5 }}>
<TagPicker
removeButtonAriaLabel="Remove"
onRenderSuggestionsItem={SuggestedSiteItem as any}
onResolveSuggestions={onFilterChanged}
pickerSuggestionsProps={{
suggestionsHeaderText: 'Suggested sites',
noResultsFoundText: 'No sites Found',
}}
resolveDelay={800}
itemLimit={1}
onItemSelected={onSelectedTagChanged}
/>
<IconButton styles={{ root: { position: "relative" } }} iconProps={{ iconName: "Edit" }} onClick={() => setIsSearching(false)} />
</Stack>
</div>}
</div>;
}
Example #6
Source File: filemenu.tsx From SPFx with Mozilla Public License 2.0 | 5 votes |
public render() {
return (
<div>
<IconButton id='ContextualMenuButton1'
text=''
width='30'
split={false}
iconProps={{ iconName: 'MoreVertical' }}
menuIconProps={{ iconName: '' }}
menuProps={{
shouldFocusOnMount: true,
items: [
{
key: 'action1',
name: 'Open in new tab',
onClick: this.handleClick.bind(this, "open", this.props.item)
},
{
key: 'divider_1',
itemType: ContextualMenuItemType.Divider
},
{
key: 'action2',
name: 'Download',
onClick: this.handleClick.bind(this, "download", this.props.item)
},
{
key: 'action3',
name: 'Delete',
onClick: this.handleClick.bind(this, "delete", this.props.item)
},
{
key: 'disabled',
name: 'Disabled action',
disabled: true,
onClick: () => console.error('Disabled action should not be clickable.')
}
]
}} />
</div>
);
}
Example #7
Source File: NetworkViewPCF.tsx From NetworkViewPCF with MIT License | 5 votes |
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 #8
Source File: RecordDetails.tsx From NetworkViewPCF with MIT License | 5 votes |
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 #9
Source File: Progress.tsx From AIPerf with MIT License | 4 votes |
render(): React.ReactNode {
const { bestAccuracy } = this.props;
const { isShowLogDrawer, isCalloutVisible, isShowSucceedInfo, info, typeInfo } = this.state;
const count = TRIALS.countStatus();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const stoppedCount = count.get('USER_CANCELED')! + count.get('SYS_CANCELED')! + count.get('EARLY_STOPPED')!;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const bar2 = count.get('RUNNING')! + count.get('SUCCEEDED')! + count.get('FAILED')! + stoppedCount;
// support type [0, 1], not 98%
const bar2Percent = bar2 / EXPERIMENT.profile.params.maxTrialNum;
const percent = EXPERIMENT.profile.execDuration / EXPERIMENT.profile.params.maxExecDuration;
const remaining = convertTime(EXPERIMENT.profile.params.maxExecDuration - EXPERIMENT.profile.execDuration);
const maxDuration = convertTime(EXPERIMENT.profile.params.maxExecDuration);
const maxTrialNum = EXPERIMENT.profile.params.maxTrialNum;
const execDuration = convertTime(EXPERIMENT.profile.execDuration);
return (
<Stack className="progress" id="barBack">
<Stack className="basic lineBasic">
<p>Status</p>
<Stack horizontal className="status">
<span className={`${EXPERIMENT.status} status-text`}>{EXPERIMENT.status}</span>
{
EXPERIMENT.status === 'ERROR'
?
<div>
<div className={styles.buttonArea} ref={(val): any => this.menuButtonElement = val}>
<IconButton
iconProps={{ iconName: 'info' }}
onClick={isCalloutVisible ? this.onDismiss : this.onShow}
/>
</div>
{isCalloutVisible && (
<Callout
className={styles.callout}
ariaLabelledBy={this.labelId}
ariaDescribedBy={this.descriptionId}
role="alertdialog"
gapSpace={0}
target={this.menuButtonElement}
onDismiss={this.onDismiss}
setInitialFocus={true}
>
<div className={styles.header}>
<p className={styles.title} id={this.labelId}>Error</p>
</div>
<div className={styles.inner}>
<p className={styles.subtext} id={this.descriptionId}>
{EXPERIMENT.error}
</p>
<div className={styles.actions}>
<Link className={styles.link} onClick={this.isShowDrawer}>
Learn about
</Link>
</div>
</div>
</Callout>
)}
</div>
:
null
}
</Stack>
</Stack>
<ProgressBar
who="Duration"
percent={percent}
description={execDuration}
bgclass={EXPERIMENT.status}
maxString={`Max duration: ${maxDuration}`}
/>
<ProgressBar
who="Trial numbers"
percent={bar2Percent}
description={bar2.toString()}
bgclass={EXPERIMENT.status}
maxString={`Max trial number: ${maxTrialNum}`}
/>
<Stack className="basic colorOfbasic mess" horizontal>
<StackItem grow={50}>
<p>Best metric</p>
<div>{isNaN(bestAccuracy) ? 'N/A' : bestAccuracy.toFixed(6)}</div>
</StackItem>
<StackItem>
{isShowSucceedInfo && <MessageInfo className="info" typeInfo={typeInfo} info={info} />}
</StackItem>
</Stack>
<Stack horizontal horizontalAlign="space-between" className="mess">
<span style={itemStyles} className="basic colorOfbasic">
<p>Spent</p>
<div>{execDuration}</div>
</span>
<span style={itemStyles} className="basic colorOfbasic">
<p>Remaining</p>
<div className="time">{remaining}</div>
</span>
<span style={itemStyles}>
{/* modify concurrency */}
<TooltipHost content={CONCURRENCYTOOLTIP}>
<p className="cursor">Concurrency<span className="progress-info">{infoIcon}</span></p>
</TooltipHost>
<ConcurrencyInput value={this.props.concurrency} updateValue={this.editTrialConcurrency} />
</span>
<span style={itemStyles} className="basic colorOfbasic"></span>
</Stack>
<Stack horizontal horizontalAlign="space-between" className="mess">
<div style={itemStyles} className="basic colorOfbasic">
<p>Running</p>
<div>{count.get('RUNNING')}</div>
</div>
<div style={itemStyles} className="basic colorOfbasic">
<p>Succeeded</p>
<div>{count.get('SUCCEEDED')}</div>
</div>
<div style={itemStyles} className="basic">
<p>Stopped</p>
<div>{stoppedCount}</div>
</div>
<div style={itemStyles} className="basic">
<p>Failed</p>
<div>{count.get('FAILED')}</div>
</div>
</Stack>
{/* learn about click -> default active key is dispatcher. */}
{isShowLogDrawer ? (
<LogDrawer
closeDrawer={this.closeDrawer}
activeTab="dispatcher"
/>
) : null}
</Stack>
);
}
Example #10
Source File: TableList.tsx From AIPerf with MIT License | 4 votes |
render(): React.ReactNode {
const { intermediateKey, modalIntermediateWidth, modalIntermediateHeight,
tableColumns, allColumnList, isShowColumn, modalVisible,
selectRows, isShowCompareModal, intermediateOtherKeys,
isShowCustomizedModal, copyTrialId, intermediateOption
} = this.state;
const { columnList } = this.props;
const tableSource: Array<TableRecord> = JSON.parse(JSON.stringify(this.state.tableSourceForSort));
return (
<Stack>
<div id="tableList">
<DetailsList
columns={tableColumns}
items={tableSource}
setKey="set"
compact={true}
onRenderRow={this.onRenderRow}
layoutMode={DetailsListLayoutMode.justified}
selectionMode={SelectionMode.multiple}
selection={this.getSelectedRows}
/>
</div>
{/* Intermediate Result Modal */}
<Modal
isOpen={modalVisible}
onDismiss={this.hideIntermediateModal}
containerClassName={contentStyles.container}
>
<div className={contentStyles.header}>
<span>Intermediate result</span>
<IconButton
styles={iconButtonStyles}
iconProps={{ iconName: 'Cancel' }}
ariaLabel="Close popup modal"
onClick={this.hideIntermediateModal as any}
/>
</div>
{
intermediateOtherKeys.length > 1
?
<Stack horizontalAlign="end" className="selectKeys">
<Dropdown
className="select"
selectedKey={intermediateKey}
options={
intermediateOtherKeys.map((key, item) => {
return {
key: key, text: intermediateOtherKeys[item]
};
})
}
onChange={this.selectOtherKeys}
/>
</Stack>
:
null
}
<div className="intermediate-graph">
<ReactEcharts
option={intermediateOption}
style={{
width: 0.5 * modalIntermediateWidth,
height: 0.7 * modalIntermediateHeight,
padding: 20
}}
theme="my_theme"
/>
<div className="xAxis">#Intermediate result</div>
</div>
</Modal>
{/* Add Column Modal */}
{
isShowColumn &&
<ChangeColumnComponent
hideShowColumnDialog={this.hideShowColumnModal}
isHideDialog={!isShowColumn}
showColumn={allColumnList}
selectedColumn={columnList}
changeColumn={this.props.changeColumn}
/>
}
{/* compare trials based message */}
{isShowCompareModal && <Compare compareStacks={selectRows} cancelFunc={this.hideCompareModal} />}
{/* clone trial parameters and could submit a customized trial */}
<Customize
visible={isShowCustomizedModal}
copyTrialId={copyTrialId}
closeCustomizeModal={this.closeCustomizedTrial}
/>
</Stack>
);
}
Example #11
Source File: header.tsx From msteams-meetings-template with MIT License | 4 votes |
function HeaderComponent(props: Partial<HeaderProps>) {
const onSignOut = props.onSignOut ?? (() => {});
return (
<div className="header">
<div className="headerLogo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2228.833 2073.333">
<path
fill="#5059C9"
d="M1554.637 777.5h575.713c54.391 0 98.483 44.092 98.483 98.483v524.398c0 199.901-162.051 361.952-361.952 361.952h-1.711c-199.901.028-361.975-162-362.004-361.901V828.971c.001-28.427 23.045-51.471 51.471-51.471z"
/>
<circle fill="#5059C9" cx="1943.75" cy="440.583" r="233.25" />
<circle fill="#7B83EB" cx="1218.083" cy="336.917" r="336.917" />
<path
fill="#7B83EB"
d="M1667.323 777.5H717.01c-53.743 1.33-96.257 45.931-95.01 99.676v598.105c-7.505 322.519 247.657 590.16 570.167 598.053 322.51-7.893 577.671-275.534 570.167-598.053V877.176c1.245-53.745-41.268-98.346-95.011-99.676z"
/>
<path
opacity=".1"
d="M1244 777.5v838.145c-.258 38.435-23.549 72.964-59.09 87.598a91.856 91.856 0 01-35.765 7.257H667.613c-6.738-17.105-12.958-34.21-18.142-51.833a631.287 631.287 0 01-27.472-183.49V877.02c-1.246-53.659 41.198-98.19 94.855-99.52H1244z"
/>
<path
opacity=".2"
d="M1192.167 777.5v889.978a91.838 91.838 0 01-7.257 35.765c-14.634 35.541-49.163 58.833-87.598 59.09H691.975c-8.812-17.105-17.105-34.21-24.362-51.833-7.257-17.623-12.958-34.21-18.142-51.833a631.282 631.282 0 01-27.472-183.49V877.02c-1.246-53.659 41.198-98.19 94.855-99.52h475.313z"
/>
<path
opacity=".2"
d="M1192.167 777.5v786.312c-.395 52.223-42.632 94.46-94.855 94.855h-447.84A631.282 631.282 0 01622 1475.177V877.02c-1.246-53.659 41.198-98.19 94.855-99.52h475.312z"
/>
<path
opacity=".2"
d="M1140.333 777.5v786.312c-.395 52.223-42.632 94.46-94.855 94.855H649.472A631.282 631.282 0 01622 1475.177V877.02c-1.246-53.659 41.198-98.19 94.855-99.52h423.478z"
/>
<path
opacity=".1"
d="M1244 509.522v163.275c-8.812.518-17.105 1.037-25.917 1.037-8.812 0-17.105-.518-25.917-1.037a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003a288.02 288.02 0 01-16.587-51.833h258.648c52.305.198 94.657 42.549 94.856 94.854z"
/>
<path
opacity=".2"
d="M1192.167 561.355v111.442a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003h190.228c52.304.198 94.656 42.55 94.855 94.854z"
/>
<path
opacity=".2"
d="M1192.167 561.355v111.442a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003h190.228c52.304.198 94.656 42.55 94.855 94.854z"
/>
<path
opacity=".2"
d="M1140.333 561.355v103.148c-104.963-24.857-191.679-98.469-233.25-198.003h138.395c52.305.199 94.656 42.551 94.855 94.855z"
/>
<linearGradient
id="a"
gradientUnits="userSpaceOnUse"
x1="198.099"
y1="1683.073"
x2="942.234"
y2="394.261"
gradientTransform="matrix(1 0 0 -1 0 2075.333)"
>
<stop offset="0" style={{ stopColor: '#5a62c3' }} />
<stop offset=".5" style={{ stopColor: '#4d55bd' }} />
<stop offset="1" style={{ stopColor: '#3940ab' }} />
</linearGradient>
<path
fill="url(#a)"
d="M95.01 466.5h950.312c52.473 0 95.01 42.538 95.01 95.01v950.312c0 52.473-42.538 95.01-95.01 95.01H95.01c-52.473 0-95.01-42.538-95.01-95.01V561.51c0-52.472 42.538-95.01 95.01-95.01z"
/>
<path
fill="#FFF"
d="M820.211 828.193h-189.97v517.297h-121.03V828.193H320.123V727.844h500.088v100.349z"
/>
</svg>
</div>
<div>
<Text variant="xLarge" styles={boldStyle}>
Microsoft Teams
</Text>
</div>
<div className="headerIcon">
<IconButton
onClick={() => onSignOut()}
iconProps={{ iconName: 'Leave' }}
title={translate('header.signout.title')}
ariaLabel={translate('header.signout.ariaLabel')}
/>
</div>
</div>
);
}
Example #12
Source File: PeopleSearchContainer.tsx From spfx-msgraph-peoplesearch with MIT License | 4 votes |
/**
*
*
* @returns {React.ReactElement<IPeopleSearchContainerProps>}
* @memberof Directory
*/
public render(): React.ReactElement<IPeopleSearchContainerProps> {
const areResultsLoading = this.state.areResultsLoading;
const items = this.state.results[this.state.page - 1];
const hasError = this.state.hasError;
const errorMessage = this.state.errorMessage;
const { semanticColors }: IReadonlyTheme = this.props.themeVariant;
let renderWebPartTitle: JSX.Element = null;
let renderWebPartContent: JSX.Element = null;
let renderOverlay: JSX.Element = null;
let renderShimmerElements: JSX.Element = null;
let renderSearchBox: JSX.Element = null;
let renderPagination: JSX.Element = null;
// Loading behavior
if (areResultsLoading) {
if (!isEmpty(items.value)) {
renderOverlay = <div>
<Overlay isDarkThemed={false} theme={this.props.themeVariant as ITheme} className={styles.overlay}>
<Spinner size={SpinnerSize.medium} />
</Overlay>
</div>;
} else {
let templateContext = {
items: items,
resultCount: this.state.resultCount,
showPagination: this.props.showPagination,
showResultsCount: this.props.showResultsCount,
showBlank: this.props.showBlank && this.props.searchParameterOption !== SearchParameterOption.SearchBox,
showLPC: this.props.showLPC,
themeVariant: this.props.themeVariant,
pageSize: this.props.searchService.pageSize,
serviceScope: this.props.serviceScope
} as ITemplateContext;
templateContext = { ...templateContext, ...this.props.templateParameters };
renderShimmerElements = this.props.templateService.getShimmerTemplateComponent(this.props.selectedLayout, templateContext);
}
}
// WebPart title
renderWebPartTitle = <WebPartTitle displayMode={this.props.displayMode} title={this.props.webPartTitle} updateProperty={(value: string) => this.props.updateWebPartTitle(value)} />;
// WebPart content
if (isEmpty(items.value) && this.props.showBlank && this.props.selectedLayout !== ResultsLayoutOption.Debug && this.props.searchParameterOption !== SearchParameterOption.SearchBox) {
if (this.props.displayMode === DisplayMode.Edit) {
renderWebPartContent = <MessageBar messageBarType={MessageBarType.info}>{strings.ShowBlankEditInfoMessage}</MessageBar>;
}
else {
renderWebPartTitle = null;
}
} else {
let templateContext = {
items: items,
resultCount: this.state.resultCount,
showPagination: this.props.showPagination,
showResultsCount: this.props.showResultsCount,
showBlank: this.props.showBlank && this.props.searchParameterOption !== SearchParameterOption.SearchBox,
showLPC: this.props.showLPC,
themeVariant: this.props.themeVariant,
pageSize: this.props.searchService.pageSize,
serviceScope: this.props.serviceScope
} as ITemplateContext;
templateContext = { ...templateContext, ...this.props.templateParameters };
let renderSearchResultTemplate = this.props.templateService.getTemplateComponent(this.props.selectedLayout, templateContext);
if (this.props.searchParameterOption === SearchParameterOption.SearchBox) {
renderSearchBox = <PeopleSearchBox themeVariant={this.props.themeVariant} onSearch={(searchQuery) => { this.props.updateSearchParameter(searchQuery); }} searchInputValue={this.props.searchService.searchParameter} />;
}
if (this.props.showPagination) {
let prevPageEl: JSX.Element = null;
let nextPageEl: JSX.Element = null;
if (this.hasPreviousPage()) {
prevPageEl = <IconButton onClick={async () => await this._fetchPeopleSearchResults(this.state.page - 1)} iconProps={{ iconName: 'DoubleChevronLeft8' }} />;
}
if (this.hasNextPage()) {
nextPageEl = <IconButton onClick={async () => await this._fetchPeopleSearchResults(this.state.page + 1)} iconProps={{ iconName: 'DoubleChevronRight8' }} />;
}
renderPagination =
<div className={styles.searchPagination}>
{prevPageEl}
{nextPageEl}
</div>;
}
renderWebPartContent =
<React.Fragment>
{renderOverlay}
{renderSearchBox}
{renderSearchResultTemplate}
{renderPagination}
</React.Fragment>;
}
// Error Message
if (hasError) {
renderWebPartContent = <MessageBar messageBarType={MessageBarType.error}>{errorMessage}</MessageBar>;
}
return (
<div style={{backgroundColor: semanticColors.bodyBackground}}>
<div className={styles.peopleSearchWebPart}>
{renderWebPartTitle}
{renderShimmerElements ? renderShimmerElements : renderWebPartContent}
</div>
</div>
);
}
Example #13
Source File: SiteScriptDesigner.tsx From sp-site-designs-studio with MIT License | 4 votes |
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 #14
Source File: SiteScriptDesigner.tsx From sp-site-designs-studio with MIT License | 4 votes |
SiteScriptDesigner = (props: ISiteScriptDesignerProps) => {
const [appContext] = useAppContext<IApplicationState, ActionType>();
// Get service references
const siteScriptSchemaService = appContext.serviceScope.consume(SiteScriptSchemaServiceKey);
const [isSorting, setIsSorting] = useState<boolean>(false);
const [contentUI, setContentUI] = useState<ISiteScriptContentUIWrapper>(new SiteScriptContentUIWrapper(props.siteScriptContent));
const previousContentUI = usePrevious<ISiteScriptContentUIWrapper>(contentUI);
const updateUITimeoutRef = React.useRef<any>(null);
useEffect(() => {
const newContentUI = new SiteScriptContentUIWrapper(props.siteScriptContent);
if (previousContentUI) {
newContentUI.editingActionKeys = previousContentUI.editingActionKeys;
}
setContentUI(newContentUI);
}, [props.siteScriptContent]);
const onUIUpdated = (uiWrapper: ISiteScriptContentUIWrapper) => {
setContentUI(uiWrapper);
if (updateUITimeoutRef.current) {
clearTimeout(updateUITimeoutRef.current);
}
updateUITimeoutRef.current = setTimeout(() => {
props.onSiteScriptContentUpdated(uiWrapper.toSiteScriptContent());
clearTimeout(updateUITimeoutRef.current);
updateUITimeoutRef.current = null;
}, 0);
};
const onActionAdded = (verb: string) => {
const newAction = siteScriptSchemaService.getNewActionFromVerb(verb);
const updatedContentUI = contentUI.addAction(newAction);
setContentUI(updatedContentUI);
if (updateUITimeoutRef.current) {
clearTimeout(updateUITimeoutRef.current);
}
updateUITimeoutRef.current = setTimeout(() => {
props.onSiteScriptContentUpdated(updatedContentUI.toSiteScriptContent());
clearTimeout(updateUITimeoutRef.current);
updateUITimeoutRef.current = null;
}, 0);
};
const getAddableActions = useConstCallback(() => {
return {
"Actions": siteScriptSchemaService.getAvailableActions().map(a => ({
group: "Actions",
iconName: "SetAction",
key: a.verb,
text: a.label,
item: a
} as IAddableItem))
};
});
const onSortChanged = (args: ISortEndEventArgs) => {
props.onSiteScriptContentUpdated(contentUI.reorderActions(args.newIndex, args.oldIndex).toSiteScriptContent());
};
const toggleSorting = () => {
if (!isSorting) {
setTimeout(() => {
setContentUI(contentUI.clearEditing());
}, 0);
}
setIsSorting(!isSorting);
};
const renderScriptAction = (scriptActionUI: ISiteScriptActionUIWrapper, index: number) => {
const scriptActionBlock = <SiteScriptActionDesignerBlock key={scriptActionUI.$uiKey}
siteScriptAction={scriptActionUI}
siteScriptContentUI={contentUI}
onSiteScriptContentUIChanged={onUIUpdated}
isSorting={isSorting}
index={index}
actionsCount={(contentUI.actions || 0) && contentUI.actions.length}
/>;
if (isSorting) {
const SortableItem = SortableElement(() => scriptActionBlock);
return <SortableItem key={scriptActionUI.$uiKey} index={index} />;
} else {
return scriptActionBlock;
}
};
const renderScriptActionsList = () => {
if (!contentUI.actions) {
return null;
}
if (isSorting) {
const SortableListContainer = SortableContainer(({ items }) => {
return <div>{items.map(renderScriptAction)}</div>;
});
return <SortableListContainer
items={contentUI.actions}
// onSortStart={(args) => this._onSortStart(args)}
onSortEnd={(args: any) => onSortChanged(args)}
lockToContainerEdges={true}
useDragHandle={false}
/>;
} else {
return <div>{contentUI.actions.map(renderScriptAction)}</div>;
}
};
return <div className={styles.SiteScriptDesigner}>
{contentUI.actions && contentUI.actions.length > 1 && <IconButton iconProps={{ iconName: "Sort" }}
styles={{ root: { position: "absolute", top: -32, right: 9 } }}
checked={isSorting}
onClick={toggleSorting} />}
{renderScriptActionsList()}
{!isSorting && <Adder items={getAddableActions()}
searchBoxPlaceholderText="Search an action..."
onSelectedItem={(item) => onActionAdded(item.key)} />}
</div>;
}