Skip to content

Commit

Permalink
Merge pull request #80 from SharePoint/dev
Browse files Browse the repository at this point in the history
Merge for v1.4.0 release
  • Loading branch information
estruyf committed May 25, 2018
2 parents 234f653 + 3b6a60b commit 05d6045
Show file tree
Hide file tree
Showing 27 changed files with 481 additions and 17 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Releases

## 1.4.0

**New Controls**

- `SecurityTrimmedControl` control got added [#74](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/74)

**Enhancements**

- Allow the `TaxonomyPicker` to also be used in Application Customizer [#77](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/77)
- Add `npm postinstall` script to automatically add the locale config [#78](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/78)

**Fixes**

- Icon not showing up in the `Placeholder` control [#76](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/76)

## 1.3.0

**New Controls**
Expand Down
15 changes: 15 additions & 0 deletions docs/documentation/docs/about/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Releases

## 1.4.0

**New Controls**

- `SecurityTrimmedControl` control got added [#74](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/74)

**Enhancements**

- Allow the `TaxonomyPicker` to also be used in Application Customizer [#77](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/77)
- Add `npm postinstall` script to automatically add the locale config [#78](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/78)

**Fixes**

- Icon not showing up in the `Placeholder` control [#76](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/76)

## 1.3.0

**New Controls**
Expand Down
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.
71 changes: 71 additions & 0 deletions docs/documentation/docs/controls/ListPicker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# ListPicker control

This control allows you to select one or multiple available lists/libraries of the current site.

Here is an example of the control:

![ListPicker initial](../assets/ListPicker-initial.png)

`ListPicker` single selection mode:

![ListPicker single selection](../assets/ListPicker-single.png)

`ListPicker` multi-selection mode

![ListPicker multi selection](../assets/ListPicker-multi.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 { ListPicker } from "@pnp/spfx-controls-react/lib/ListPicker";
```

- Use the `ListPicker` control in your code as follows:

```TypeScript
<ListPicker context={this.props.context}
label="Select your list(s)"
placeHolder="Select your list(s)"
baseTemplate={100}
includeHidden={false}
multiSelect={false}
onSelectionChanged={this.onListPickerChange} />
```

- The `onSelectionChanged` change event returns the list(s) and can be implemented as follows:

```TypeScript
private onListPickerChange (lists: string | string[]) {
console.log("Lists:", lists);
}
```

## Implementation

The `ListPicker` control can be configured with the following properties:

| Property | Type | Required | Description |
| ---- | ---- | ---- | ---- |
| context | WebPartContext OR ApplicationCustomizerContext | yes | The context object of the SPFx loaded webpart or customizer. |
| className | string | no | If provided, additional class name to provide on the dropdown element. |
| disabled | boolean | no | Whether or not the control is disabled. |
| baseTemplate | number | no | The SharePoint BaseTemplate ID to filter the list options by. |
| includeHidden | boolean | no | Whether or not to include hidden lists. Default is `true`. |
| orderBy | LibsOrderBy | no | How to order the lists retrieved from SharePoint. |
| selectedList | string OR string[] | no | Keys of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. |
| multiSelect | boolean | no | Optional mode indicates if multi-choice selections is allowed. Default to `false`. |
| label | string | no | Label to use for the control. |
| placeholder | string | no | Placeholder label to show in the dropdown. |
| onSelectionChanged | (newValue: string OR string[]): void | no | Callback function when the selected option changes. |

Enum `LibsOrderBy`

| Value |
| ---- |
| Id |
| Title |

![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/ListPicker)
72 changes: 72 additions & 0 deletions docs/documentation/docs/controls/SecurityTrimmedControl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# SecurityTrimmedControl

This control is intended to be used when you want to show or hide components based on the user its permissions. The control can be used to check the user’s permissions on the current site / list were the solution is loaded, or on a remote site / list.

## 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 following modules to your component:

```TypeScript
import { SecurityTrimmedControl } from "@pnp/spfx-controls-react/lib/SecurityTrimmedControl";
```

- You can use the `SecurityTrimmedControl` as follows in your solutions:

**Checking permissions on the current site**

```jsx
<SecurityTrimmedControl context={this.props.context}
level={PermissionLevel.currentWeb}
permissions={[SPPermission.viewPages]}>
{/* Specify the components to load when user has the required permissions */}
</SecurityTrimmedControl>
```

**Checking permissions on the current list**

```jsx
<SecurityTrimmedControl context={this.props.context}
level={PermissionLevel.currentList}
permissions={[SPPermission.addListItems]}>
{/* Specify the components to load when user has the required permissions */}
</SecurityTrimmedControl>
```

**Checking permissions on remote site**

```jsx
<SecurityTrimmedControl context={this.props.context}
level={PermissionLevel.remoteWeb}
remoteSiteUrl="https://<tenant>.sharepoint.com/sites/<siteName>"
permissions={[SPPermission.viewPages, SPPermission.addListItems]}>
{/* Specify the components to load when user has the required permissions */}
</SecurityTrimmedControl>
```

**Checking permissions on remote list / library**

```jsx
<SecurityTrimmedControl context={this.props.context}
level={PermissionLevel.remoteListOrLib}
remoteSiteUrl="https://<tenant>.sharepoint.com/sites/<siteName>"
relativeLibOrListUrl="/sites/<siteName>/<list-or-library-URL>"
permissions={[SPPermission.addListItems]}>
{/* Specify the components to load when user has the required permissions */}
</SecurityTrimmedControl>
```

## Implementation

The `SecurityTrimmedControl` can be configured with the following properties:

| Property | Type | Required | Description |
| ---- | ---- | ---- | ---- |
| context | WebPartContext or ApplicationCustomizerContext or FieldCustomizerContext or ListViewCommandSetContext | yes | Context of the web part, application customizer, field customizer, or list view command set. |
| permissions | SPPermission[] | yes | The permissions to check for the user. |
| level | PermissionLevel | yes | Specify where to check the user permissions: current site or list / remote site or list. |
| remoteSiteUrl | string | no | The URL of the remote site. Required when you want to check permissions on remote site or list. |
| relativeLibOrListUrl | string | no | The relative URL of the list or library. Required when you want to check permissions on remote list. |


![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/SecurityTrimmedControl)
10 changes: 5 additions & 5 deletions docs/documentation/docs/controls/TaxonomyPicker.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Taxonomy Picker

This control Allows you to select one or more Terms from a TermSet via its name or TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the AnchorId.
This control allows you to select one or more Terms from a TermSet via its name or TermSet ID. You can also configure the control to select the child terms from a specific term in the TermSet by setting the AnchorId.

!!! note "Disclaimer"
This control makes use of the `ProcessQuery` API end-points to retrieve the managed metadata information. This will get changed once the APIs for managing managed metadata will become available.
Expand All @@ -11,15 +11,15 @@ This control Allows you to select one or more Terms from a TermSet via its name

**Selecting terms**

![Selecting terms](../assets/termpicker-selection.png)
![Selecting terms](../assets/termPicker-tree-selection.png)

**Selected terms in picker**

![Selected terms in the input](../assets/termpicker-selected-terms.png)

**Term picker: Auto Complete**

![Selected terms in the input](../assets/termpicker-autocomplete.png)
![Selected terms in the input](../assets/termpicker-input-autocomplete.png)


## How to use this control in your solutions
Expand All @@ -36,7 +36,7 @@ import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/Taxon
```TypeScript
<TaxonomyPicker
allowMultipleSelections={true}
TermSetNameOrID="Countries"
termsetNameOrID="Countries"
panelTitle="Select Term"
label="Taxonomy Picker"
context={this.props.context}
Expand Down Expand Up @@ -65,7 +65,7 @@ The TaxonomyPicker control can be configured with the following properties:
| context | WebPartContext | yes | Context of the current web part. |
| initialValues | IPickerTerms | no | Defines the selected by default term sets. |
| allowMultipleSelections | boolean | no | Defines if the user can select only one or many term sets. Default value is false. |
| TermSetNameOrID | string | yes | The name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from. |
| termsetNameOrID | string | yes | The name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from. |
| onChange | function | no | captures the event of when the terms in the picker has changed. |
| isTermSetSelectable | boolean | no | Specify if the TermSet itself is selectable in the tree view. |
| anchorId | string | no | Set the anchorid to a child term in the TermSet to be able to select terms from that level and below. |
Expand Down
3 changes: 3 additions & 0 deletions docs/documentation/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ npm install @pnp/spfx-controls-react --save --save-exact

### Configuration

!!! note
Since `v1.4.0` the localized resource path will automatically be configured during the dependency installing.

Once the package is installed, you will have to configure the resource file of the property controls to be used in your project. You can do this by opening the `config/config.json` and adding the following line to the `localizedResources` property:

```json
Expand Down
2 changes: 2 additions & 0 deletions docs/documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ pages:
- Home: 'index.md'
- Controls:
- FileTypeIcon: 'controls/FileTypeIcon.md'
- ListPicker: 'controls/ListPicker.md'
- ListView: 'controls/ListView.md'
- "ListView: add a contextual menu": 'controls/ListView.ContextualMenu.md'
- Placeholder: 'controls/Placeholder.md'
- SiteBreadcrumb: 'controls/SiteBreadcrumb.md'
- WebPartTitle: 'controls/WebPartTitle.md'
- SecurityTrimmedControl: 'controls/SecurityTrimmedControl.md'
- TaxonomyPicker: 'controls/TaxonomyPicker.md'
- IFrameDialog: 'controls/IFrameDialog.md'
- 'Field Controls':
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@pnp/spfx-controls-react",
"description": "Reusable React controls for SharePoint Framework solutions",
"version": "1.3.0",
"version": "1.4.0",
"engines": {
"node": ">=0.10.0"
},
Expand All @@ -12,7 +12,8 @@
"prepublishOnly": "gulp",
"versionUpdater": "gulp versionUpdater",
"karma": "karma start --circle true",
"changelog": "node scripts/sync-changelogs.js"
"changelog": "node scripts/sync-changelogs.js",
"postinstall": "node postinstall/install.js"
},
"dependencies": {
"@pnp/common": "^1.0.1",
Expand Down
57 changes: 57 additions & 0 deletions postinstall/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

console.log("INFO: Adding the required localized resource configuration to the config.json file.");

// Get the current directory
const crntDir = path.resolve(__dirname);
// Split the whole directory path
let nesting = crntDir.split("/");
// Windows split
if (nesting.length <= 1) {
nesting = crntDir.split("\\");
}
// Check if correctly splitted
if (nesting.length > 0) {
// Find the first node_modules folder index
let idx = nesting.indexOf("node_modules");
// Check if index of the folder was found
if (idx !== -1) {
// Slice unnecessary nodes
const nest = nesting.slice(idx);
if (nest && nest.length > 0) {
const paths = nest.map(m => "..");
// Get the path of the projects root location
const rootDir = path.resolve(path.join(__dirname, paths.join('/')));
const fileLoc = `${rootDir}/config/config.json`;
// Check if config.json file exists
if (fs.existsSync(fileLoc)) {
// Get the config file
const config = fs.readFileSync(fileLoc, "utf8");
if (config && typeof config === "string") {
const contents = JSON.parse(config);
if (contents && contents.localizedResources && !contents.localizedResources.ControlStrings) {
contents.localizedResources["ControlStrings"] = "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js";
// Update the file
fs.writeFileSync(fileLoc, JSON.stringify(contents, null, 2));
console.log("INFO: Localized resource added.");
} else {
console.warn(`WARNING: it seems something is wrong with the config.json file or the "ControlStrings" reference was already set.`);
}
} else {
console.warn("WARNING: the config.json file was not correctly retrieved.");
}
} else {
console.warn("WARNING: the config.json file does not exist.");
}
} else {
console.warn("WARNING: something is wrong with the installation path.");
}
} else {
console.warn("WARNING: something when wrong during with retrieving the project its root location.");
}
} else {
console.warn("WARNING: something is wrong with the installation path.");
}
1 change: 1 addition & 0 deletions src/SecurityTrimmedControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './controls/securityTrimmedControl';
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class FieldUserRenderer extends React.Component<IFieldUserRendererProps,
if (this._loadedUserProfiles[user.id]) {
return <ul className={styles.sections}>
<li className={styles.section}>
<div className={styles.header}>{strings.Contact} <i className={css('ms-Icon ms-Icon--ChevronRight', styles.chevron)} aria-hidden={'true'}></i></div>
<div className={styles.header}>{strings.Contact} <Icon iconName="ChevronRight" className={styles.chevron} /></div>
<div className={styles.contactItem}>
<Icon iconName={'Mail'}/>
<Link className={styles.content} title={user.email} href={`mailto:${user.email}`} target={'_self'}>{user.email}</Link>
Expand Down
5 changes: 2 additions & 3 deletions src/controls/placeholder/PlaceholderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import styles from './PlaceholderComponent.module.scss';
import * as appInsights from '../../common/appInsights';
import { IPlaceholderState } from '.';
import { Icon } from 'office-ui-fabric-react/lib/components/Icon';

/**
* Placeholder component
Expand Down Expand Up @@ -83,15 +84,13 @@ export class Placeholder extends React.Component<IPlaceholderProps, IPlaceholder
* Default React component render method
*/
public render(): React.ReactElement<IPlaceholderProps> {
const iconName = typeof this.props.iconName !== 'undefined' && this.props.iconName !== null ? `ms-Icon--${this.props.iconName}` : '';

return (
<div className={`${styles.placeholder} ${this.props.contentClassName ? this.props.contentClassName : ''}`} ref={this._linkElm}>
<div className={styles.placeholderContainer}>
<div className={styles.placeholderHead}>
<div className={styles.placeholderHeadContainer}>
{
iconName ? <i className={`${styles.placeholderIcon} ms-fontSize-su ms-Icon ${iconName}`}></i> : ''
this.props.iconName && <Icon iconName={this.props.iconName} className={`${styles.placeholderIcon} ms-fontSize-su ms-Icon`} />
}
<span className={`${styles.placeholderText} ms-fontWeight-light ms-fontSize-xxl ${(this.state.width && this.state.width <= 380) ? styles.hide : "" }`}>{this.props.iconText}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ApplicationCustomizerContext } from '@microsoft/sp-application-base';
import { FieldCustomizerContext, ListViewCommandSetContext } from '@microsoft/sp-listview-extensibility';
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { SPPermission } from '@microsoft/sp-page-context';
import { PermissionLevel } from '.';

export interface ISecurityTrimmedControlProps {
/**
* Context of the web part, application customizer, field customizer, or list view command set.
*/
context: WebPartContext | ApplicationCustomizerContext | FieldCustomizerContext | ListViewCommandSetContext;
/**
* The permissions to check for the user.
*/
permissions: SPPermission[];
/**
* Specify where to check the user permissions: current site or list / remote site or list.
*/
level: PermissionLevel;
/**
* The URL of the remote site. Required when you want to check permissions on remote site or list.
*/
remoteSiteUrl?: string;
/**
* The relative URL of the list or library. Required when you want to check permissions on remote list.
*/
relativeLibOrListUrl?: string;
}
Loading

0 comments on commit 05d6045

Please sign in to comment.