Support for localization
This commit is contained in:
parent
daa67c1fa7
commit
7727eafd28
|
@ -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" />
|
||||||
|
|
|
@ -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
|
@ -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",
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -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 }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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: [] });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -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' {
|
||||||
|
|
Loading…
Reference in New Issue