office-ui-fabric-react#Icon TypeScript Examples
The following examples show how to use
office-ui-fabric-react#Icon.
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: UniversityView.tsx From website with MIT License | 6 votes |
onRenderTitle = (options?: IDropdownOption[]): JSX.Element => {
const option = options![0];
return (
<div>
{option.data && option.data.icon && (
<Icon style={iconStyles} iconName={option.data.icon} aria-hidden="true" title={option.data.icon} />
)}
<span>{option.text}</span>
</div>
);
}
Example #2
Source File: UniversityView.tsx From website with MIT License | 6 votes |
onRenderOption = (option?: IDropdownOption): JSX.Element => {
return (
<div>
{option?.data && option?.data.icon && (
<Icon style={iconStyles} iconName={option.data.icon} aria-hidden="true" title={option.data.icon} />
)}
<span>{option?.text}</span>
</div>
);
}
Example #3
Source File: RepresentativesList.tsx From website with MIT License | 6 votes |
RapresentativesList = (props: Props) => {
var theme = useTheme();
const locale = LocalizationService.strings();
return (
<div className="representatives pb-4 pt-2">
{
props.loadingRepresentatives || props.errorLoadingRepresentatives ? <LoadingSpinner loading={props.loadingRepresentatives} error={props.errorLoadingRepresentatives} />
: props.data.length === 0 ?
<div className="justify-content-center">
<Message text={locale?.university.representativesNotAvailable!} />
</div> : <></>
}
<Row className="people-list text-center">
{props.data.length !== 0 && !props.errorLoadingRepresentatives && !props.loadingRepresentatives ? props.data.map((x,i) =>
<Col key={i} xl={3} lg={3} md={4} sm={6} xs={12} className="mb-3 col-persona">
{
( () => {
var primaryText : any;
var imageUrl = `https://studentiunimi-groups-propics.marcoaceti.workers.dev/${x.tguser?.id}.png`;
if (x.tguser?.username !== "") primaryText = (<><Icon iconName="Send" style={{ color: theme.palette.themePrimary }} /> <Link href={`https://t.me/${x.tguser?.username}`}>{`${x.tguser?.first_name ?? ""} ${x.tguser?.last_name ?? ""}`}</Link></>);
else { primaryText = `${x.tguser?.first_name ?? ""} ${x.tguser?.last_name ?? ""}`};
return <Persona imageUrl={imageUrl} onRenderPrimaryText={() => primaryText} text={`${x.tguser?.first_name ?? ""} ${x.tguser?.last_name ?? ""}`} secondaryText={x.degree_name} size={PersonaSize.size40} />
})()
}
</Col>
) : <></> }
</Row>
</div>
)
}
Example #4
Source File: AdditionalGroup.tsx From website with MIT License | 5 votes |
AdditionalGroup = (props: Props) => {
const theme = useTheme();
const locale = LocalizationService.strings();
var language: string | undefined = LocalizationService.getLanguage();
const data = props.data;
const helpfulTextStyles: ITextStyles = { root: { fontWeight: FontWeights.regular, } };
const descriptionTextStyles: ITextStyles = { root: { fontWeight: FontWeights.semibold } };
const cardTokens: ICardTokens = { childrenMargin: 12 };
const telegramGroupIcon: IIconProps = { iconName: 'Send' };
let desc = data.description![language!];
let name = data.name![language!];
// PrimaryText inizialization
var primaryText : any;
primaryText = <div style={{ wordWrap: 'break-word', whiteSpace: 'normal', marginTop: '2px' }}><Text styles={semibold}>{name}</Text></div>;
// Group image initialization
var imageUrl: string;
imageUrl = process.env.PUBLIC_URL + '/extra_groups_images/' + data.image;
return (
<Card tokens={cardTokens}>
<Card.Item>
<Persona imageUrl={imageUrl} onRenderPrimaryText={() => primaryText} text={name} />
</Card.Item>
<Card.Section>
<Text styles={descriptionTextStyles}>
<Chip label={name === 'MUG - Milan University Gamers' ? locale?.studentsAssociation : locale?.extraGroups.extraGroup} size="small" style={{ color: theme.palette.white, backgroundColor: name === 'MUG - Milan University Gamers' ? theme.palette.themeTertiary : theme.palette.themeSecondary }} className="m-1" />
</Text>
<Text variant="small" styles={helpfulTextStyles} className="mb-2">
<JsxParser bindings={{ theme: theme, semibold: semibold }} components={{ Text, Link, Icon }} jsx={"<Icon iconName='Info' /> " + desc} />
</Text>
{
(() => {
if (data.gruppo !== "" && data.gruppo !== null) {
return (
<ActionButton
href={data.gruppo as any}
className="text-decoration-none"
iconProps={telegramGroupIcon}
style={{ justifyContent: 'center', marginLeft: 'auto', marginRight: 'auto', marginTop: '3px' }}
disabled={data.gruppo === "" || data.gruppo === null}
allowDisabledFocus>
{name === 'MUG - Milan University Gamers' ? locale?.homepage.section3.part3.title : locale?.telegramGroup}
</ActionButton>
);
}
})()
}
</Card.Section>
</Card>
);
}
Example #5
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 #6
Source File: ExportPackageViewer.tsx From sp-site-designs-studio with MIT License | 5 votes |
ExportPackageViewer = (props: IExportPackageViewerProps) => {
const [currentFile, setCurrentFile] = useState(props.exportPackage.allFiles && props.exportPackage.allFiles.length && props.exportPackage.allFiles[0]);
useEffect(() => {
const allFiles = props.exportPackage.allFiles;
if (allFiles && allFiles.length > 0) {
setCurrentFile(allFiles[0]);
}
}, [props.exportPackage]);
const viewFileContent = (file: string) => {
setCurrentFile(file);
};
const getContentLanguage = (fileName: string) => {
if (!fileName) {
return null;
}
const fileNameParts = fileName.split(".");
const extension = fileNameParts.length > 1 ? fileNameParts[fileNameParts.length - 1].toLowerCase() : null;
switch (extension) {
case "json":
return "json";
case "ps1":
return "powershell";
default:
return "";
}
};
const currentContent = props.exportPackage.hasContent(currentFile)
? props.exportPackage.getFileContent(currentFile)
: "";
return <div className={styles.ExportPackageViewer}>
<div className={styles.row}>
<div className={styles.column}>
<h3><Icon styles={{
root: {
fontSize: 24,
verticalAlign: "text-bottom",
marginRight: 10
}
}} iconName="Package" />{(props.exportPackage.packageName) || ""}</h3>
</div></div>
<div className={styles.row}>
<div className={styles.column2}>
<ul className={styles.filesList}>
{props.exportPackage.allFiles.map(f => <li>
<ActionButton iconProps={{ iconName: "TextDocument" }}
styles={{
root: { fontWeight: currentFile == f ? "bold" : "normal" }
}}
checked={currentFile == f} text={f} onClick={() => viewFileContent(f)} />
</li>)}
</ul>
</div>
<div className={styles.column10}>
<CodeEditor
height="65vh"
language={getContentLanguage(currentFile)}
options={{
readOnly: true,
folding: true,
renderIndentGuides: true,
minimap: {
enabled: false
}
}}
value={currentContent}
/>
</div>
</div>
</div>;
}
Example #7
Source File: AdminsList.tsx From website with MIT License | 5 votes |
AdminsList = (props: Props) => {
var theme = useTheme();
const locale = LocalizationService.strings();
let [admins, setAdmins] = React.useState<Admin[]>([]); // Amministratori
const [loadingAdmins, setLoadingAdmins] = React.useState<boolean>(false);
const [errorLoadingAdmins, setErrorLoadingAdmins] = React.useState<boolean>(false);
/* Admins callBack */
const updateAdmins = React.useCallback(async () => {
if (props.degree?.slug === '' || props.degree?.slug === undefined) return;
setErrorLoadingAdmins(false);
setLoadingAdmins(true);
let adminsResult = await getDegreeAdmins(props.degree?.slug);
if (adminsResult.status !== 200) {
setLoadingAdmins(false);
setErrorLoadingAdmins(true);
return;
}
setLoadingAdmins(false);
setAdmins(adminsResult.value ?? []);
}, [props.degree?.slug]);
React.useEffect(() => {
updateAdmins();
}, [props.degree, updateAdmins]);
return (
<div className="mb-2">
<div className="pb-2 pt-2 mb-4" style={{ backgroundColor: theme.palette.neutralLight }}>
<Container>
<div><Text variant="medium" styles={semibold}><Icon iconName="WorkforceManagement" /> {locale?.groups.availableAdmins}</Text></div>
</Container>
</div>
{
loadingAdmins || errorLoadingAdmins ? <LoadingSpinner loading={loadingAdmins} error={errorLoadingAdmins} />
: admins.length === 0 ?
<div className="justify-content-center">
<Message text={locale?.groups.adminsNotFound!} />
</div> : <></>
}
{admins.length !== 0 && !errorLoadingAdmins && !loadingAdmins ?
<Container>
<Row className="admin-list" style={{ justifyContent: admins?.length === 0 ? 'center' : ""}}>
{admins?.length !== 0 ? admins?.map((x,i) =>
<Col key={i} xl={3} lg={3} md={4} sm={6} xs={12} className="mb-3 col-persona">
{(() => {
var imageUrl = `https://studentiunimi-groups-propics.marcoaceti.workers.dev/${x.id}.png`;
return <Persona imageUrl={imageUrl} onRenderPrimaryText={() => (<><Icon iconName="Send" style={{ color: theme.palette.themePrimary }}/> <Link href={`https://t.me/${x.username}`}>{`${x.first_name ?? ""} ${x.last_name ?? ""}`}</Link></>)} text={`@${x.first_name ?? ""} ${x.last_name ?? ""}`} secondaryText={`@${x.username}`} size={PersonaSize.size40} />
})()}
</Col>
) : <Message text={locale?.groups.adminsNotFound!} />
}
</Row>
</Container> : <></>
}
</div>
)
}
Example #8
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
infoIcon = <Icon iconName='info' />
Example #9
Source File: Mantainers.tsx From website with MIT License | 5 votes |
Mantainers = () => {
var theme = useTheme();
const locale = LocalizationService.strings();
var language: string | undefined = LocalizationService.getLanguage();
const profileIconStyle = { color: theme.palette.themePrimary, fontSize: FontSizes.size24 };
const sectionCard = {
minHeight: '120px',
height: '100%',
width: '100%',
maxWidth: 'none',
marginLeft: 'auto',
marginRight: 'auto',
maxHeight: 'none',
backgroundColor: theme.palette.white
};
return (
<div className="pb-4 pt-4" style={{ backgroundColor: theme.palette.neutralLighter }}>
<Container className="contributors text-center">
<div className="mb-4"><Text variant="xLarge">{locale?.contributors.header1}</Text></div>
<Row className="justify-content-center">
{
developers.map((x: any, i: any) => {
return (
<Col className="mb-3" xl={4} lg={4} md={4} sm={6} xs={12} key={i}>
<Card tokens={cardTokens} style={sectionCard} className="justify-content-center text-center">
<Card.Section>
<div className="justify-content-center">
<Image id="logo"
src={process.env.PUBLIC_URL + "/contributors/" + x.pic}
alt={x.name}
style={developerPic}
/>
</div>
<div className="mb-0"><Text variant="medium" styles={semibold}>{x.name}</Text></div>
<Text variant="medium" className="mt-2">
{x.description[language!]}
</Text>
<div>
<TooltipHost
content={locale?.contributors.githubProfile}
calloutProps={calloutProps}
styles={hostStyles}
delay={TooltipDelay.zero}
>
<Link onClick={() => redirectToLink(x.github)}><Icon iconName="ProfileSearch" style={profileIconStyle} /></Link>
</TooltipHost>
<TooltipHost
content={locale?.contributors.websiteProfile}
calloutProps={calloutProps}
styles={hostStyles}
delay={TooltipDelay.zero}
>
<Link onClick={() => redirectToLink(x.website)}><Icon iconName="Website" style={profileIconStyle} /></Link>
</TooltipHost>
</div>
</Card.Section>
</Card>
</Col>
)
})
}
</Row>
</Container>
</div>
)
}
Example #10
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
LineChart = <Icon iconName='LineChart' />
Example #11
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
tableListIcon = <Icon iconName='BulletedList' />
Example #12
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
copy = <Icon iconName='Copy' />
Example #13
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
blocked = <Icon iconName='StatusCircleBlock' />
Example #14
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
completed = <Icon iconName='Completed' />
Example #15
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
errorBadge = <Icon iconName='ErrorBadge' />
Example #16
Source File: Icon.tsx From AIPerf with MIT License | 5 votes |
warining = <Icon iconName='Warning' />
Example #17
Source File: UniversityView.tsx From website with MIT License | 4 votes |
UniversityView = () => {
var theme = useTheme();
let didMount = React.useRef(false);
const locale = LocalizationService.strings();
var language: string | undefined = LocalizationService.getLanguage();
const history = useHistory();
//const whiteText = '#faf9f8';
const imageProperties = { display: 'inline-block', width: '80%' };
const universityLinks: any[] = getUniversityLinks();
/* ChoiceGroup for university links */
const iconProps: any = { fontSize: '24px' };
const options: IChoiceGroupOption[] = [];
const itemSize = 100;
const choiceGroupOptionsStyle: IChoiceGroupOptionStyles = {
choiceFieldWrapper: {
width: itemSize + "px",
height: itemSize + "px"
},
labelWrapper: {
maxWidth: itemSize / (3 / 4) + "px",
height: "auto",
},
field: {
height: "100%",
padding: "0px"
}
};
/* Workaround to not show selected choicegroup */
const [selectedChoiceGroup, setSelectedChoiceGroup] = React.useState<string>("");
const selectionChanged = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption): void => { setSelectedChoiceGroup(""); }
universityLinks.map((x) => {
if (x.icon !== "" && x.link !== "") options.push({
key: x.name![language!],
text: x.name![language!],
styles: choiceGroupOptionsStyle,
iconProps: { iconName: x.icon!, className: iconProps, color: theme.palette.themePrimary },
onClick: () => {redirectToLink(x.link!)}
});
return options;
});
/* Remove title properties from documentCardTitles */
React.useEffect(() => {
const divList = document.getElementsByClassName("ms-DocumentCardTitle");
for (let i: number = 0; i < divList.length; i++) {
divList[i].removeAttribute('title');
}
});
const [departments, setDepartments] = React.useState<Department[]>([]);
const [representatives, setRepresentatives] = React.useState<Representative[]>([]);
const [selectedDepartment, setSelectedDepartment] = React.useState<string>('');
const [loadingRepresentatives, setLoadingRepresentatives] = React.useState<boolean>(false);
const [errorLoadingRepresentatives, setErrorLoadingRepresentatives] = React.useState<boolean>(false);
const [errorLoadingDepartments, setErrorLoadingDepartments] = React.useState<boolean>(false);
const departmentSelectionChanged = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IDropdownOption): void => {
setSelectedDepartment(option?.key as string ?? '');
history.push(`/representatives/${option?.data.slug as string}`);
};
/* Departments callBack */
const updateDepartments = React.useCallback(async () => {
setErrorLoadingDepartments(false);
let departmentsResult = await getDepartments();
if (departmentsResult.status !== 200) {
setErrorLoadingDepartments(true);
return;
}
//console.log("Departments result: ", departmentsResult.value ?? []);
setDepartments(departmentsResult.value ?? []);
}, []);
/* Representatives callBack */
const updateRepresentatives = React.useCallback(async () => {
if (selectedDepartment === '' || selectedDepartment === undefined) return;
setLoadingRepresentatives(true);
setErrorLoadingRepresentatives(false);
let representativesResult = await getRepresentatives(selectedDepartment);
if (representativesResult.status !== 200) {
setLoadingRepresentatives(false);
setErrorLoadingRepresentatives(true);
}
//console.log("Representatives result: ", representativesResult.value ?? []);
setLoadingRepresentatives(false);
setRepresentatives(representativesResult.value ?? []);
}, [setRepresentatives, selectedDepartment]);
/* This function initializes representatives based on url parameters */
const initializeRepresentativesViaUrl = React.useCallback(() => {
if (!didMount.current && departments.length !== 0) {
didMount.current = true
var states = history.location.pathname.substring(1).split('/').filter(x => x !== '');
var departmentSlug = states.length >= 2 ? states[1] : '';
//console.log("Department slug: ", departmentSlug)
setSelectedDepartment(departments.filter(x => x.slug === departmentSlug)[0]?.pk as unknown as string);
}
}, [departments, history.location.pathname]);
React.useEffect(() => {
if (!didMount.current) {
updateDepartments();
}
}, [updateDepartments]);
React.useEffect(() => {
updateRepresentatives();
}, [selectedDepartment, updateRepresentatives]);
React.useEffect(() => {
if (!didMount.current) initializeRepresentativesViaUrl();
}, [initializeRepresentativesViaUrl, departments]);
let departmentOptions: IDropdownOption[] = [];
departments.forEach(x => {
if (x.representative_count !== 0) departmentOptions.push({ key: x.pk, text: x.name ?? "", data: { icon: x.icon, slug: x.slug }, disabled: x.representative_count === 0 });
});
return (
<div className="university">
<div className="pt-5 pb-5 mb-4" style={{ backgroundColor: theme.palette.themeDark }}>
<Container>
<Row>
<Col xl={9} lg={8} className="mb-3 mb-lg-0">
<div className="mb-2">
<Text variant="xLargePlus" style={{ color: theme.palette.white }}>{locale?.university.header.text1}</Text>
</div>
<div className="mb-3">
<Text variant="large" style={{ color: theme.palette.white }}>{locale?.university.header.text2}</Text>
</div>
</Col>
<Col xl={3} lg={4} className="text-center">
<div style={{ marginLeft: 'auto', marginRight: 'auto', maxWidth: 500 }}>
<Image id="logo" className="mb-2" src={process.env.PUBLIC_URL + '/images/university.png'} style={{ display: 'inline-block', width: '80%' }} />
</div>
</Col>
</Row>
</Container>
</div>
<div>
<Container>
<div className="mb-3 text-center">
<Text variant="xLarge"><Icon iconName="NewsSearch" /> {locale?.university.news.title}</Text>
</div>
<div className="mb-3">
<Slider />
</div>
</Container>
</div>
<div className="pt-5 pb-5" style={{ backgroundColor: theme.palette.themeTertiary }}>
<Container>
<Row>
<Col lg={4} className="text-center">
<div style={{ marginLeft: 'auto', marginRight: 'auto', maxWidth: 300 }}>
<Image id="logo" className="mb-2" src={process.env.PUBLIC_URL + '/images/university_links.png'} style={imageProperties} />
</div>
</Col>
<Col lg={8} className="mb-2">
<div className="mb-2">
<Text variant="xLargePlus" style={{color: theme.palette.white}}>{locale?.university.linksAndRedirects.text1}</Text>
</div>
<div className="mb-3">
<Text variant="large" style={{ color: theme.palette.white }}>{locale?.university.linksAndRedirects.text2}</Text>
</div>
<div className="text-center justify-content-center university-links" style={{ marginLeft: 'auto', marginRight: 'auto' }}>
<ChoiceGroup options={options} onChange={selectionChanged} selectedKey={selectedChoiceGroup} />
</div>
</Col>
</Row>
</Container>
</div>
<div className="pt-5 pb-5 mb-4" style={{ backgroundColor: theme.palette.themeDarkAlt }}>
<Container>
<Row>
<Col>
<div className="mb-2">
<div className="mb-2">
<Text variant="xLarge" style={{ color: theme.palette.white }}>
{locale?.university.text1}
</Text>
</div>
<div className="mb-2">
<Text variant="large" style={{ color: theme.palette.white }}>
{locale?.university.text2}
</Text>
</div>
<div className="mb-2 text-center" style={{ maxWidth: '400px', marginRight: 'auto'}}>
<Dropdown
placeholder={locale?.university.departmentSelect}
label={locale?.university.departmentSelect}
onRenderLabel={() => <Text style={{ color: theme.palette.white }} styles={semibold}>{locale?.university.departmentSelect}</Text>}
options={departmentOptions}
onChange={departmentSelectionChanged}
selectedKey={selectedDepartment}
onRenderTitle={onRenderTitle}
onRenderOption={onRenderOption}
errorMessage={errorLoadingDepartments ? locale?.errorLoadingDepartments : undefined}
disabled={errorLoadingDepartments || departments.length === 0}
/>
</div>
</div>
</Col>
<Col lg={3} className="text-center">
<div style={{ marginLeft: 'auto', marginRight: 'auto', maxWidth: 300 }}>
<Image id="logo" className="mb-2" src={process.env.PUBLIC_URL + '/images/representatives.png'} style={{ display: 'inline-block', width: '100%' }} />
</div>
</Col>
</Row>
</Container>
</div>
<div style={{ display: selectedDepartment !== '' && selectedDepartment !== undefined ? 'block' : 'none' }}>
<Container>
<RepresentativesList data={representatives} loadingRepresentatives={loadingRepresentatives} errorLoadingRepresentatives={errorLoadingRepresentatives} />
</Container>
</div>
</div>
)
}
Example #18
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 #19
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>;
}