Initial push of README
This commit is contained in:
parent
85eb0e0b36
commit
e046d58f20
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"typescript.tsdk": "./node_modules/typescript/lib"
|
||||||
|
}
|
|
@ -1,26 +1,118 @@
|
||||||
## react-todo-webpart
|
# Todo Basic Sample
|
||||||
|
|
||||||
This is where you include your web part docs.
|
## Summary
|
||||||
|
A simple todo web part built using react to showcase some of the SharePoint Framework developer features, utilities and best practices in building react based web parts.
|
||||||
|
|
||||||
### Building the code
|
![Todo basic web part demo in SharePoint Workbench](./assets/todo-basic-demo.gif)
|
||||||
|
|
||||||
```bash
|
## Applies to
|
||||||
git clone the repo
|
|
||||||
npm i
|
* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
|
||||||
npm i -g gulp
|
* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
|
||||||
gulp
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
react-todo-basic | Chakkaradeep Chandran (@chakkaradeep)
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0|October 12th, 2016|Initial release
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
- Clone this repository
|
||||||
|
- in the command line run:
|
||||||
|
- `npm install`
|
||||||
|
- `gulp serve`
|
||||||
|
|
||||||
|
## Features
|
||||||
|
This todo basic sample web part showcases some of the SharePoint Framework developer features which will help you build web parts with great user experiences along with good coding pattern and practices for react based web parts. Below are some resources if you are not familiar with react:
|
||||||
|
|
||||||
|
- [React Quick Start](https://facebook.github.io/react/docs/tutorial.html)
|
||||||
|
- [TypeScript React Tutorials](https://www.typescriptlang.org/docs/handbook/react-&-webpack.html)
|
||||||
|
|
||||||
|
### Status Renderers
|
||||||
|
SharePoint Framework provides status renderers to display information when the web part is performing any time consuming operations such as fetching data from SharePoint. The following status renderers are available via the web part context property:
|
||||||
|
|
||||||
|
- Loading indicator
|
||||||
|
- Used to display the loading indicator. Useful when you are initializing or loading any content in your web part.
|
||||||
|
- Error indicator
|
||||||
|
- Used to display error messages.
|
||||||
|
|
||||||
|
![Todo basic web part loading progress](./assets/todo-basic-placeholder.gif)
|
||||||
|
|
||||||
|
Here is an example of using the loading indicator. You can find this code in the `onInit` method in the [TodoWebPart.ts](./src/webparts/todo/TodoWebPart.ts) file.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Todo");
|
||||||
|
```
|
||||||
|
The code above displays the default loading indicator for web parts. The `this.domElement` specifically instructs the loading indicator to be displayed in the web part's DOM element.
|
||||||
|
|
||||||
|
To clear the loading indicator when your operation is complete, you just call `clearLoadingIndicator`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||||
```
|
```
|
||||||
|
|
||||||
This package produces the following:
|
### Placeholders
|
||||||
|
Placeholders are a great way to show default information when the web part is first run or needs to be configured. SharePoint Framework provides a default placeholder react component that you can use in your react based web parts.
|
||||||
|
|
||||||
* lib/* commonjs components - this allows this package to be reused from other packages.
|
![Todo basic web part placeholder](./assets/todo-basic-placeholder.gif)
|
||||||
* dist/* - a single bundle containing the components used for uploading to a cdn pointing a registered Sharepoint webpart library to.
|
|
||||||
* example/* a test page that hosts all components in this package.
|
|
||||||
|
|
||||||
### Build options
|
To use this placeholder component, you will need to import the `Placeholder` component from `@microsoft/sp-client-preview` module.
|
||||||
|
|
||||||
gulp nuke - TODO
|
```ts
|
||||||
gulp test - TODO
|
import { Placeholder } from '@microsoft/sp-client-preview';
|
||||||
gulp watch - TODO
|
```
|
||||||
gulp build - TODO
|
Once imported, then you can simply create the component. You can find this code in the [TodoContainer.tsx](./src/webparts/todo/components/TodoContainer/TodoContainer.tsx) file.
|
||||||
gulp deploy - TODO
|
|
||||||
|
```tsx
|
||||||
|
<Placeholder
|
||||||
|
icon={ 'ms-Icon--Edit' }
|
||||||
|
iconText='Todos'
|
||||||
|
description='Get things done. Organize and share your team\'s to-do items with your team. Edit this web part to start managing to-dos.' />
|
||||||
|
```
|
||||||
|
You can also include a button in the placeholder if you want to aid specific operation that helps end users.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<Placeholder
|
||||||
|
icon={ 'ms-Icon--Edit' }
|
||||||
|
iconText='Todos'
|
||||||
|
description='Get things done. Organize and share your team\'s to-do items with your team.'
|
||||||
|
buttonLabel='Configure'
|
||||||
|
onAdd={ this._configureWebPart } />
|
||||||
|
```
|
||||||
|
### Lodash Utility Library
|
||||||
|
[lodash](https://lodash.com/) is a great JavaScript utility library that you can use to perform operations on various objects like arrays, numbers, strings etc., SharePoint Framework includes [`lodash` utility library](https://www.npmjs.com/package/@microsoft/sp-lodash-subset) for use with SharePoint Framework out of the box so you need not install it separately. To improve runtime performance, it only includes a subset of the most essential lodash functions.
|
||||||
|
|
||||||
|
To use the `lodash` utility, you will need to first import the library from the `@microsoft/sp-lodash-subset` module:
|
||||||
|
|
||||||
|
```
|
||||||
|
import * as lodash from '@microsoft/sp-lodash-subset';
|
||||||
|
```
|
||||||
|
Here is an example how the [MockDataProvider](./src/webparts/todo/tests/MockDataProvider.ts) uses `lodash`'s `findIndex` method to find the index of the todo item to update. You can find this code in the `updateItem` method:
|
||||||
|
|
||||||
|
```
|
||||||
|
const index: number =
|
||||||
|
lodash.findIndex(
|
||||||
|
this._items[this._selectedList.Title],
|
||||||
|
(item: ITodoItem) => item.Id === itemUpdated.Id
|
||||||
|
);
|
||||||
|
```
|
||||||
|
### Page Display Modes
|
||||||
|
SharePoint pages have display modes which indicates in which mode that page and/or its contents (e.g. text and web parts) are displayed. In the classic server-side SharePoint page, the web part needs to be in edit mode even though the page is already in the edit mode while in the modern client-side SharePoint page, both the page and/or its contents are in the same mode.
|
||||||
|
|
||||||
|
You can provide a tailored experience using the display modes to enhance the web part user experience. In this web part, we display different placeholder depending on the page display mode. This is well demonstrated in the classic server-side SharePoint page.
|
||||||
|
|
||||||
|
When the page is in edit mode, but the web part is not, the web part displays the following placeholder.
|
||||||
|
|
||||||
|
When the page in in edit mode and also the web part, the web part displays the following placeholder:
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 734 KiB |
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
|
@ -1,5 +1,4 @@
|
||||||
interface ITodoWebPartProps {
|
interface ITodoWebPartProps {
|
||||||
description: string;
|
|
||||||
spListIndex: number;
|
spListIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
BaseClientSideWebPart,
|
BaseClientSideWebPart,
|
||||||
IPropertyPaneSettings,
|
IPropertyPaneSettings,
|
||||||
IWebPartContext,
|
IWebPartContext,
|
||||||
PropertyPaneTextField,
|
|
||||||
PropertyPaneDropdown,
|
PropertyPaneDropdown,
|
||||||
IPropertyPaneField,
|
IPropertyPaneField,
|
||||||
PropertyPaneLabel,
|
PropertyPaneLabel,
|
||||||
|
@ -59,7 +58,6 @@ export default class TodoWebPart extends BaseClientSideWebPart<ITodoWebPartProps
|
||||||
const element: React.ReactElement<ITodoContainerProps> = React.createElement(
|
const element: React.ReactElement<ITodoContainerProps> = React.createElement(
|
||||||
TodoContainer,
|
TodoContainer,
|
||||||
{
|
{
|
||||||
description: this.properties.description,
|
|
||||||
dataProvider: this._dataProvider,
|
dataProvider: this._dataProvider,
|
||||||
webPartContext: this.context,
|
webPartContext: this.context,
|
||||||
webPartDisplayMode: this.displayMode,
|
webPartDisplayMode: this.displayMode,
|
||||||
|
@ -123,10 +121,6 @@ export default class TodoWebPart extends BaseClientSideWebPart<ITodoWebPartProps
|
||||||
private _getGroupFields(): IPropertyPaneField<any>[] {
|
private _getGroupFields(): IPropertyPaneField<any>[] {
|
||||||
const fields: IPropertyPaneField<any>[] = [];
|
const fields: IPropertyPaneField<any>[] = [];
|
||||||
|
|
||||||
fields.push(PropertyPaneTextField('description', {
|
|
||||||
label: strings.DescriptionFieldLabel
|
|
||||||
}));
|
|
||||||
|
|
||||||
fields.push(PropertyPaneDropdown('spListIndex', {
|
fields.push(PropertyPaneDropdown('spListIndex', {
|
||||||
label: "Select a list",
|
label: "Select a list",
|
||||||
isDisabled: this._disableDropdown,
|
isDisabled: this._disableDropdown,
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { DisplayMode } from '@microsoft/sp-client-base';
|
||||||
import ITodoDataProvider from '../../dataProviders/ITodoDataProvider';
|
import ITodoDataProvider from '../../dataProviders/ITodoDataProvider';
|
||||||
|
|
||||||
interface ITodoContainerProps {
|
interface ITodoContainerProps {
|
||||||
description: string;
|
|
||||||
dataProvider: ITodoDataProvider;
|
dataProvider: ITodoDataProvider;
|
||||||
webPartContext: IWebPartContext;
|
webPartContext: IWebPartContext;
|
||||||
webPartDisplayMode: DisplayMode;
|
webPartDisplayMode: DisplayMode;
|
||||||
|
|
|
@ -11,8 +11,6 @@ import ITodoContainerState from './ITodoContainerState';
|
||||||
import update = require('react-addons-update');
|
import update = require('react-addons-update');
|
||||||
|
|
||||||
export default class Todo extends React.Component<ITodoContainerProps, ITodoContainerState> {
|
export default class Todo extends React.Component<ITodoContainerProps, ITodoContainerState> {
|
||||||
|
|
||||||
//private _dataProvider: ITodoDataProvider;
|
|
||||||
private _showPlaceHolder: boolean = true;
|
private _showPlaceHolder: boolean = true;
|
||||||
|
|
||||||
constructor(props: ITodoContainerProps) {
|
constructor(props: ITodoContainerProps) {
|
||||||
|
@ -40,10 +38,8 @@ export default class Todo extends React.Component<ITodoContainerProps, ITodoCont
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillReceiveProps(props: ITodoContainerProps) {
|
public componentWillReceiveProps(props: ITodoContainerProps) {
|
||||||
//if (props.selectedList) {
|
|
||||||
if (this.props.dataProvider.selectedList) {
|
if (this.props.dataProvider.selectedList) {
|
||||||
if (this.props.dataProvider.selectedList.Id !== '0') {
|
if (this.props.dataProvider.selectedList.Id !== '0') {
|
||||||
//this._dataProvider.selectedList = props.selectedList;
|
|
||||||
this._showPlaceHolder = false;
|
this._showPlaceHolder = false;
|
||||||
this.props.dataProvider.getItems().then(
|
this.props.dataProvider.getItems().then(
|
||||||
(items: ITodoItem[]) => {
|
(items: ITodoItem[]) => {
|
||||||
|
@ -77,7 +73,7 @@ export default class Todo extends React.Component<ITodoContainerProps, ITodoCont
|
||||||
iconText='Todos'
|
iconText='Todos'
|
||||||
description='Get things done. Organize and share your team\'s to-do items with your team.'
|
description='Get things done. Organize and share your team\'s to-do items with your team.'
|
||||||
buttonLabel='Configure'
|
buttonLabel='Configure'
|
||||||
onAdd={ this._configureWebPart.bind(this) } />
|
onAdd={ this._configureWebPart } />
|
||||||
}
|
}
|
||||||
{ this._showPlaceHolder && this.props.webPartDisplayMode === DisplayMode.Read &&
|
{ this._showPlaceHolder && this.props.webPartDisplayMode === DisplayMode.Read &&
|
||||||
<Placeholder
|
<Placeholder
|
||||||
|
@ -88,7 +84,7 @@ export default class Todo extends React.Component<ITodoContainerProps, ITodoCont
|
||||||
{ !this._showPlaceHolder &&
|
{ !this._showPlaceHolder &&
|
||||||
<div className={ styles.todo }>
|
<div className={ styles.todo }>
|
||||||
<div className={ styles.topRow }>
|
<div className={ styles.topRow }>
|
||||||
<h2 className={ styles.todoHeading }>{this.props.description}</h2>
|
<h2 className={ styles.todoHeading }>Todo</h2>
|
||||||
</div>
|
</div>
|
||||||
<TodoForm onAddTodoItem={ this._createTodoItem} />
|
<TodoForm onAddTodoItem={ this._createTodoItem} />
|
||||||
<TodoList items={this.state.todoItems}
|
<TodoList items={this.state.todoItems}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { List, FocusZone, FocusZoneDirection, getRTLSafeKeyCode, KeyCodes } from 'office-ui-fabric-react';
|
import { List, FocusZone, FocusZoneDirection, getRTLSafeKeyCode, KeyCodes } from 'office-ui-fabric-react';
|
||||||
import { Compare } from '@microsoft/sp-client-base';
|
|
||||||
import ITodoListProps from './ITodoListProps';
|
import ITodoListProps from './ITodoListProps';
|
||||||
import TodoListItem from '../TodoListItem/TodoListItem';
|
import TodoListItem from '../TodoListItem/TodoListItem';
|
||||||
import ITodoItem from '../../models/ITodoItem';
|
import ITodoItem from '../../models/ITodoItem';
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
define([], function() {
|
define([], function() {
|
||||||
return {
|
return {
|
||||||
"PropertyPaneDescription": "Description",
|
"PropertyPaneDescription": "Configure todo web part",
|
||||||
"BasicGroupName": "Group Name",
|
"BasicGroupName": "Basics"
|
||||||
"DescriptionFieldLabel": "Description Field"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -25,8 +25,7 @@ export default class MockDataProvider implements ITodoDataProvider {
|
||||||
'List One': [
|
'List One': [
|
||||||
this._createMockTodoItem('Sunt filet mignon ut ut porchetta', true),
|
this._createMockTodoItem('Sunt filet mignon ut ut porchetta', true),
|
||||||
this._createMockTodoItem('Laborum flank brisket esse chuck t-bone', false),
|
this._createMockTodoItem('Laborum flank brisket esse chuck t-bone', false),
|
||||||
this._createMockTodoItem('consectetur ex meatloaf boudin beef laborum pastrami', false),
|
this._createMockTodoItem('consectetur ex meatloaf boudin beef laborum pastrami', false)
|
||||||
this._createMockTodoItem('Pariatur rump in kielbasa prosciutto', true)
|
|
||||||
],
|
],
|
||||||
'List Two': [
|
'List Two': [
|
||||||
this._createMockTodoItem('Striga! Ut custodiant te sermonem dicens', false),
|
this._createMockTodoItem('Striga! Ut custodiant te sermonem dicens', false),
|
||||||
|
|
Loading…
Reference in New Issue