Skip to content

Commit

Permalink
Enhance UI, use date picker
Browse files Browse the repository at this point in the history
  • Loading branch information
mehmetseckin committed Feb 21, 2020
1 parent db2631f commit ac3fb93
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 33 deletions.
105 changes: 73 additions & 32 deletions TimeZoneDisplay/components/Display/Display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@ import * as React from "react";
import { useState } from "react";
import { TimeZoneConverter } from "../../utils/TimeZoneConverter";
import { Card, ICardSectionStyles, ICardTokens, ICardSectionTokens } from "@uifabric/react-cards";
import { Icon, Text, ITextStyles, FontWeights, IIconStyles, Dropdown, IDropdownProps, IDropdownOption } from "office-ui-fabric-react";
import { Icon, Text, ITextStyles, FontWeights, IIconStyles, TagPicker, ITag, ISuggestionItemProps } from "office-ui-fabric-react";

interface IDisplayProps {
date: Date | null;
timeZone: string | null;
format: string;
options: IDotNetFormatOptions;
timeZonePickerIconTitle: string;
timeZonePickerPlaceholder: string;
timeZonePickerSuggestionsHeaderText: string;
timeZonePickerNoSuggestionsFoundText: string;
}

const textStyles: ITextStyles = {
root: {
color: '#333333',
fontWeight: FontWeights.regular
}
};
const iconStyles: IIconStyles = {
root: {
color: '#0078D4',
Expand All @@ -26,60 +24,103 @@ const iconStyles: IIconStyles = {
float: 'left'
}
};
const noneSelectedIconStyles: IIconStyles = {
root: {
color: '#c3c3c3',
fontSize: 72,
fontWeight: FontWeights.regular,
padding: 12,
}
};
const noneSelectedTextStyles: IIconStyles = {
root: {
color: '#303030',
fontWeight: FontWeights.regular,
padding: 12,
}
};
const dropdownCardSectionStyles: ICardSectionStyles = {
root: {
alignSelf: 'stretch',
borderBottom: '1px solid #F3F2F1'
}
};

const timeZoneTags: ITag[] = TimeZoneConverter.availableTimeZones.map(tz => { return { key: tz, name: tz } });

const cardTokens: ICardTokens = { childrenMargin: 12 };
const dropdownCardSectionTokens: ICardSectionTokens = { padding: '0px 0px 12px 0px' };

export const Display = (props: IDisplayProps) => {
let { date, timeZone, format, options } = props;
let { date, timeZone, format, options,
timeZonePickerIconTitle, timeZonePickerPlaceholder,
timeZonePickerSuggestionsHeaderText, timeZonePickerNoSuggestionsFoundText
} = props;

let [selectedTimeZone, setSelectedTimeZone] = useState(timeZone);
let initialState: ITag[] = timeZone ? [{ key: timeZone, name: timeZone }] : [];
let [selectedTimeZones, setSelectedTimeZones] = useState(initialState);

let result = (date !== null && selectedTimeZone !== null && TimeZoneConverter.isValidTimeZone(selectedTimeZone))
? TimeZoneConverter.convert(date, selectedTimeZone).toDotNetFormat(format, options)
: "N/A";
let results = (date !== null && selectedTimeZones.length)
? selectedTimeZones.map(tz => ({
key: tz.key,
timeZone: tz.key,
formattedDate: TimeZoneConverter.convert(date as any, tz.key).toDotNetFormat(format, options)
}))
: [];

return <Card tokens={cardTokens}>
<Card.Section styles={dropdownCardSectionStyles} tokens={dropdownCardSectionTokens}>
<Card.Item>
<Dropdown
onRenderPlaceHolder={_onRenderPlaceHolder}
onRenderTitle={_onRenderTitle}
selectedKey={selectedTimeZone}
options={TimeZoneConverter.availableTimeZones.map(tz => { return { key: tz, text: tz } })}
onChange={(e, option) => {
if (option !== null && option !== undefined) {
setSelectedTimeZone(option.key.toString())
}
<Icon iconName="WorldClock" styles={iconStyles} title={timeZonePickerIconTitle} />
<TagPicker
selectedItems={selectedTimeZones}
inputProps={{
placeholder: timeZonePickerPlaceholder
}}
onResolveSuggestions={_onFilterChanged}
pickerSuggestionsProps={{
suggestionsHeaderText: timeZonePickerSuggestionsHeaderText,
noResultsFoundText: timeZonePickerNoSuggestionsFoundText
}}
itemLimit={1}
getTextFromItem={item => item.name}
onChange={items => { setSelectedTimeZones(items || []) }}
onRenderSuggestionsItem={_onRenderSuggestionsItem}
/>
</Card.Item>
</Card.Section>
<Card.Section>
<Card.Item>
<Text styles={textStyles}>{result}</Text>
{results.length ? (
<div>
<Icon iconName="Clock" styles={iconStyles} />
<Text>{results[0].formattedDate}</Text>
</div>
) : (
<div>
<Icon iconName="Balloons" styles={noneSelectedIconStyles} />
<br />
<Text styles={noneSelectedTextStyles}>No time zone selected. Select a time zone to see the date here.</Text>
</div>
)}
</Card.Item>
</Card.Section>
</Card>;
}

const _onRenderPlaceHolder = (props?: IDropdownProps): JSX.Element => {
return <div>
/* <Icon iconName="WorldClock" styles={iconStyles} /> */

const _onRenderSuggestionsItem = (props: ITag, item: ISuggestionItemProps<ITag>) => {
return <div style={{padding: 12}}>
<Icon iconName="WorldClock" styles={iconStyles} />
<span>{props?.placeHolder}</span>
<span>{props.name}</span>
</div>
}

const _onRenderTitle = (options?: IDropdownOption[]): JSX.Element => {
const option = options && options[0];
return <div>
<Icon iconName="WorldClock" styles={iconStyles} />
<span>{option?.text}</span>
</div>
}
const _onFilterChanged = (filterText: string, tagList?: ITag[]): ITag[] => {
return filterText
? timeZoneTags
.filter(tag => tag.name.toLowerCase().indexOf(filterText.toLowerCase()) !== -1)
.filter(tag => tagList?.filter(existingTag => existingTag === tag).length === 0)
: [];
};
6 changes: 5 additions & 1 deletion TimeZoneDisplay/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export class TimeZoneDisplay implements ComponentFramework.StandardControl<IInpu
date: this.getDateInput(context),
timeZone: this.getdefaultTimeZoneInput(context),
format: this.getDotNetFormatString(context),
options: this.getDotNetFormatOptions(context)
options: this.getDotNetFormatOptions(context),
timeZonePickerIconTitle: context.resources.getString("TimeZonePickerIconTitle"),
timeZonePickerPlaceholder: context.resources.getString("TimeZonePickerPlaceholder"),
timeZonePickerSuggestionsHeaderText: context.resources.getString("TimeZonePickerSuggestionsHeaderText"),
timeZonePickerNoSuggestionsFoundText: context.resources.getString("TimeZonePickerNoSuggestionsFoundText")
}),
this.container
);
Expand Down
12 changes: 12 additions & 0 deletions TimeZoneDisplay/strings/TimeZoneDisplay.1033.resx
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,16 @@
<data name="ControlDisplayName" xml:space="preserve">
<value>Time Zone Display</value>
</data>
<data name="TimeZonePickerIconTitle" xml:space="preserve">
<value>Time Zone</value>
</data>
<data name="TimeZonePickerPlaceholder" xml:space="preserve">
<value>Start typing a time zone name...</value>
</data>
<data name="TimeZonePickerSuggestionsHeaderText" xml:space="preserve">
<value>Suggested Time Zones</value>
</data>
<data name="TimeZonePickerNoSuggestionsFoundText" xml:space="preserve">
<value>No time zones found.</value>
</data>
</root>

0 comments on commit ac3fb93

Please sign in to comment.