-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'joelfmrodrigues-add-folder-picker' into dev
- Loading branch information
Showing
15 changed files
with
335 additions
and
9 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# FolderPicker control | ||
|
||
This control allows you to explore and select a folder. | ||
It also allows the user to create a new folder at the current level being explored. | ||
|
||
Here is an example of the control: | ||
|
||
![FolderPicker](../assets/FolderPicker.png) | ||
|
||
`FolderPicker` no selection: | ||
|
||
![FolderPicker no selection](../assets/FolderPicker-no-selection.png) | ||
|
||
`FolderPicker` selection: | ||
|
||
![FolderPicker selection](../assets/FolderPicker-selection.png) | ||
|
||
`FolderPicker` selected: | ||
|
||
![FolderPicker selected](../assets/FolderPicker-selected.png) | ||
|
||
## How to use this control in your solutions | ||
|
||
- Check that you installed the `@pnp/spfx-controls-react` dependency. Check out the [getting started](../../#getting-started) page for more information about installing the dependency. | ||
- Import the control into your component: | ||
|
||
```TypeScript | ||
import { FolderPicker, IFolder } from "@pnp/spfx-controls-react/lib/FolderPicker"; | ||
``` | ||
|
||
- Use the `FolderPicker` control in your code as follows: | ||
|
||
```TypeScript | ||
<FolderPicker context={this.props.context} | ||
label='Folder Picker' | ||
required={true} | ||
rootFolder={{ | ||
Name: 'Documents', | ||
ServerRelativeUrl: `/sites/TestSite/Shared Documents` | ||
}} | ||
onSelect={this._onFolderSelect} | ||
canCreateFolders={true} /> | ||
``` | ||
|
||
- The `onSelect` change event returns the selected folder and can be implemented as follows: | ||
|
||
```TypeScript | ||
private _onFolderSelect = (folder: IFolder): void => { | ||
console.log('selected folder', folder); | ||
} | ||
``` | ||
|
||
## Implementation | ||
|
||
The `FolderPicker` control can be configured with the following properties: | ||
|
||
| Property | Type | Required | Description | | ||
| ---- | ---- | ---- | ---- | | ||
| context | WebPartContext \| ExtensionContext | yes | The context object of the SPFx loaded webpart or customizer. | | ||
| label | string | yes | The label for the control. | | ||
| rootFolder | IFolder | yes | The lowest level folder that can be explored. This can be the root folder of a library. | | ||
| defaultFolder | IFolder | no | The default folder to be selected or explored. | | ||
| required | boolean | no | Is selection required. | | ||
| disabled | boolean | no | Is the control disabled. | | ||
| canCreateFolders | boolean | no | Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions. | | ||
| onSelect | (folder: IFolder): void | no | Callback function called after a folder is selected. | | ||
|
||
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/FolderPicker) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './controls/folderPicker/index'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// @import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss"; | ||
@import '~office-ui-fabric-react/dist/sass/References.scss'; | ||
|
||
|
||
.folderPicker { | ||
display: flex; | ||
align-items: center; | ||
|
||
.selection { | ||
width: 90%; | ||
} | ||
|
||
.selectFolderLabel { | ||
color: $ms-color-neutralSecondary; | ||
} | ||
|
||
.selectFolder { | ||
align-items: center; | ||
display: flex; | ||
margin-right: 5px; | ||
max-width: 90%; | ||
span { | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
} | ||
} | ||
|
||
& .selectButton { | ||
width: 10%; | ||
display: flex; | ||
justify-content: center; | ||
} | ||
} | ||
|
||
.actions { | ||
button { | ||
margin-right: 15px; | ||
} | ||
} | ||
|
||
label.required::after { | ||
content: " *"; | ||
color: rgb(168, 0, 0); | ||
padding-right: 12px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import * as React from 'react'; | ||
import styles from './FolderPicker.module.scss'; | ||
import { IFolderPickerProps, IFolderPickerState } from '.'; | ||
import { IFolder } from '../../services/IFolderExplorerService'; | ||
import { IconButton, PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; | ||
import { Label } from 'office-ui-fabric-react/lib/Label'; | ||
import { Link } from 'office-ui-fabric-react/lib/Link'; | ||
import { getId } from 'office-ui-fabric-react/lib/Utilities'; | ||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel'; | ||
import { FolderExplorer } from '../folderExplorer/FolderExplorer'; | ||
|
||
|
||
export default class FolderPicker extends React.Component<IFolderPickerProps, IFolderPickerState> { | ||
|
||
private _folderLinkId = getId('folderLink'); | ||
private _selectedFolder: IFolder; | ||
|
||
constructor(props: IFolderPickerProps) { | ||
super(props); | ||
|
||
this.state = { | ||
showPanel: false, | ||
selectedFolder: this.props.defaultFolder | ||
}; | ||
} | ||
|
||
public componentWillReceiveProps(nextProps: IFolderPickerProps) { | ||
|
||
this.setState({ | ||
selectedFolder: nextProps.defaultFolder, | ||
}); | ||
|
||
} | ||
|
||
public render(): React.ReactElement<IFolderPickerProps> { | ||
return ( | ||
<div> | ||
{this.props.label && | ||
<Label className={this.props.required ? styles.required : ''} htmlFor={this._folderLinkId}>{this.props.label}</Label> | ||
} | ||
<div className={styles.folderPicker}> | ||
<div className={styles.selection}> | ||
{!this.state.selectedFolder && | ||
<span className={styles.selectFolderLabel}>Select a folder</span> | ||
} | ||
{this.state.selectedFolder && | ||
<div className={styles.selectFolder}> | ||
<Link className={styles.selectFolder} target='_blank' data-interception="off" id={this._folderLinkId} href={this.state.selectedFolder.ServerRelativeUrl}> | ||
<span title={this.state.selectedFolder.Name}>{this.state.selectedFolder.Name}</span> | ||
</Link> | ||
<IconButton | ||
iconProps={{ iconName: 'Cancel' }} | ||
title="Delete selection" | ||
ariaLabel="Delete selection" | ||
onClick={this._resetSelection} | ||
disabled={this.props.disabled} | ||
/> | ||
</div> | ||
} | ||
</div> | ||
<div className={styles.selectButton}> | ||
<IconButton | ||
iconProps={{ iconName: 'FolderList' }} | ||
title="Select folder" | ||
ariaLabel="Select folder" | ||
disabled={this.props.disabled} | ||
onClick={this._showPanel} | ||
/> | ||
</div> | ||
</div> | ||
|
||
<Panel | ||
isOpen={this.state.showPanel} | ||
type={PanelType.medium} | ||
onDismiss={this._hidePanel} | ||
headerText="Select folder" | ||
closeButtonAriaLabel="Close" | ||
onRenderFooterContent={this._onRenderFooterContent} | ||
> | ||
<div> | ||
<FolderExplorer | ||
context={this.props.context} | ||
rootFolder={this.props.rootFolder} | ||
defaultFolder={this.state.selectedFolder} | ||
onSelect={this._onFolderSelect} | ||
canCreateFolders={this.props.canCreateFolders} | ||
/> | ||
</div> | ||
</Panel> | ||
|
||
</div> | ||
); | ||
} | ||
|
||
private _showPanel = () => { | ||
this.setState({ showPanel: true }); | ||
} | ||
|
||
private _hidePanel = () => { | ||
this.setState({ showPanel: false }); | ||
} | ||
|
||
private _onRenderFooterContent = () => { | ||
return ( | ||
<div className={styles.actions}> | ||
<PrimaryButton iconProps={{ iconName: 'Save' }} onClick={this._onFolderSave}> | ||
Save | ||
</PrimaryButton> | ||
<DefaultButton iconProps={{ iconName: 'Cancel' }} onClick={this._hidePanel}> | ||
Cancel | ||
</DefaultButton> | ||
</div> | ||
); | ||
} | ||
|
||
private _onFolderSelect = (folder: IFolder): void => { | ||
this._selectedFolder = folder; | ||
} | ||
|
||
private _onFolderSave = (): void => { | ||
this.setState({ | ||
selectedFolder: this._selectedFolder, | ||
showPanel: false, | ||
}); | ||
|
||
this.props.onSelect(this._selectedFolder); | ||
} | ||
|
||
private _resetSelection = (): void => { | ||
this._selectedFolder = null; | ||
|
||
this.setState({ | ||
selectedFolder: this._selectedFolder, | ||
}); | ||
|
||
this.props.onSelect(this._selectedFolder); | ||
} | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { WebPartContext } from '@microsoft/sp-webpart-base'; | ||
import { ExtensionContext } from '@microsoft/sp-extension-base'; | ||
import { IFolder } from '../../services/IFolderExplorerService'; | ||
|
||
export interface IFolderPickerProps { | ||
/** | ||
* Current context | ||
*/ | ||
context: WebPartContext | ExtensionContext; | ||
|
||
/** | ||
* The label for the control | ||
*/ | ||
label: string; | ||
|
||
/** | ||
* The lowest level folder that can be explored. This can be the root folder of a library. | ||
*/ | ||
rootFolder: IFolder; | ||
|
||
/** | ||
* The default folder to be explored | ||
*/ | ||
defaultFolder?: IFolder; | ||
|
||
/** | ||
* Is selection required | ||
*/ | ||
required?: boolean; | ||
|
||
/** | ||
* Is the control disabled | ||
*/ | ||
disabled?: boolean; | ||
|
||
/** | ||
* Allow current user to create folders on the target location. If enabled, you need to ensure that the user has the required permissions | ||
*/ | ||
canCreateFolders?: boolean; | ||
|
||
/** | ||
* Callback function called after a folder is selected | ||
* @argument folder The selected folder | ||
*/ | ||
onSelect: (folder: IFolder) => void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { IFolder } from '../../services/IFolderExplorerService'; | ||
|
||
export interface IFolderPickerState { | ||
showPanel: boolean; | ||
selectedFolder: IFolder; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './FolderPicker'; | ||
export * from './IFolderPickerProps'; | ||
export * from './IFolderPickerState'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.