Skip to content

Commit

Permalink
Merge pull request #54 from SharePoint/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
estruyf authored Mar 28, 2018
2 parents 90d982c + d8dc76a commit eb68fb6
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 56 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Releases

## 1.2.4

**Enhancements**
- Hiding placeholder web part on small zones

**Fixes**
- iFrame dialog reference fix [#52 - Need some more implementation documentation on IFrameDialog](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/52)

## 1.2.3

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

## 1.2.4

**Enhancements**
- Hiding placeholder web part on small zones

**Fixes**
- iFrame dialog reference fix [#52 - Need some more implementation documentation on IFrameDialog](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/52)

## 1.2.3

**Enhancements**
Expand Down
2 changes: 1 addition & 1 deletion docs/documentation/docs/controls/IFrameDialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Here is an example of the control in action:
import { IFrameDialog } from "@pnp/spfx-controls-react/lib/IFrameDialog";
```

- Use the `IFrameDialog` control in your code as follows:
- Use the `IFrameDialog` control in your code as follows (`this._onIframeLoaded` and `this._onDialogDismiss` are methods that should be implemented if you want to execute some actions when the iframe content is loaded and dialog should be closed respectively):

```TypeScript
<IFrameDialog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { FieldLookupRenderer } from "@pnp/spfx-controls-react/lib/FieldLookupRen
- Use the `FieldLookupRenderer` control in your code as follows:

```TypeScript
<FieldLookupRenderer lookups={event.fieldValue} dispFormUrl={'https://contoso.sharepoint.com/_layouts/15/listform.aspx?PageType=4&ListId={list_id}'} className={'some-class'} cssProps={{ background: '#f00' }} />
<FieldLookupRenderer lookups={event.fieldValue} fieldId={'<field-guid>'} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
```

## Implementation
Expand All @@ -36,6 +36,8 @@ The FieldLookupRenderer component can be configured with the following propertie
| lookups | ISPFieldLookupValue[] | yes | Lookup field values. |
| dispFormUrl | boolean | no | Url of Display form for the list that is referenced by the lookup. |
| onClick | (args: ILookupClickEventArgs) => {} | no | Custom event handler of lookup item click. If not set the dialog with Display Form will be shown. |
| fieldId | string | Field's id |
| context | IContext | Customizer context. Must be providede if fieldId is set |

![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/fields/FieldLookupRenderer)

2 changes: 1 addition & 1 deletion docs/documentation/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ npm install @pnp/spfx-controls-react --save --save-exact
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
"ControlStrings": "./node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
```

## Available controls
Expand Down
2 changes: 1 addition & 1 deletion 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.2.3",
"version": "1.2.4",
"engines": {
"node": ">=0.10.0"
},
Expand Down
23 changes: 12 additions & 11 deletions src/common/utilities/FieldRendererHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { SPField } from '@microsoft/sp-page-context';
import { IContext } from '../Interfaces';
import { GeneralHelper } from './GeneralHelper';
import { FieldLookupRenderer, IFieldLookupClickEventArgs } from '../../controls/fields/fieldLookupRenderer/FieldLookupRenderer';
import IFrameDialog from '../../controls/iFrameDialog/IFrameDialog';
import { FieldUrlRenderer } from '../../controls/fields/fieldUrlRenderer/FieldUrlRenderer';
import { FieldTaxonomyRenderer } from '../../controls/fields/fieldTaxonomyRenderer/FieldTaxonomyRenderer';
import { IFieldRendererProps } from '../../controls/fields/fieldCommon/IFieldRendererProps';
Expand Down Expand Up @@ -132,16 +131,18 @@ export class FieldRendererHelper {
break;
case "Lookup":
case "LookupMulti":
SPHelper.getLookupFieldListDispFormUrl(field.id.toString(), context).then(dispFormUrlValue => {
const lookupValues = fieldValue as ISPFieldLookupValue[];
const dispFormUrl: string = dispFormUrlValue.toString();
resolve(React.createElement(FieldLookupRenderer, {
lookups: lookupValues,
dispFormUrl: dispFormUrl,
...props
}));
});

//
// we're providing fieldId and context. In that case Lookup values will be rendered right away
// without additional lag of waiting of response to get dispUrl.
// The request for DispUrl will be sent only if user click on the value
//
const lookupValues = fieldValue as ISPFieldLookupValue[];
resolve(React.createElement(FieldLookupRenderer, {
lookups: lookupValues,
fieldId: field.id.toString(),
context: context,
...props
}));
break;
case 'URL':
SPHelper.getFieldProperty(field.id.toString(), 'Format', context, true).then(format => {
Expand Down
103 changes: 78 additions & 25 deletions src/controls/fields/fieldLookupRenderer/FieldLookupRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { override } from '@microsoft/decorators';
import * as React from 'react';
import { css, DialogType, Link } from 'office-ui-fabric-react';
import { css, Dialog, DialogType, Link, Spinner, SpinnerSize } from 'office-ui-fabric-react';

import { ISPFieldLookupValue } from "../../../common/SPEntities";
import { IFieldRendererProps } from '../fieldCommon/IFieldRendererProps';
import * as appInsights from '../../../common/appInsights';

import styles from './FieldLookupRenderer.module.scss';
import IFrameDialog from '../../iFrameDialog/IFrameDialog';
import { IFrameDialog } from '../../iFrameDialog/IFrameDialog';
import { SPHelper } from '../../../Utilities';
import { IContext } from '../../../Common';

/**
* Field Lookup Renderer Props
* There are 3 options to provide the props:
* - [recommended, used in FieldRendererHelper] Provide fieldId and context. In that case request for DispUrl will be sent only if a user clicks on the value
* - Provide dispFormUrl: if you know this URL a priori you can provide it into the renderer
* - Provide onClick handler to handle value's click event outside the renderer
*/
export interface IFieldLookupRendererProps extends IFieldRendererProps {
/**
* lookup values
Expand All @@ -22,14 +31,23 @@ export interface IFieldLookupRendererProps extends IFieldRendererProps {
* custom event handler of lookup item click. If not set the dialog with Display Form will be shown
*/
onClick?: (args: IFieldLookupClickEventArgs) => {};
/**
* Field's id.
*/
fieldId?: string;
/**
* Customizer context. Must be providede if fieldId is set
*/
context?: IContext;
}

/**
* For future
* Field Lookup Renderer State
*/
export interface IFieldLookupRendererState {
hideDialog?: boolean;
lookupDispFormUrl?: string;
dispFormUrl?: string;
}

/**
Expand All @@ -51,7 +69,8 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
appInsights.track('FieldLookupRenderer', {});

this.state = {
hideDialog: true
hideDialog: true,
dispFormUrl: props.dispFormUrl
};
}

Expand All @@ -61,23 +80,35 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
return <Link onClick={this._onClick.bind(this, lookup)} className={styles.lookup} style={this.props.cssProps}>{lookup.lookupValue}</Link>;
});
return (
<div style={this.props.cssProps} className={css(this.props.className)}>{lookupLinks}
{!this.state.hideDialog && <IFrameDialog
url={this.state.lookupDispFormUrl}
iframeOnLoad={this._onIframeLoaded.bind(this)}
hidden={this.state.hideDialog}
onDismiss={this._onDialogDismiss.bind(this)}
modalProps={{
isBlocking: true,
containerClassName: styles.dialogContainer
}}
dialogContentProps={{
type: DialogType.close,
showCloseButton: true
}}
width={'570px'}
height={'315px'}/>}
</div>);
<div style={this.props.cssProps} className={css(this.props.className)}>{lookupLinks}
{!this.state.hideDialog && this.state.dispFormUrl && <IFrameDialog
url={this.state.lookupDispFormUrl}
iframeOnLoad={this._onIframeLoaded.bind(this)}
hidden={this.state.hideDialog}
onDismiss={this._onDialogDismiss.bind(this)}
modalProps={{
isBlocking: true,
containerClassName: styles.dialogContainer
}}
dialogContentProps={{
type: DialogType.close,
showCloseButton: true
}}
width={'570px'}
height={'315px'} />}
{!this.state.hideDialog && !this.state.dispFormUrl && <Dialog
onDismiss={this._onDialogDismiss.bind(this)}
modalProps={{
isBlocking: true,
containerClassName: styles.dialogContainer
}}
dialogContentProps={{
type: DialogType.close,
showCloseButton: true
}}>
<Spinner size={SpinnerSize.large} />
</Dialog>}
</div>);
}

private _onClick(lookup: ISPFieldLookupValue): void {
Expand All @@ -92,10 +123,32 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
//
// showing Display Form in the dialog
//
this.setState({
lookupDispFormUrl: `${this.props.dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`,
hideDialog: false
});
if (this.state.dispFormUrl) {
this.setState({
lookupDispFormUrl: `${this.state.dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`,
hideDialog: false
});
}
else if (this.props.fieldId) {

this.setState({
hideDialog: false
});

SPHelper.getLookupFieldListDispFormUrl(this.props.fieldId, this.props.context).then(dispFormUrlValue => {
const dispFormUrl: string = dispFormUrlValue.toString();
this.setState((prevState, props) => {
if (prevState.hideDialog) {
return;
}

return {
dispFormUrl: dispFormUrl,
lookupDispFormUrl: `${dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`
};
});
});
}
}

private _onIframeLoaded(iframe: any): void {
Expand Down
6 changes: 3 additions & 3 deletions src/controls/iFrameDialog/IFrameDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Dialog, IDialogProps } from 'office-ui-fabric-react';
import IFrameDialogContent from './IFrameDialogContent';
import { IFrameDialogContent } from './IFrameDialogContent';
import * as appInsights from '../../common/appInsights';

export interface IFrameDialogProps extends IDialogProps {
Expand All @@ -12,7 +12,7 @@ export interface IFrameDialogProps extends IDialogProps {
/**
* iframe's onload event handler
*/
iframeOnLoad?: (iframe: any) => {};
iframeOnLoad?: (iframe: any) => void;
/**
* iframe width
*/
Expand All @@ -29,7 +29,7 @@ export interface IFrameDialogState {
/**
* Dialog component to display content in iframe
*/
export default class IFrameDialog extends React.Component<IFrameDialogProps, IFrameDialogState> {
export class IFrameDialog extends React.Component<IFrameDialogProps, IFrameDialogState> {

public constructor(props: IFrameDialogProps, state: IFrameDialogState) {
super(props, state);
Expand Down
4 changes: 2 additions & 2 deletions src/controls/iFrameDialog/IFrameDialogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import styles from './IFrameDialogContent.module.scss';
export interface IIFrameDialogContentProps {
url: string;
close: () => void;
iframeOnLoad?: (iframe: any) => {};
iframeOnLoad?: (iframe: any) => void;
width: string;
height: string;
}

/**
* IFrame Dialog content
*/
export default class IFrameDialogContent extends React.Component<IIFrameDialogContentProps, {}> {
export class IFrameDialogContent extends React.Component<IIFrameDialogContentProps, {}> {
private _iframe: any;

constructor(props: IIFrameDialogContentProps) {
Expand Down
4 changes: 4 additions & 0 deletions src/controls/placeholder/IPlaceholderComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ export interface IPlaceholderProps {
*/
contentClassName?: string;
}

export interface IPlaceholderState {
width: number;
}
8 changes: 6 additions & 2 deletions src/controls/placeholder/PlaceholderComponent.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@
}

.placeholderText {
display: inline-block;
display: inline;
vertical-align: middle;
white-space: normal
white-space: normal;

&.hide {
display: none;
}
}
}

Expand Down
Loading

0 comments on commit eb68fb6

Please sign in to comment.