Merge pull request #1818 from chandaniprajapati/react-datatable-profilepic
react-datatable: Added feature to show profile picture of user column
This commit is contained in:
commit
2eff0055bb
|
@ -43,6 +43,7 @@ Version|Date|Comments
|
||||||
1.1|February 24, 2021|Added support for large lists
|
1.1|February 24, 2021|Added support for large lists
|
||||||
1.2|March 01, 2021|Fixed search issue for number field
|
1.2|March 01, 2021|Fixed search issue for number field
|
||||||
1.3|March 31,2021| Changed UI as per SharePoint list, Set themeing as per current SharePoint site theme, Created custom pagination by using reusable controls, Added features to export CSV based on the filter if the filter is available, Added hyperlink feature for image and link column in export to pdf and also set alternative row formatting in generated pdf as per property pane configuration odd/even row color, fixed object issue (for people/hyperlink, etc) in export to CSV.
|
1.3|March 31,2021| Changed UI as per SharePoint list, Set themeing as per current SharePoint site theme, Created custom pagination by using reusable controls, Added features to export CSV based on the filter if the filter is available, Added hyperlink feature for image and link column in export to pdf and also set alternative row formatting in generated pdf as per property pane configuration odd/even row color, fixed object issue (for people/hyperlink, etc) in export to CSV.
|
||||||
|
1.4|April 10, 2021|Added feature to show profile picture in user column and shows display name of user field in export to CSV and PDF.
|
||||||
|
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 48 KiB |
|
@ -9,7 +9,7 @@
|
||||||
"This web part provides easy way to render SharePoint custom list in data table view with all the necessary features."
|
"This web part provides easy way to render SharePoint custom list in data table view with all the necessary features."
|
||||||
],
|
],
|
||||||
"created": "2021-03-01",
|
"created": "2021-03-01",
|
||||||
"modified": "2021-03-01",
|
"modified": "2021-04-10",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
@ -49,4 +49,4 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
export function csvCellFormatter(value: any, type: string) {
|
export function csvCellFormatter(value: any, type: string) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return value;
|
|
||||||
}
|
|
||||||
switch (type) {
|
|
||||||
case 'SP.FieldUrl':
|
|
||||||
value = value.props.children;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
switch (type) {
|
||||||
|
case 'SP.FieldUrl':
|
||||||
|
value = value.props.children;
|
||||||
|
break;
|
||||||
|
case 'SP.FieldUser':
|
||||||
|
value = value.props.displayName;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
export function pdfCellFormatter(value: any, type: string) {
|
export function pdfCellFormatter(value: any, type: string) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return value;
|
|
||||||
}
|
|
||||||
switch (type) {
|
|
||||||
case 'SP.FieldUrl':
|
|
||||||
let { children: text, href: link } = value.props;
|
|
||||||
value = { text, link, color: 'blue' };
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
switch (type) {
|
||||||
|
case 'SP.FieldUrl':
|
||||||
|
let { children: text, href: link } = value.props;
|
||||||
|
value = { text, link, color: 'blue' };
|
||||||
|
break;
|
||||||
|
case 'SP.FieldUser':
|
||||||
|
value = value.props.displayName;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Persona, PersonaSize } from 'office-ui-fabric-react/lib/Persona';
|
||||||
|
|
||||||
|
interface IProfilePicProps {
|
||||||
|
loginName: string;
|
||||||
|
displayName: string;
|
||||||
|
getUserProfileUrl: () => Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RenderProfilePicture(props: IProfilePicProps) {
|
||||||
|
|
||||||
|
const [profileUrl, setProfileUrl] = React.useState<string>();
|
||||||
|
let { displayName, getUserProfileUrl } = props;
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
getUserProfileUrl().then(url => {
|
||||||
|
setProfileUrl(url);
|
||||||
|
});
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Persona
|
||||||
|
imageUrl={profileUrl}
|
||||||
|
text={displayName}
|
||||||
|
size={PersonaSize.size32}
|
||||||
|
imageAlt={displayName}
|
||||||
|
styles={{ primaryText: { fontSize: '12px' } }}
|
||||||
|
/>);
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ export class SPService {
|
||||||
for (var i = 0; i < selectedFields.length; i++) {
|
for (var i = 0; i < selectedFields.length; i++) {
|
||||||
switch (selectedFields[i].fieldType) {
|
switch (selectedFields[i].fieldType) {
|
||||||
case 'SP.FieldUser':
|
case 'SP.FieldUser':
|
||||||
selectQuery.push(`${selectedFields[i].key}/Title,${selectedFields[i].key}/Name`);
|
selectQuery.push(`${selectedFields[i].key}/Title,${selectedFields[i].key}/EMail,${selectedFields[i].key}/Name`);
|
||||||
expandQuery.push(selectedFields[i].key);
|
expandQuery.push(selectedFields[i].key);
|
||||||
break;
|
break;
|
||||||
case 'SP.FieldLookup':
|
case 'SP.FieldLookup':
|
||||||
|
@ -63,9 +63,10 @@ export class SPService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getUserProfileUrl(loginName: string, propertyName: string) {
|
public async getUserProfileUrl(loginName: string) {
|
||||||
try {
|
try {
|
||||||
const profileUrl = await sp.profiles.getUserProfilePropertyFor(loginName, propertyName);
|
const properties = await sp.profiles.getPropertiesFor(loginName);
|
||||||
|
const profileUrl = properties['PictureUrl'];
|
||||||
return profileUrl;
|
return profileUrl;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { DetailsList, DetailsListLayoutMode, DetailsRow, IDetailsRowStyles, IDet
|
||||||
import { pdfCellFormatter } from '../../../shared/common/ExportListItemsToPDF/ExportListItemsToPDFFormatter';
|
import { pdfCellFormatter } from '../../../shared/common/ExportListItemsToPDF/ExportListItemsToPDFFormatter';
|
||||||
import { csvCellFormatter } from '../../../shared/common/ExportListItemsToCSV/ExportListItemsToCSVFormatter';
|
import { csvCellFormatter } from '../../../shared/common/ExportListItemsToCSV/ExportListItemsToCSVFormatter';
|
||||||
import { IPropertyPaneDropdownOption } from '@microsoft/sp-property-pane';
|
import { IPropertyPaneDropdownOption } from '@microsoft/sp-property-pane';
|
||||||
|
import { RenderProfilePicture } from '../../../shared/common/RenderProfilePicture/RenderProfilePicture';
|
||||||
|
|
||||||
export default class ReactDatatable extends React.Component<IReactDatatableProps, IReactDatatableState> {
|
export default class ReactDatatable extends React.Component<IReactDatatableProps, IReactDatatableState> {
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
this.getSelectedListItems();
|
this.getSelectedListItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getUserProfileUrl = (loginName: string) => {
|
||||||
|
return this._services.getUserProfileUrl(loginName)
|
||||||
|
}
|
||||||
|
|
||||||
public componentDidUpdate(prevProps: IReactDatatableProps) {
|
public componentDidUpdate(prevProps: IReactDatatableProps) {
|
||||||
if (prevProps.list !== this.props.list) {
|
if (prevProps.list !== this.props.list) {
|
||||||
this.props.onChangeProperty("list");
|
this.props.onChangeProperty("list");
|
||||||
|
@ -82,7 +86,7 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
private _onConfigure() {
|
private _onConfigure() {
|
||||||
this.props.context.propertyPane.open();
|
this.props.context.propertyPane.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public formatColumnValue(value: any, type: string) {
|
public formatColumnValue(value: any, type: string) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -102,7 +106,9 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
value = value['Title'];
|
value = value['Title'];
|
||||||
break;
|
break;
|
||||||
case 'SP.FieldUser':
|
case 'SP.FieldUser':
|
||||||
value = value['Title'];
|
let loginName = value['Name'];
|
||||||
|
let userName = value['Title'];
|
||||||
|
value = <RenderProfilePicture loginName={loginName} displayName={userName} getUserProfileUrl={() => this.getUserProfileUrl(loginName)} ></RenderProfilePicture>;
|
||||||
break;
|
break;
|
||||||
case 'SP.FieldMultiLineText':
|
case 'SP.FieldMultiLineText':
|
||||||
value = <div dangerouslySetInnerHTML={{ __html: value }}></div>;
|
value = <div dangerouslySetInnerHTML={{ __html: value }}></div>;
|
||||||
|
@ -124,6 +130,7 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public formatValueForExportingData(value: any, type?: string) {
|
public formatValueForExportingData(value: any, type?: string) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -144,17 +151,17 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private exportDataFormatter(fields: Array<IPropertyPaneDropdownOption & { fieldType: string }>, listItems: any[], cellFormatterFn: (value: any, type: string) => any){
|
private exportDataFormatter(fields: Array<IPropertyPaneDropdownOption & { fieldType: string }>, listItems: any[], cellFormatterFn: (value: any, type: string) => any) {
|
||||||
return listItems && listItems.map(item => ({
|
return listItems && listItems.map(item => ({
|
||||||
...fields.reduce((ob, f) => {
|
...fields.reduce((ob, f) => {
|
||||||
ob[f.text] = item[f.key] ? cellFormatterFn(item[f.key], f.fieldType) : '-';
|
ob[f.text] = item[f.key] ? cellFormatterFn(item[f.key], f.fieldType) : '-';
|
||||||
return ob;
|
return ob;
|
||||||
}, {})
|
}, {})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private handlePaginationChange(pageNo: number, pageSize: number) {
|
private handlePaginationChange(pageNo: number, rowsPerPage: number) {
|
||||||
this.setState({ page: pageNo, rowsPerPage: pageSize });
|
this.setState({ page: pageNo, rowsPerPage: rowsPerPage });
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleSearch(event: React.ChangeEvent<HTMLInputElement>) {
|
public handleSearch(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
@ -257,8 +264,8 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
columnHeader={columns.map(c => c.name)}
|
columnHeader={columns.map(c => c.name)}
|
||||||
listName={list}
|
listName={list}
|
||||||
description={title}
|
description={title}
|
||||||
dataSource={()=> this.exportDataFormatter(fields, filteredItems, csvCellFormatter)}
|
dataSource={() => this.exportDataFormatter(fields, filteredItems, csvCellFormatter)}
|
||||||
/> : <></>}
|
/> : <></>}
|
||||||
{enableDownloadAsPdf
|
{enableDownloadAsPdf
|
||||||
? <ExportListItemsToPDF
|
? <ExportListItemsToPDF
|
||||||
listName={list}
|
listName={list}
|
||||||
|
@ -266,7 +273,7 @@ export default class ReactDatatable extends React.Component<IReactDatatableProps
|
||||||
columns={columns.map(c => c.name)}
|
columns={columns.map(c => c.name)}
|
||||||
oddRowColor={oddRowColor}
|
oddRowColor={oddRowColor}
|
||||||
evenRowColor={evenRowColor}
|
evenRowColor={evenRowColor}
|
||||||
dataSource={()=> this.exportDataFormatter(fields, filteredItems, pdfCellFormatter)} />
|
dataSource={() => this.exportDataFormatter(fields, filteredItems, pdfCellFormatter)} />
|
||||||
: <></>}
|
: <></>}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid container justify='flex-end' xs={6}>
|
<Grid container justify='flex-end' xs={6}>
|
||||||
|
|
Loading…
Reference in New Issue