Support for localization

This commit is contained in:
Nanddeep Nachan 2020-07-10 14:19:07 +00:00
parent daa67c1fa7
commit 7727eafd28
13 changed files with 849 additions and 307 deletions

View File

@ -63,7 +63,9 @@ The sample also provisions sample data to the "Timeline" list, which can be used
### NPM Packages Used ### NPM Packages Used
Below NPM package is used to develop this sample. Below NPM package is used to develop this sample.
1. @pnp/sp (https://www.npmjs.com/package/@pnp/sp) 1. @pnp/sp (https://www.npmjs.com/package/@pnp/sp)
2. @pnp/spfx-controls-react (https://pnp.github.io/sp-dev-fx-controls-react/)
3. @pnp/spfx-property-controls (https://pnp.github.io/sp-dev-fx-property-controls/)
## Used SharePoint Framework Version ## Used SharePoint Framework Version
@ -121,3 +123,5 @@ This sample web part displays list of events in chronological order with data st
[figure5]: ./assets/layout-horizontal.png [figure5]: ./assets/layout-horizontal.png
[figure6]: ./assets/list-schema.png [figure6]: ./assets/list-schema.png
[figure7]: ./assets/list-sample-data.png [figure7]: ./assets/list-sample-data.png
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-timeline" />

View File

@ -13,6 +13,8 @@
}, },
"externals": {}, "externals": {},
"localizedResources": { "localizedResources": {
"TimelineWebPartStrings": "lib/webparts/timeline/loc/{locale}.js" "TimelineWebPartStrings": "lib/webparts/timeline/loc/{locale}.js",
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js",
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,8 @@
"@microsoft/sp-property-pane": "1.10.0", "@microsoft/sp-property-pane": "1.10.0",
"@microsoft/sp-webpart-base": "1.10.0", "@microsoft/sp-webpart-base": "1.10.0",
"@pnp/sp": "^2.0.6", "@pnp/sp": "^2.0.6",
"@pnp/spfx-controls-react": "1.19.0",
"@pnp/spfx-property-controls": "1.19.0",
"@types/es6-promise": "0.0.33", "@types/es6-promise": "0.0.33",
"@types/react": "16.8.8", "@types/react": "16.8.8",
"@types/react-dom": "16.8.3", "@types/react-dom": "16.8.3",

View File

@ -17,14 +17,14 @@ export default class TimelineService {
/** /**
* Get timeline activity by id. * Get timeline activity by id.
* @param listTitle * @param listId
* @param id * @param id
*/ */
public async getTimelineActivity(listTitle: string, id: number): Promise<ITimelineActivity> { public async getTimelineActivity(listId: string, id: number): Promise<ITimelineActivity> {
let returnTimelineActivity: ITimelineActivity = undefined; let returnTimelineActivity: ITimelineActivity = undefined;
try { try {
let activity: any = await sp.web.lists.getByTitle(listTitle).items.usingCaching().getById(id) let activity: any = await sp.web.lists.getById(listId).items.usingCaching().getById(id)
.select("Id", "Title", "SPFxTimelineLink", "SPFxTimelineDate", "SPFxTimelinePicture", "SPFxTimelineDescription") .select("Id", "Title", "SPFxTimelineLink", "SPFxTimelineDate", "SPFxTimelinePicture", "SPFxTimelineDescription")
.get(); .get();
@ -46,15 +46,15 @@ export default class TimelineService {
/** /**
* Get all timeline activities * Get all timeline activities
* @param listTitle * @param listId
* @param sortOrder * @param sortOrder
*/ */
public async getTimelineActivities(listTitle: string, sortOrder: string): Promise<ITimelineActivity[]> { public async getTimelineActivities(listId: string, sortOrder: string): Promise<ITimelineActivity[]> {
let returnTimelineActivities: ITimelineActivity[] = []; let returnTimelineActivities: ITimelineActivity[] = [];
let sortOrderAsc: boolean = (sortOrder === "asc"); let sortOrderAsc: boolean = (sortOrder === "asc");
try { try {
let activities: any[] = await sp.web.lists.getByTitle(listTitle).items let activities: any[] = await sp.web.lists.getById(listId).items
.select("Id", "Title", "SPFxTimelineLink", "SPFxTimelineDate", "SPFxTimelinePicture", "SPFxTimelineDescription") .select("Id", "Title", "SPFxTimelineLink", "SPFxTimelineDate", "SPFxTimelinePicture", "SPFxTimelineDescription")
.orderBy("SPFxTimelineDate", sortOrderAsc) .orderBy("SPFxTimelineDate", sortOrderAsc)
.get(); .get();
@ -81,10 +81,10 @@ export default class TimelineService {
/** /**
* Adds timeline activity to SP list. * Adds timeline activity to SP list.
* @param listTitle * @param listId
* @param newTimelineActivity * @param newTimelineActivity
*/ */
public async addTimelineActivity(listTitle: string, newTimelineActivity: ITimelineActivity) { public async addTimelineActivity(listId: string, newTimelineActivity: ITimelineActivity) {
try { try {
let addData: ITypedHash<any> = { let addData: ITypedHash<any> = {
Title: newTimelineActivity.activityTitle, Title: newTimelineActivity.activityTitle,
@ -110,7 +110,7 @@ export default class TimelineService {
}; };
} }
await sp.web.lists.getByTitle(listTitle).items.add(addData); await sp.web.lists.getById(listId).items.add(addData);
} }
catch (error) { catch (error) {
console.log(error); console.log(error);
@ -120,10 +120,10 @@ export default class TimelineService {
/** /**
* Updates timeline activity to SP list by id. * Updates timeline activity to SP list by id.
* @param listTitle * @param listId
* @param updateTimelineActivity * @param updateTimelineActivity
*/ */
public async updateTimelineActivity(listTitle: string, updateTimelineActivity: ITimelineActivity) { public async updateTimelineActivity(listId: string, updateTimelineActivity: ITimelineActivity) {
try { try {
let updateItem: ITypedHash<any> = { let updateItem: ITypedHash<any> = {
Title: updateTimelineActivity.activityTitle, Title: updateTimelineActivity.activityTitle,
@ -153,7 +153,7 @@ export default class TimelineService {
}; };
} }
await sp.web.lists.getByTitle(listTitle).items.getById(updateTimelineActivity.id).update(updateItem).then((value: any) => { await sp.web.lists.getById(listId).items.getById(updateTimelineActivity.id).update(updateItem).then((value: any) => {
console.log(value); console.log(value);
}); });
} }
@ -165,12 +165,12 @@ export default class TimelineService {
/** /**
* Deletes timeline activity from SP list. * Deletes timeline activity from SP list.
* @param listTitle * @param listId
* @param deleteTimelineActivity * @param deleteTimelineActivity
*/ */
public async deleteTimelineActivity(listTitle: string, deleteTimelineActivity: ITimelineActivity) { public async deleteTimelineActivity(listId: string, deleteTimelineActivity: ITimelineActivity) {
try { try {
await sp.web.lists.getByTitle(listTitle).items.getById(deleteTimelineActivity.id).delete(); await sp.web.lists.getById(listId).items.getById(deleteTimelineActivity.id).delete();
} }
catch (error) { catch (error) {
return Promise.reject(error); return Promise.reject(error);

View File

@ -22,11 +22,9 @@
"officeFabricIconFontName": "TimelineProgress", "officeFabricIconFontName": "TimelineProgress",
"properties": { "properties": {
"description": "Timeline Events", "description": "Timeline Events",
"listName": "Timeline",
"layout": "Vertical", "layout": "Vertical",
"showImage": true, "showImage": true,
"showDescription": true, "showDescription": true,
"dateFormat": "MM/DD/yyyy",
"sortOrder": "asc" "sortOrder": "asc"
} }
}] }]

View File

@ -11,7 +11,7 @@ import * as strings from 'TimelineWebPartStrings';
import Timeline from './components/Timeline'; import Timeline from './components/Timeline';
import { ITimelineProps } from './components/ITimelineProps'; import { ITimelineProps } from './components/ITimelineProps';
import TimelineService from '../../services/TimelineService'; import TimelineService from '../../services/TimelineService';
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy, ISPList } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
export interface ITimelineWebPartProps { export interface ITimelineWebPartProps {
description: string; description: string;
@ -19,16 +19,16 @@ export interface ITimelineWebPartProps {
layout: string; layout: string;
showImage: boolean; showImage: boolean;
showDescription: boolean; showDescription: boolean;
dateFormat : string; dateFormat: string;
sortOrder: string; sortOrder: string;
} }
export default class TimelineWebPart extends BaseClientSideWebPart <ITimelineWebPartProps> { export default class TimelineWebPart extends BaseClientSideWebPart<ITimelineWebPartProps> {
private TimelineService: TimelineService = null; private TimelineService: TimelineService = null;
protected onInit(): Promise<void> { protected onInit(): Promise<void> {
this.TimelineService = new TimelineService(this.context); this.TimelineService = new TimelineService(this.context);
return Promise.resolve(); return Promise.resolve();
} }
public render(): void { public render(): void {
@ -44,7 +44,7 @@ export default class TimelineWebPart extends BaseClientSideWebPart <ITimelineWeb
dateFormat: this.properties.dateFormat, dateFormat: this.properties.dateFormat,
sortOrder: this.properties.sortOrder sortOrder: this.properties.sortOrder
} }
); );
ReactDom.render(element, this.domElement); ReactDom.render(element, this.domElement);
} }
@ -71,30 +71,44 @@ export default class TimelineWebPart extends BaseClientSideWebPart <ITimelineWeb
PropertyPaneTextField('description', { PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel label: strings.DescriptionFieldLabel
}), }),
PropertyPaneTextField('listName', { PropertyFieldListPicker('listName', {
label: strings.ListNameFieldLabel label: strings.ListNameFieldLabel,
selectedList: this.properties.listName,
includeHidden: false,
orderBy: PropertyFieldListPickerOrderBy.Title,
disabled: false,
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
properties: this.properties,
context: this.context,
onGetErrorMessage: null,
deferredValidationTime: 0,
key: 'listPickerFieldId',
baseTemplate: 100
}), }),
PropertyPaneDropdown('layout', { PropertyPaneDropdown('layout', {
label: strings.LayoutFieldLabel, label: strings.LayoutFieldLabel,
options: [ options: [
{ key: 'Vertical', text: 'Vertical' }, { key: 'Vertical', text: strings.VerticalLabel },
{ key: 'Horizontal', text: 'Horizontal' } { key: 'Horizontal', text: strings.HorizontalLabel }
] ]
}), }),
PropertyPaneToggle('showImage', { PropertyPaneToggle('showImage', {
label: strings.ShowImageFieldLabel,checked:true label: strings.ShowImageFieldLabel,
checked: true
}), }),
PropertyPaneToggle('showDescription', { PropertyPaneToggle('showDescription', {
label: strings.ShowDescriptionFieldLabel, checked: true label: strings.ShowDescriptionFieldLabel,
checked: true
}), }),
PropertyPaneTextField('dateFormat', { PropertyPaneTextField('dateFormat', {
label: strings.DateFormatFieldLabel label: strings.DateFormatFieldLabel,
value: strings.DateFormatText
}), }),
PropertyPaneDropdown('sortOrder', { PropertyPaneDropdown('sortOrder', {
label: strings.SortOrderFieldLabel, label: strings.SortOrderFieldLabel,
options: [ options: [
{ key: 'asc', text: 'Ascending' }, { key: 'asc', text: strings.AscendingLabel },
{ key: 'desc', text: 'Descending' } { key: 'desc', text: strings.DescendingLabel }
] ]
}) })
] ]

View File

@ -1,5 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import styles from './timelineEvent.module.scss'; import styles from './timelineEvent.module.scss';
import * as strings from 'TimelineWebPartStrings';
import { IEventProps } from './ITimeLineEventProps'; import { IEventProps } from './ITimeLineEventProps';
import { IEventState } from './ITimeLineEventState'; import { IEventState } from './ITimeLineEventState';
import { ITimelineActivity } from '../../../../models/ITimelineActivity'; import { ITimelineActivity } from '../../../../models/ITimelineActivity';
@ -219,13 +220,13 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
<div> <div>
<Dialog <Dialog
isOpen={this.props.showPanel} isOpen={this.props.showPanel}
closeButtonAriaLabel="Close" closeButtonAriaLabel={strings.CloseLabel}
dialogContentProps={{ dialogContentProps={{
type: DialogType.normal, type: DialogType.normal,
title: title:
this.props.panelMode == 2 this.props.panelMode == 2
? "Edit Timeline Event" ? strings.EditEventLabel
: "Create Timeline Event", : strings.AddEventLabel,
showCloseButton: true, showCloseButton: true,
}} }}
onDismiss={this.hidePanel} onDismiss={this.hidePanel}
@ -235,7 +236,7 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
> >
<div> <div>
<TextField <TextField
label="Title" label={strings.TitleLabel}
required required
value={ value={
this.state.eventData this.state.eventData
@ -247,7 +248,7 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
/> />
</div> </div>
<Label> <Label>
Date {strings.DateLabel}
</Label> </Label>
<div <div
@ -339,14 +340,14 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
<div> <div>
<TextField <TextField
label="Description" label={strings.DescriptionLabel}
value={this.state.activityDescription} onChange={this.onDescriptionChange} value={this.state.activityDescription} onChange={this.onDescriptionChange}
multiline multiline
/> />
</div> </div>
<div> <div>
<TextField <TextField
label="Picture URL" label={strings.PictureURLLabel}
value={ value={
this.state.eventData this.state.eventData
? this.state.eventData.activityPictureUrl ? this.state.eventData.activityPictureUrl["Url"] : '' ? this.state.eventData.activityPictureUrl ? this.state.eventData.activityPictureUrl["Url"] : ''
@ -358,7 +359,7 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
</div> </div>
<div> <div>
<TextField <TextField
label="Link URL" label={strings.LinkURLLabel}
value={ value={
this.state.eventData this.state.eventData
? this.state.eventData.activityLink ? this.state.eventData.activityLink["Url"] : '' ? this.state.eventData.activityLink ? this.state.eventData.activityLink["Url"] : ''
@ -369,7 +370,7 @@ export class TimelineEvent extends React.Component<IEventProps, IEventState> {
/> />
</div> </div>
<DialogFooter> <DialogFooter>
<PrimaryButton onClick={this.onSave} text={this.props.panelMode == 2 ? "Update Event" : "Create Event"} /> <PrimaryButton onClick={this.onSave} text={this.props.panelMode == 2 ? strings.UpdateEventLabel : strings.AddEventLabel} />
<DefaultButton onClick={this.hidePanel} text="Cancel" /> <DefaultButton onClick={this.hidePanel} text="Cancel" />
</DialogFooter> </DialogFooter>
</Dialog> </Dialog>

View File

@ -1,27 +1,15 @@
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss"; @import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
:global(.ms-Dialog-inner) {
padding-left: 50px !important;
padding-right: 50px !important;
}
:global(.ms-Dialog-title) {
color: white !important;
background-color: $ms-color-themePrimary !important;
font-size: 16px;
font-weight: bold;
padding: 18px !important;
}
:global(i.ms-Button-icon[data-icon-name="Cancel"]) {
width: 25px;
height: 25px;
background-repeat: no-repeat;
background-size: 23px 23px;
color: white !important;
}
.dialogOverride { .dialogOverride {
:global(.ms-Dialog-title) {
color: white !important;
background-color: $ms-color-themePrimary !important;
}
:global(i.ms-Button-icon[data-icon-name="Cancel"]) {
color: white !important;
}
@media (max-width: $ms-screen-max-md) { @media (max-width: $ms-screen-max-md) {
// need to remove justify center when on a small screen so dialog can use full width // need to remove justify center when on a small screen so dialog can use full width
:global(.ms-Dialog) { :global(.ms-Dialog) {

View File

@ -1,10 +1,11 @@
import * as React from 'react'; import * as React from 'react';
import styles from './Timeline.module.scss'; import styles from './Timeline.module.scss';
import * as strings from 'TimelineWebPartStrings';
import { ITimelineProps } from './ITimelineProps'; import { ITimelineProps } from './ITimelineProps';
import { ITimelineState } from './ITimelineState'; import { ITimelineState } from './ITimelineState';
import { escape } from '@microsoft/sp-lodash-subset'; import { escape } from '@microsoft/sp-lodash-subset';
import TimelineService from '../../../services/TimelineService'; import TimelineService from '../../../services/TimelineService';
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import TimelineActivity from "./TimelineActivity"; import TimelineActivity from "./TimelineActivity";
import { ITimelineActivity } from "../../../models/ITimelineActivity"; import { ITimelineActivity } from "../../../models/ITimelineActivity";
import { SPPermission } from '@microsoft/sp-page-context'; import { SPPermission } from '@microsoft/sp-page-context';
@ -36,29 +37,47 @@ export default class Timeline extends React.Component<ITimelineProps, ITimelineS
} }
} }
private _onConfigure = () => {
// Context of the web part
this.props.context.propertyPane.open();
}
public render(): React.ReactElement<ITimelineProps> { public render(): React.ReactElement<ITimelineProps> {
return ( return (
<div className={styles.timeline}> <div className={styles.timeline}>
<h1>{this.props.description}</h1> {
<div className={this.props.layout == "Vertical" ? `${styles.timelineContainerVertical}` : `${styles.timelineContainerHorizontal}`}> this.state.timelineActivities.length == 0 &&
{ <Placeholder iconName='Edit'
this.state.timelineActivities.map((activity, i) => { iconText={strings.ConfigureWebPartLabel}
return ( description={strings.ConfigureDescription}
<TimelineActivity activity={activity} buttonLabel={strings.ConfigureLabel}
index={i} onConfigure={this._onConfigure} />
context={this.props.context} }
onDissmissPanel={this.onDismissPanel}
displayPanel={false} {this.state.timelineActivities.length > 0 &&
listName={this.props.listName} <>
layout={this.props.layout} <h1>{this.props.description}</h1>
showImage={this.props.showImage} <div className={this.props.layout == "Vertical" ? `${styles.timelineContainerVertical}` : `${styles.timelineContainerHorizontal}`}>
showDescription={this.props.showDescription} {
dateFormat={this.props.dateFormat} this.state.timelineActivities.map((activity, i) => {
canEdit={this.canEdit} > return (
</TimelineActivity> <TimelineActivity activity={activity}
); index={i}
})} context={this.props.context}
</div> onDissmissPanel={this.onDismissPanel}
displayPanel={false}
listName={this.props.listName}
layout={this.props.layout}
showImage={this.props.showImage}
showDescription={this.props.showDescription}
dateFormat={this.props.dateFormat}
canEdit={this.canEdit} >
</TimelineActivity>
);
})}
</div>
</>
}
</div> </div>
); );
} }
@ -66,13 +85,17 @@ export default class Timeline extends React.Component<ITimelineProps, ITimelineS
public componentDidMount(): void { public componentDidMount(): void {
this.TimelineService.getTimelineActivities(this.props.listName, this.props.sortOrder).then((activities: ITimelineActivity[]) => { this.TimelineService.getTimelineActivities(this.props.listName, this.props.sortOrder).then((activities: ITimelineActivity[]) => {
this.setState({ timelineActivities: activities }); this.setState({ timelineActivities: activities });
}).catch((error: any) => {
this.setState({ timelineActivities: [] });
}); });
} }
public componentWillReceiveProps(nextProps: ITimelineProps) { public componentWillReceiveProps(nextProps: ITimelineProps) {
if (this.props.sortOrder !== nextProps.sortOrder) { if (this.props.sortOrder !== nextProps.sortOrder || this.props.listName !== nextProps.listName) {
this.TimelineService.getTimelineActivities(this.props.listName, nextProps.sortOrder).then((activities: ITimelineActivity[]) => { this.TimelineService.getTimelineActivities(nextProps.listName, nextProps.sortOrder).then((activities: ITimelineActivity[]) => {
this.setState({ timelineActivities: activities }); this.setState({ timelineActivities: activities });
}).catch((error: any) => {
this.setState({ timelineActivities: [] });
}); });
} }
} }

View File

@ -1,5 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import styles from './Timeline.module.scss'; import styles from './Timeline.module.scss';
import * as strings from 'TimelineWebPartStrings';
import { escape } from '@microsoft/sp-lodash-subset'; import { escape } from '@microsoft/sp-lodash-subset';
import { ITimelineActivity } from "../../../models"; import { ITimelineActivity } from "../../../models";
import { Card, ICardTokens, ICardSectionStyles, ICardSectionTokens } from '@uifabric/react-cards'; import { Card, ICardTokens, ICardSectionStyles, ICardSectionTokens } from '@uifabric/react-cards';
@ -178,14 +179,14 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
{ {
this.props.canEdit && this.props.canEdit &&
<div className={this.state.layout == "Vertical" ? `${styles.timelineAddVertical}` : `${styles.timelineAddHorizontal}`}> <div className={this.state.layout == "Vertical" ? `${styles.timelineAddVertical}` : `${styles.timelineAddHorizontal}`}>
<IconButton iconProps={addToIcon} title="Add Timeline Event" ariaLabel="Add Activity" className={styles.addToButton} onClick={this.createEvent} /> <IconButton iconProps={addToIcon} title={strings.AddEventLabel} ariaLabel={strings.AddEventLabel} className={styles.addToButton} onClick={this.createEvent} />
</div> </div>
} }
<Dialog type={DialogType.normal} <Dialog type={DialogType.normal}
hidden={!this.state.showDeleteDialog} hidden={!this.state.showDeleteDialog}
title='Delete event?' title={strings.DeleteEventLabel}
subText='Do you want to delete this event?' subText={strings.DeleteEventConfirmationLabel}
isBlocking={true} isBlocking={true}
containerClassName={'ms-dialogMainOverride'}> containerClassName={'ms-dialogMainOverride'}>
<DialogFooter> <DialogFooter>
@ -220,7 +221,6 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
)} )}
<div className={styles.timelineCard}> <div className={styles.timelineCard}>
<Card <Card
aria-label="Clickable horizontal card "
horizontal horizontal
tokens={cardTokens} tokens={cardTokens}
> >
@ -229,7 +229,7 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
<Card.Item fill> <Card.Item fill>
<Image <Image
src={activity.activityPictureUrl ? activity.activityPictureUrl["Url"] : ''} src={activity.activityPictureUrl ? activity.activityPictureUrl["Url"] : ''}
alt="Placeholder image." alt={activity.activityTitle}
width="100px" width="100px"
height="100px" height="100px"
/> />
@ -259,7 +259,7 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
> >
{canEdit && {canEdit &&
<IconButton <IconButton
id="ContextualMenuButton1" id="ContextualMenuButtonMore"
text="" text=""
split={false} split={false}
iconProps={{ iconName: "MoreVertical" }} iconProps={{ iconName: "MoreVertical" }}
@ -270,7 +270,7 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
items: [ items: [
{ {
key: "Edit", key: "Edit",
name: "Edit", name: strings.EditEventLabel,
onClick: (event) => { onClick: (event) => {
this.setState({ selectedEvent: activity }); this.setState({ selectedEvent: activity });
this.editEvent(); this.editEvent();
@ -282,7 +282,7 @@ export default class TimelineActivity extends React.Component<IActivityProps, IA
}, },
{ {
key: "Delete", key: "Delete",
name: "Delete", name: strings.DeleteEventLabel,
onClick: (event) => { onClick: (event) => {
this.setState({ this.setState({
selectedEvent: activity, selectedEvent: activity,

View File

@ -1,13 +1,32 @@
define([], function() { define([], function () {
return { return {
"PropertyPaneDescription": "Description", "PropertyPaneDescription": "Description",
"BasicGroupName": "Group Name", "BasicGroupName": "Group Name",
"DescriptionFieldLabel": "WebPart Title", "DescriptionFieldLabel": "WebPart Title",
"ListNameFieldLabel":"List Name", "ListNameFieldLabel": "List Name",
"LayoutFieldLabel":"Layout Type", "LayoutFieldLabel": "Layout Type",
"ShowImageFieldLabel":"Show Image", "ShowImageFieldLabel": "Show Image",
"ShowDescriptionFieldLabel": "Show Description", "ShowDescriptionFieldLabel": "Show Description",
"DateFormatFieldLabel": "Date Format", "DateFormatFieldLabel": "Date Format",
"SortOrderFieldLabel": "Sort Direction" "SortOrderFieldLabel": "Sort Direction",
"EditEventLabel": "Edit Event",
"UpdateEventLabel": "Update Event",
"AddEventLabel": "Add Event",
"DeleteEventLabel": "Delete Event",
"DeleteEventConfirmationLabel": "Do you want to delete this event?",
"CloseLabel": "Close",
"TitleLabel": "Title",
"DateLabel": "Date",
"DescriptionLabel": "Description",
"PictureURLLabel": "Picture URL",
"LinkURLLabel": "Link URL",
"ConfigureWebPartLabel": "Configure your timeline",
"ConfigureDescription": "Please select the list with timeline information",
"ConfigureLabel": "Configure",
"AscendingLabel": "Ascending",
"DescendingLabel": "Descending",
"VerticalLabel": "Vertical",
"HorizontalLabel": "Horizontal",
"DateFormatText": "MM/DD/yyyy"
} }
}); });

View File

@ -8,6 +8,25 @@ declare interface ITimelineWebPartStrings {
ShowDescriptionFieldLabel: string; ShowDescriptionFieldLabel: string;
DateFormatFieldLabel: string; DateFormatFieldLabel: string;
SortOrderFieldLabel: string; SortOrderFieldLabel: string;
EditEventLabel: string;
UpdateEventLabel: string;
AddEventLabel: string;
DeleteEventLabel: string;
DeleteEventConfirmationLabel: string;
CloseLabel: string;
TitleLabel: string;
DateLabel: string;
DescriptionLabel: string;
PictureURLLabel: string;
LinkURLLabel: string;
ConfigureWebPartLabel: string;
ConfigureDescription: string;
ConfigureLabel: string;
AscendingLabel: string;
DescendingLabel: string;
VerticalLabel: string;
HorizontalLabel: string;
DateFormatText: string;
} }
declare module 'TimelineWebPartStrings' { declare module 'TimelineWebPartStrings' {