Upgrade to 1.17.1 and linter changes
This commit is contained in:
parent
2512a1cbed
commit
221117cda9
|
@ -0,0 +1,5 @@
|
||||||
|
require('@rushstack/eslint-config/patch/modern-module-resolution');
|
||||||
|
module.exports = {
|
||||||
|
extends: ['@microsoft/eslint-config-spfx/lib/profiles/react'],
|
||||||
|
parserOptions: { tsconfigRootDir: __dirname }
|
||||||
|
};
|
|
@ -9,9 +9,11 @@ node_modules
|
||||||
# Build generated files
|
# Build generated files
|
||||||
dist
|
dist
|
||||||
lib
|
lib
|
||||||
|
release
|
||||||
solution
|
solution
|
||||||
temp
|
temp
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
.heft
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
!dist
|
||||||
|
config
|
||||||
|
|
||||||
|
gulpfile.js
|
||||||
|
|
||||||
|
release
|
||||||
|
src
|
||||||
|
temp
|
||||||
|
|
||||||
|
tsconfig.json
|
||||||
|
tslint.json
|
||||||
|
|
||||||
|
*.log
|
||||||
|
|
||||||
|
.yo-rc.json
|
||||||
|
.vscode
|
|
@ -1,6 +1,12 @@
|
||||||
{
|
{
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
"version": "1.11.0",
|
"plusBeta": false,
|
||||||
|
"nodeVersion": "18.16.0",
|
||||||
|
"sdksVersions": {
|
||||||
|
"@microsoft/microsoft-graph-client": "3.0.2",
|
||||||
|
"@microsoft/teams-js": "2.9.1"
|
||||||
|
},
|
||||||
|
"version": "1.17.1",
|
||||||
"libraryName": "react-directory",
|
"libraryName": "react-directory",
|
||||||
"libraryId": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
"libraryId": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
|
@ -8,6 +14,9 @@
|
||||||
"framework": "react",
|
"framework": "react",
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
"componentType": "webpart"
|
"componentType": "webpart",
|
||||||
|
"solutionName": "\\",
|
||||||
|
"solutionShortDescription": "\\ description",
|
||||||
|
"skipFeatureDeployment": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ Search People from Organization Directory and show live persona card on hover.
|
||||||
| Every SPFx version is only compatible with specific version(s) of Node.js. In order to be able to build this sample, please ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|
| Every SPFx version is only compatible with specific version(s) of Node.js. In order to be able to build this sample, please ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|
||||||
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
|
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
![SPFx 1.17.1](https://img.shields.io/badge/SPFx-1.17.1-green.svg)
|
||||||
![Node.js v10](https://img.shields.io/badge/Node.js-v10-green.svg)
|
![Node.js v16](https://img.shields.io/badge/Node.js-v16-green.svg)
|
||||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
@ -82,6 +82,7 @@ Version|Date|Comments
|
||||||
3.0.1|March 4 2021|Bugfix 'Sort People by'
|
3.0.1|March 4 2021|Bugfix 'Sort People by'
|
||||||
3.0.2|Oct 3 2022|Minor styling fixes and people container position
|
3.0.2|Oct 3 2022|Minor styling fixes and people container position
|
||||||
3.0.3|Oct 4 2022|Fix for LivePersonaCard
|
3.0.3|Oct 4 2022|Fix for LivePersonaCard
|
||||||
|
3.0.4|Jun 20 2023|Upgrade to SPFx 1.17.1
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
|
||||||
"deployCdnPath": "temp/deploy"
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
"workingDir": "./temp/deploy/",
|
"workingDir": "./release/assets/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "react-directory",
|
"container": "",
|
||||||
"accessKey": "<!-- ACCESS KEY -->"
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,32 @@
|
||||||
},
|
},
|
||||||
"name": "Search Directory",
|
"name": "Search Directory",
|
||||||
"id": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
"id": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
||||||
"version": "3.0.3.0",
|
"version": "3.0.4.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false,
|
||||||
|
"metadata": {
|
||||||
|
"shortDescription": {
|
||||||
|
"default": "react-directory description"
|
||||||
|
},
|
||||||
|
"longDescription": {
|
||||||
|
"default": "react-directory description"
|
||||||
|
},
|
||||||
|
"screenshotPaths": [],
|
||||||
|
"videoUrl": "",
|
||||||
|
"categories": []
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"title": "react-directory DirectoryWebPart Feature",
|
||||||
|
"description": "The feature that activates DirectoryWebPart from the react-directory solution.",
|
||||||
|
"id": "fae479bf-405f-4f80-a086-eea22eff3d6f",
|
||||||
|
"version": "3.0.4.0",
|
||||||
|
"componentIds": [
|
||||||
|
"fae479bf-405f-4f80-a086-eea22eff3d6f"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-directory.sppkg"
|
"zippedPackage": "solution/react-directory.sppkg"
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json"
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
|
||||||
"port": 4321,
|
"port": 4321,
|
||||||
"https": true,
|
"https": true,
|
||||||
"initialPage": "https://localhost:5432/workbench",
|
"initialPage": "https://{tenantDomain}/_layouts/workbench.aspx",
|
||||||
"api": {
|
|
||||||
"port": 5432,
|
|
||||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// check if gulp dist was called
|
|
||||||
if (process.argv.indexOf('dist') !== -1) {
|
|
||||||
// add ship options to command call
|
|
||||||
process.argv.push('--ship');
|
|
||||||
}
|
|
||||||
|
|
||||||
const path = require('path');
|
|
||||||
const gulp = require('gulp');
|
|
||||||
const build = require('@microsoft/sp-build-web');
|
const build = require('@microsoft/sp-build-web');
|
||||||
const gulpSequence = require('gulp-sequence');
|
|
||||||
|
|
||||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
// Create clean distrubution package
|
var getTasks = build.rig.getTasks;
|
||||||
gulp.task('dist', gulpSequence('clean', 'bundle', 'package-solution'));
|
build.rig.getTasks = function () {
|
||||||
// Create clean development package
|
var result = getTasks.call(build.rig);
|
||||||
gulp.task('dev', gulpSequence('clean', 'bundle', 'package-solution'));
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom Framework Specific gulp tasks
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
build.initialize(require('gulp'));
|
||||||
build.initialize(gulp);
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,63 +1,48 @@
|
||||||
{
|
{
|
||||||
"name": "react-directory",
|
"name": "react-directory",
|
||||||
"version": "2.0.0",
|
"version": "3.0.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=16.13.0 <17.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp bundle",
|
"build": "gulp bundle",
|
||||||
"clean": "gulp clean",
|
"clean": "gulp clean",
|
||||||
"preversion": "node ./tools/pre-version.js",
|
"preversion": "node ./tools/pre-version.js",
|
||||||
"postversion": "gulp dist",
|
"postversion": "gulp dist",
|
||||||
"test": "./node_modules/.bin/jest --config ./config/jest.config.json",
|
"test": "gulp test"
|
||||||
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.11.0",
|
"@microsoft/sp-core-library": "1.17.1",
|
||||||
"@microsoft/sp-lodash-subset": "1.11.0",
|
"@microsoft/sp-lodash-subset": "1.17.1",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.17.1",
|
||||||
"@microsoft/sp-property-pane": "1.16.1",
|
"@microsoft/sp-property-pane": "1.17.1",
|
||||||
"@microsoft/sp-webpart-base": "1.16.1",
|
"@microsoft/sp-webpart-base": "1.17.1",
|
||||||
"@pnp/pnpjs": "^1.3.3",
|
"@pnp/sp": "2.5.0",
|
||||||
"@pnp/spfx-controls-react": "1.13.2",
|
"@pnp/spfx-controls-react": "3.14.0",
|
||||||
"@pnp/spfx-property-controls": "1.15.0",
|
"@pnp/spfx-property-controls": "^3.13.0",
|
||||||
"@types/jquery": "^3.3.30",
|
"react": "17.0.1",
|
||||||
"@uifabric/fluent-theme": "^0.16.9",
|
"react-dom": "17.0.1",
|
||||||
"jquery": "^3.5.0",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"office-ui-fabric-react": "6.214.0",
|
|
||||||
"react": "16.7.0",
|
|
||||||
"react-dom": "16.7.0",
|
|
||||||
"react-js-pagination": "^3.0.3",
|
"react-js-pagination": "^3.0.3",
|
||||||
"throttle-debounce": "^2.3.0"
|
"throttle-debounce": "^5.0.0",
|
||||||
},
|
"tslib": "2.3.1"
|
||||||
"resolutions": {
|
|
||||||
"@types/react": "16.8.8"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
"@microsoft/eslint-config-spfx": "1.17.1",
|
||||||
"@microsoft/sp-build-web": "1.16.1",
|
"@microsoft/eslint-plugin-spfx": "1.17.1",
|
||||||
"@microsoft/sp-module-interfaces": "1.11.0",
|
"@microsoft/rush-stack-compiler-4.5": "0.2.2",
|
||||||
"@microsoft/sp-tslint-rules": "1.11.0",
|
"@microsoft/sp-build-web": "1.17.1",
|
||||||
"@microsoft/sp-webpart-workbench": "1.12.1",
|
"@microsoft/sp-module-interfaces": "1.17.1",
|
||||||
"@types/chai": "3.4.34",
|
"@rushstack/eslint-config": "2.5.1",
|
||||||
"@types/es6-promise": "0.0.33",
|
"@types/react": "17.0.45",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/react-dom": "17.0.17",
|
||||||
"@types/react": "16.8.8",
|
"@types/react-js-pagination": "^3.0.4",
|
||||||
"@types/react-dom": "16.8.3",
|
"@types/throttle-debounce": "^5.0.0",
|
||||||
"@types/webpack-env": "1.13.1",
|
"@types/webpack-env": "~1.15.2",
|
||||||
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
"ajv": "^6.12.5",
|
||||||
"ajv": "~6.12.3",
|
"eslint": "8.7.0",
|
||||||
"gulp": "~4.0.2",
|
"eslint-plugin-react-hooks": "4.3.0",
|
||||||
"gulp-sequence": "1.0.0",
|
"gulp": "4.0.2"
|
||||||
"jest": "^29.3.1",
|
|
||||||
"jest-junit": "^6.3.0",
|
|
||||||
"typescript": "~3.3.x"
|
|
||||||
},
|
|
||||||
"jest-junit": {
|
|
||||||
"output": "temp/test/junit/junit.xml",
|
|
||||||
"usePathForSuiteName": "true"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,8 +1,9 @@
|
||||||
import { PeoplePickerEntity } from '@pnp/sp';
|
import { SearchResults } from '@pnp/sp/search';
|
||||||
|
|
||||||
|
|
||||||
export interface ISPServices {
|
export interface ISPServices {
|
||||||
|
|
||||||
searchUsers(searchString: string, searchFirstName: boolean);
|
searchUsers(searchString: string, searchFirstName: boolean): Promise<SearchResults>;
|
||||||
searchUsersNew(searchString: string, srchQry: string, isInitialSearch: boolean, pageNumber?: number);
|
searchUsersNew(searchString: string, srchQry: string, isInitialSearch: boolean): Promise<SearchResults>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
{
|
|
||||||
"odata.metadata": "https://contoso.sharepoint.com/_api/$metadata#Microsoft.Office.Server.Search.REST.SearchResult",
|
|
||||||
"ElapsedTime": 34,
|
|
||||||
"PrimaryQueryResult": {
|
|
||||||
"CustomResults": [],
|
|
||||||
"QueryId": "70699796-a977-4437-b771-92a074e322e6",
|
|
||||||
"QueryRuleId": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"RefinementResults": null,
|
|
||||||
"RelevantResults": {
|
|
||||||
"GroupTemplateId": null,
|
|
||||||
"ItemTemplateId": null,
|
|
||||||
"Properties": [],
|
|
||||||
"ResultTitle": null,
|
|
||||||
"ResultTitleUrl": null,
|
|
||||||
"RowCount": 1,
|
|
||||||
"Table": {
|
|
||||||
"Rows": [{
|
|
||||||
"Cells": [{
|
|
||||||
"Key": "Rank",
|
|
||||||
"Value": "0",
|
|
||||||
"ValueType": "Edm.Double"
|
|
||||||
}, {
|
|
||||||
"Key": "DocId",
|
|
||||||
"Value": "17646696630634",
|
|
||||||
"ValueType": "Edm.Int64"
|
|
||||||
}, {
|
|
||||||
"Key": "FirstName",
|
|
||||||
"Value": "Peter Paul",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "LastName",
|
|
||||||
"Value": "Kirschner",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "PreferredName",
|
|
||||||
"Value": "Peter Paul Kirschner",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "WorkEmail",
|
|
||||||
"Value": "petkir@pkirschner.onmicrosoft.com",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "OfficeNumber",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "PictureURL",
|
|
||||||
"Value": "",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "WorkPhone",
|
|
||||||
"Value": "4250000000",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "MobilePhone",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "JobTitle",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "Department",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "Skills",
|
|
||||||
"Value": "",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "PastProjects",
|
|
||||||
"Value": "",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "BaseOfficeLocation",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "SPS-UserType",
|
|
||||||
"Value": "0",
|
|
||||||
"ValueType": "Edm.Int64"
|
|
||||||
}, {
|
|
||||||
"Key": "GroupId",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "SiteId",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "WebId",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "UniqueId",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "contentclass",
|
|
||||||
"Value": "urn:content-class:SPSPeople",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "PartitionId",
|
|
||||||
"Value": "92ab9c96-469b-4d78-8b8c-961c4df9356b",
|
|
||||||
"ValueType": "Edm.Guid"
|
|
||||||
}, {
|
|
||||||
"Key": "UrlZone",
|
|
||||||
"Value": "0",
|
|
||||||
"ValueType": "Edm.Int32"
|
|
||||||
}, {
|
|
||||||
"Key": "Culture",
|
|
||||||
"Value": "en-US",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "ResultTypeId",
|
|
||||||
"Value": "0",
|
|
||||||
"ValueType": "Edm.Int32"
|
|
||||||
}, {
|
|
||||||
"Key": "EditProfileUrl",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "ProfileViewsLastMonth",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "ProfileViewsLastWeek",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "ProfileQueriesFoundYou",
|
|
||||||
"Value": null,
|
|
||||||
"ValueType": "Null"
|
|
||||||
}, {
|
|
||||||
"Key": "RenderTemplateId",
|
|
||||||
"Value": "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default.js",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "GeoLocationSource",
|
|
||||||
"Value": "EUR",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
"TotalRows": 1,
|
|
||||||
"TotalRowsIncludingDuplicates": 1
|
|
||||||
},
|
|
||||||
"SpecialTermResults": null
|
|
||||||
},
|
|
||||||
"Properties": [{
|
|
||||||
"Key": "RowLimit",
|
|
||||||
"Value": "500",
|
|
||||||
"ValueType": "Edm.Int32"
|
|
||||||
}, {
|
|
||||||
"Key": "SourceId",
|
|
||||||
"Value": "b09a7990-05ea-4af9-81ef-edfab16c4e31",
|
|
||||||
"ValueType": "Edm.Guid"
|
|
||||||
}, {
|
|
||||||
"Key": "CorrelationId",
|
|
||||||
"Value": "e83b679f-b0c6-2000-3de3-321f0ebd7f6d",
|
|
||||||
"ValueType": "Edm.Guid"
|
|
||||||
}, {
|
|
||||||
"Key": "WasGroupRestricted",
|
|
||||||
"Value": "false",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "WordBreakerLanguage",
|
|
||||||
"Value": "default",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "IsPartialUpnDocIdMapping",
|
|
||||||
"Value": "false",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "EnableInterleaving",
|
|
||||||
"Value": "true",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "IsMissingUnifiedGroups",
|
|
||||||
"Value": "false",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "Constellation",
|
|
||||||
"Value": "i31EEE",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "MultiGeoSearchStatus",
|
|
||||||
"Value": "Full",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "HasParseException",
|
|
||||||
"Value": "false",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "IsPartial",
|
|
||||||
"Value": "false",
|
|
||||||
"ValueType": "Edm.Boolean"
|
|
||||||
}, {
|
|
||||||
"Key": "InternalRequestId",
|
|
||||||
"Value": "e44dc9d5-b4dc-4f4e-84f1-eef4eb163ad4",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}, {
|
|
||||||
"Key": "SerializedQuery",
|
|
||||||
"Value": "<Query Culture=\"en-US\" EnableStemming=\"True\" EnablePhonetic=\"False\" EnableNicknames=\"False\" IgnoreAllNoiseQuery=\"True\" SummaryLength=\"180\" MaxSnippetLength=\"180\" DesiredSnippetLength=\"90\" KeywordInclusion=\"0\" QueryText=\"LastName:kir*\" QueryTemplate=\"\" TrimDuplicates=\"True\" Site=\"3ea90dc6-5d70-4967-80a0-e07cbae5867f\" Web=\"ea51dacc-87ca-49cd-9f28-13fd2cb3b96b\" KeywordType=\"True\" HiddenConstraints=\"\" />",
|
|
||||||
"ValueType": "Edm.String"
|
|
||||||
}],
|
|
||||||
"SecondaryQueryResults": [],
|
|
||||||
"SpellingSuggestion": null,
|
|
||||||
"TriggeredRules": []
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
import { ISPServices } from "./ISPServices";
|
|
||||||
import * as mockdata from './MockDataSearch.json';
|
|
||||||
import { cloneDeep } from '@microsoft/sp-lodash-subset';
|
|
||||||
interface MinimalMockUser {
|
|
||||||
FirstName: string;
|
|
||||||
LastName: string;
|
|
||||||
Department: string;
|
|
||||||
BaseOfficeLocation: string;
|
|
||||||
Title: string;
|
|
||||||
PreferredName: string;
|
|
||||||
WorkPhone: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
DisplayName: user.PreferredName,
|
|
||||||
Title: user.JobTitle,
|
|
||||||
PictureUrl: user.PictureURL,
|
|
||||||
Email: user.WorkEmail,
|
|
||||||
Department: user.Department,
|
|
||||||
WorkPhone: user.WorkPhone,
|
|
||||||
Location: user.OfficeNumber
|
|
||||||
? user.OfficeNumber
|
|
||||||
: user.BaseOfficeLocation
|
|
||||||
*/
|
|
||||||
const sampleUserFirstNameLetter: string[] = [
|
|
||||||
"A",
|
|
||||||
"C",
|
|
||||||
"D",
|
|
||||||
"F",
|
|
||||||
"H",
|
|
||||||
"J",
|
|
||||||
"L",
|
|
||||||
"N",
|
|
||||||
"P",
|
|
||||||
"R",
|
|
||||||
"T",
|
|
||||||
"V",
|
|
||||||
"X",
|
|
||||||
"Z",
|
|
||||||
];
|
|
||||||
const sampleUserLastNameLetter: string[] = [
|
|
||||||
"B",
|
|
||||||
"E",
|
|
||||||
"G",
|
|
||||||
"I",
|
|
||||||
"K",
|
|
||||||
"M",
|
|
||||||
"O",
|
|
||||||
"Q",
|
|
||||||
"S",
|
|
||||||
"U",
|
|
||||||
"W",
|
|
||||||
"Y",
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
export class spMockServices implements ISPServices {
|
|
||||||
private sampleData: MinimalMockUser[] = [];
|
|
||||||
constructor() {
|
|
||||||
|
|
||||||
sampleUserLastNameLetter.forEach(lastNameL => {
|
|
||||||
sampleUserFirstNameLetter.forEach(firstNameL => {
|
|
||||||
const usercount = Math.floor(Math.random() * (5)) + 1;
|
|
||||||
for (let i = 0; i < usercount; i++) {
|
|
||||||
this.sampleData.push({
|
|
||||||
FirstName: `${firstNameL}FirstName${i}`,
|
|
||||||
LastName: `${lastNameL}LastName${i}`,
|
|
||||||
PreferredName: `${firstNameL}FirstName${i} ${lastNameL}LastName${i}`,
|
|
||||||
Department: i % 2 === 0 ? `${lastNameL}Department` : `${firstNameL}Department`,
|
|
||||||
BaseOfficeLocation: i % 3 === 0 ? `${lastNameL}Location` : `${firstNameL}Location`,
|
|
||||||
Title: i % 2 === 0 ? `${lastNameL}JobTitle` : `${firstNameL}JobTitle`,
|
|
||||||
WorkPhone: '' + Math.floor(Math.random() * 1234) + 54678900
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async searchUsers(searchString: string, searchFirstName: boolean) {
|
|
||||||
let filtervalue = searchString.trim().toLowerCase();
|
|
||||||
if (searchString.length > 0 && filtervalue.lastIndexOf("*") == searchString.length - 1) {
|
|
||||||
// remove last '*'
|
|
||||||
filtervalue = filtervalue.substring(0, searchString.length - 1);
|
|
||||||
}
|
|
||||||
if (!filtervalue || filtervalue.length === 0) {
|
|
||||||
throw new Error("No valid Input.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const searchresult = !!searchFirstName ?
|
|
||||||
this.sampleData.filter(p => p.FirstName.toLowerCase().indexOf(filtervalue) === 0) :
|
|
||||||
this.sampleData.filter(p => p.LastName.toLowerCase().indexOf(filtervalue) === 0);
|
|
||||||
|
|
||||||
const timeout = Math.floor(Math.random() * (1000)) + 1;
|
|
||||||
const resultdata = {
|
|
||||||
ElapsedTime: timeout,
|
|
||||||
RowCount: searchresult.length,
|
|
||||||
TotalRows: searchresult.length,
|
|
||||||
PrimarySearchResults: searchresult
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve(resultdata);
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async searchUsersNew(searchString: string, srchQry: string, isInitialSearch: boolean, pageNumber?: number) {
|
|
||||||
let filtervalue = searchString.trim().toLowerCase();
|
|
||||||
if (searchString.length > 0 && filtervalue.lastIndexOf("*") == searchString.length - 1) {
|
|
||||||
// remove last '*'
|
|
||||||
filtervalue = filtervalue.substring(0, searchString.length - 1);
|
|
||||||
}
|
|
||||||
if (!filtervalue || filtervalue.length === 0) {
|
|
||||||
throw new Error("No valid Input.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const searchresult = !!isInitialSearch ?
|
|
||||||
this.sampleData.filter(p => p.FirstName.toLowerCase().indexOf(filtervalue) === 0) :
|
|
||||||
this.sampleData.filter(p => p.LastName.toLowerCase().indexOf(filtervalue) === 0);
|
|
||||||
|
|
||||||
const timeout = Math.floor(Math.random() * (1000)) + 1;
|
|
||||||
const resultdata = {
|
|
||||||
ElapsedTime: timeout,
|
|
||||||
RowCount: searchresult.length,
|
|
||||||
TotalRows: searchresult.length,
|
|
||||||
PrimarySearchResults: searchresult
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve(resultdata);
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,89 +1,95 @@
|
||||||
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||||
import { graph } from "@pnp/graph";
|
|
||||||
import { sp, PeoplePickerEntity, ClientPeoplePickerQueryParameters, SearchQuery, SearchResults, SearchProperty, SortDirection } from '@pnp/sp';
|
import { sp } from '@pnp/sp';
|
||||||
import { PrincipalType } from "@pnp/sp/src/sitegroups";
|
import { SearchResults, ISearchQuery, SortDirection } from '@pnp/sp/search';
|
||||||
import { isRelativeUrl } from "office-ui-fabric-react";
|
|
||||||
import { ISPServices } from "./ISPServices";
|
import { ISPServices } from "./ISPServices";
|
||||||
|
|
||||||
|
|
||||||
export class spservices implements ISPServices {
|
export class spservices implements ISPServices {
|
||||||
constructor(private context: WebPartContext) {
|
constructor(private context: WebPartContext) {
|
||||||
sp.setup({
|
sp.setup({
|
||||||
spfxContext: this.context
|
spfxContext: {
|
||||||
});
|
pageContext: {
|
||||||
}
|
web: {
|
||||||
|
absoluteUrl: this.context.pageContext.web.absoluteUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async searchUsers(searchString: string, searchFirstName: boolean): Promise<SearchResults> {
|
public async searchUsers(searchString: string, searchFirstName: boolean): Promise<SearchResults> {
|
||||||
const _search = !searchFirstName ? `LastName:${searchString}*` : `FirstName:${searchString}*`;
|
const _search = !searchFirstName ? `LastName:${searchString}*` : `FirstName:${searchString}*`;
|
||||||
const searchProperties: string[] = ["FirstName", "LastName", "PreferredName", "WorkEmail", "OfficeNumber", "PictureURL", "WorkPhone", "MobilePhone", "JobTitle", "Department", "Skills", "PastProjects", "BaseOfficeLocation", "SPS-UserType", "GroupId"];
|
const searchProperties: string[] = ["FirstName", "LastName", "PreferredName", "WorkEmail", "OfficeNumber", "PictureURL", "WorkPhone", "MobilePhone", "JobTitle", "Department", "Skills", "PastProjects", "BaseOfficeLocation", "SPS-UserType", "GroupId"];
|
||||||
|
try {
|
||||||
|
if (!searchString) return undefined;
|
||||||
|
const users = await sp.searchWithCaching(<ISearchQuery>{
|
||||||
|
Querytext: _search,
|
||||||
|
RowLimit: 500,
|
||||||
|
EnableInterleaving: true,
|
||||||
|
SelectProperties: searchProperties,
|
||||||
|
SourceId: 'b09a7990-05ea-4af9-81ef-edfab16c4e31',
|
||||||
|
SortList: [{ "Property": "LastName", "Direction": SortDirection.Ascending }],
|
||||||
|
});
|
||||||
|
return users;
|
||||||
|
} catch (error) {
|
||||||
|
Promise.reject(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async _getImageBase64(pictureUrl: string): Promise<string> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const image = new Image();
|
||||||
|
image.addEventListener("load", () => {
|
||||||
|
const tempCanvas = document.createElement("canvas");
|
||||||
|
tempCanvas.width = image.width,
|
||||||
|
tempCanvas.height = image.height,
|
||||||
|
tempCanvas.getContext("2d").drawImage(image, 0, 0);
|
||||||
|
let base64Str;
|
||||||
try {
|
try {
|
||||||
if (!searchString) return undefined;
|
base64Str = tempCanvas.toDataURL("image/png");
|
||||||
let users = await sp.searchWithCaching(<SearchQuery>{
|
} catch (e) {
|
||||||
Querytext: _search,
|
return "";
|
||||||
RowLimit: 500,
|
|
||||||
EnableInterleaving: true,
|
|
||||||
SelectProperties: searchProperties,
|
|
||||||
SourceId: 'b09a7990-05ea-4af9-81ef-edfab16c4e31',
|
|
||||||
SortList: [{ "Property": "LastName", "Direction": SortDirection.Ascending }],
|
|
||||||
});
|
|
||||||
return users;
|
|
||||||
} catch (error) {
|
|
||||||
Promise.reject(error);
|
|
||||||
}
|
}
|
||||||
}
|
resolve(base64Str);
|
||||||
|
});
|
||||||
|
image.src = pictureUrl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async _getImageBase64 (pictureUrl: string): Promise<string> {
|
public async searchUsersNew(searchString: string, srchQry: string, isInitialSearch: boolean): Promise<SearchResults> {
|
||||||
return new Promise((resolve, reject) => {
|
let qrytext = '';
|
||||||
let image = new Image();
|
if (isInitialSearch) qrytext = `FirstName:${searchString}* OR LastName:${searchString}*`;
|
||||||
image.addEventListener("load", () => {
|
else {
|
||||||
let tempCanvas = document.createElement("canvas");
|
if (srchQry) qrytext = srchQry;
|
||||||
tempCanvas.width = image.width,
|
else {
|
||||||
tempCanvas.height = image.height,
|
if (searchString) qrytext = searchString;
|
||||||
tempCanvas.getContext("2d").drawImage(image, 0, 0);
|
}
|
||||||
let base64Str;
|
if (qrytext.length <= 0) qrytext = `*`;
|
||||||
try {
|
|
||||||
base64Str = tempCanvas.toDataURL("image/png");
|
|
||||||
} catch (e) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
resolve(base64Str);
|
|
||||||
});
|
|
||||||
image.src = pictureUrl;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
const searchProperties: string[] = ["FirstName", "LastName", "PreferredName", "WorkEmail", "OfficeNumber", "PictureURL", "WorkPhone", "MobilePhone", "JobTitle", "Department", "Skills", "PastProjects", "BaseOfficeLocation", "SPS-UserType", "GroupId"];
|
||||||
public async searchUsersNew(searchString: string, srchQry: string, isInitialSearch: boolean, pageNumber?: number): Promise<SearchResults> {
|
try {
|
||||||
let qrytext: string = '';
|
const users = await sp.search(<ISearchQuery>{
|
||||||
if (isInitialSearch) qrytext = `FirstName:${searchString}* OR LastName:${searchString}*`;
|
Querytext: qrytext,
|
||||||
else {
|
RowLimit: 500,
|
||||||
if (srchQry) qrytext = srchQry;
|
EnableInterleaving: true,
|
||||||
else {
|
SelectProperties: searchProperties,
|
||||||
if (searchString) qrytext = searchString;
|
SourceId: 'b09a7990-05ea-4af9-81ef-edfab16c4e31',
|
||||||
}
|
SortList: [{ "Property": "LastName", "Direction": SortDirection.Ascending }],
|
||||||
if (qrytext.length <= 0) qrytext = `*`;
|
});
|
||||||
}
|
if (users && users.PrimarySearchResults.length > 0) {
|
||||||
const searchProperties: string[] = ["FirstName", "LastName", "PreferredName", "WorkEmail", "OfficeNumber", "PictureURL", "WorkPhone", "MobilePhone", "JobTitle", "Department", "Skills", "PastProjects", "BaseOfficeLocation", "SPS-UserType", "GroupId"];
|
for (let index = 0; index < users.PrimarySearchResults.length; index++) {
|
||||||
try {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
let users = await sp.search(<SearchQuery>{
|
let user:any = users.PrimarySearchResults[index];
|
||||||
Querytext: qrytext,
|
if (user.PictureURL) {
|
||||||
RowLimit: 500,
|
user = { ...user, PictureURL: `/_layouts/15/userphoto.aspx?size=M&accountname=${user.WorkEmail}` };
|
||||||
EnableInterleaving: true,
|
users.PrimarySearchResults[index] = user;
|
||||||
SelectProperties: searchProperties,
|
}
|
||||||
SourceId: 'b09a7990-05ea-4af9-81ef-edfab16c4e31',
|
|
||||||
SortList: [{ "Property": "LastName", "Direction": SortDirection.Ascending }],
|
|
||||||
});
|
|
||||||
if (users && users.PrimarySearchResults.length > 0) {
|
|
||||||
for (let index = 0; index < users.PrimarySearchResults.length; index++) {
|
|
||||||
let user: any = users.PrimarySearchResults[index];
|
|
||||||
if (user.PictureURL) {
|
|
||||||
user = { ...user, PictureURL: `/_layouts/15/userphoto.aspx?size=M&accountname=${user.WorkEmail}` };
|
|
||||||
users.PrimarySearchResults[index] = user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
} catch (error) {
|
|
||||||
Promise.reject(error);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return users;
|
||||||
|
} catch (error) {
|
||||||
|
Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.directory {
|
.directory {
|
||||||
.dropDownSortBy {
|
.dropDownSortBy {
|
||||||
|
|
|
@ -6,374 +6,327 @@ import { spservices } from "../../../SPServices/spservices";
|
||||||
import { IDirectoryState } from "./IDirectoryState";
|
import { IDirectoryState } from "./IDirectoryState";
|
||||||
import * as strings from "DirectoryWebPartStrings";
|
import * as strings from "DirectoryWebPartStrings";
|
||||||
import {
|
import {
|
||||||
Spinner, SpinnerSize, MessageBar, MessageBarType, SearchBox, Icon, Label,
|
Spinner, SpinnerSize, MessageBar, MessageBarType, SearchBox, Icon, Label,
|
||||||
Pivot, PivotItem, PivotLinkFormat, PivotLinkSize, Dropdown, IDropdownOption
|
Pivot, PivotItem, PivotLinkFormat, PivotLinkSize, Dropdown, IDropdownOption
|
||||||
} from "office-ui-fabric-react";
|
} from "office-ui-fabric-react";
|
||||||
import { Stack, IStackTokens } from 'office-ui-fabric-react/lib/Stack';
|
import { Stack, IStackTokens } from 'office-ui-fabric-react/lib/Stack';
|
||||||
import { debounce } from "throttle-debounce";
|
//import { debounce } from "throttle-debounce";
|
||||||
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
import { WebPartTitle } from "@pnp/spfx-controls-react";
|
||||||
import { ISPServices } from "../../../SPServices/ISPServices";
|
import { ISPServices } from "../../../SPServices/ISPServices";
|
||||||
import { Environment, EnvironmentType } from "@microsoft/sp-core-library";
|
|
||||||
import { spMockServices } from "../../../SPServices/spMockServices";
|
|
||||||
import { IDirectoryProps } from './IDirectoryProps';
|
import { IDirectoryProps } from './IDirectoryProps';
|
||||||
import Paging from './Pagination/Paging';
|
import Paging from './Pagination/Paging';
|
||||||
|
|
||||||
const slice: any = require('lodash/slice');
|
|
||||||
const filter: any = require('lodash/filter');
|
|
||||||
const wrapStackTokens: IStackTokens = { childrenGap: 30 };
|
const wrapStackTokens: IStackTokens = { childrenGap: 30 };
|
||||||
|
|
||||||
const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
||||||
let _services: ISPServices = null;
|
const _services: ISPServices = new spservices(props.context);
|
||||||
if (Environment.type === EnvironmentType.Local) {
|
const [az, setaz] = useState<string[]>([]);
|
||||||
_services = new spMockServices();
|
const [alphaKey, setalphaKey] = useState<string>('A');
|
||||||
} else {
|
const [state, setstate] = useState<IDirectoryState>({
|
||||||
_services = new spservices(props.context);
|
users: [],
|
||||||
|
isLoading: true,
|
||||||
|
errorMessage: "",
|
||||||
|
hasError: false,
|
||||||
|
indexSelectedKey: "A",
|
||||||
|
searchString: "LastName",
|
||||||
|
searchText: ""
|
||||||
|
});
|
||||||
|
const orderOptions: IDropdownOption[] = [
|
||||||
|
{ key: "FirstName", text: "First Name" },
|
||||||
|
{ key: "LastName", text: "Last Name" },
|
||||||
|
{ key: "Department", text: "Department" },
|
||||||
|
{ key: "Location", text: "Location" },
|
||||||
|
{ key: "JobTitle", text: "Job Title" }
|
||||||
|
];
|
||||||
|
const color = props.context.microsoftTeams ? "white" : "";
|
||||||
|
// Paging
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const [pagedItems, setPagedItems] = useState<any[]>([]);
|
||||||
|
const [pageSize, setPageSize] = useState<number>(props.pageSize ? props.pageSize : 10);
|
||||||
|
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||||
|
|
||||||
|
const _onPageUpdate = async (pageno?: number) => {
|
||||||
|
const currentPge = (pageno) ? pageno : currentPage;
|
||||||
|
const startItem = ((currentPge - 1) * pageSize);
|
||||||
|
const endItem = currentPge * pageSize;
|
||||||
|
const filItems = state.users.slice(startItem, endItem);
|
||||||
|
setCurrentPage(currentPge);
|
||||||
|
setPagedItems(filItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
const diretoryGrid =
|
||||||
|
pagedItems && pagedItems.length > 0
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
? pagedItems.map((user: any, i) => {
|
||||||
|
return (
|
||||||
|
<PersonaCard
|
||||||
|
context={props.context}
|
||||||
|
key={"PersonaCard" + i}
|
||||||
|
profileProperties={{
|
||||||
|
DisplayName: user.PreferredName,
|
||||||
|
Title: user.JobTitle,
|
||||||
|
PictureUrl: user.PictureURL,
|
||||||
|
Email: user.WorkEmail,
|
||||||
|
Department: user.Department,
|
||||||
|
WorkPhone: user.WorkPhone,
|
||||||
|
Location: user.OfficeNumber
|
||||||
|
? user.OfficeNumber
|
||||||
|
: user.BaseOfficeLocation
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
const _loadAlphabets = () => {
|
||||||
|
const alphabets: string[] = [];
|
||||||
|
for (let i = 65; i < 91; i++) {
|
||||||
|
alphabets.push(
|
||||||
|
String.fromCharCode(i)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const [az, setaz] = useState<string[]>([]);
|
setaz(alphabets);
|
||||||
const [alphaKey, setalphaKey] = useState<string>('A');
|
};
|
||||||
const [state, setstate] = useState<IDirectoryState>({
|
|
||||||
users: [],
|
const _alphabetChange = async (item?: PivotItem) => {
|
||||||
isLoading: true,
|
setstate({ ...state, searchText: "", indexSelectedKey: item.props.itemKey, isLoading: true });
|
||||||
errorMessage: "",
|
setalphaKey(item.props.itemKey);
|
||||||
hasError: false,
|
setCurrentPage(1);
|
||||||
indexSelectedKey: "A",
|
};
|
||||||
searchString: "LastName",
|
const _searchByAlphabets = async (initialSearch: boolean) => {
|
||||||
searchText: ""
|
setstate({ ...state, isLoading: true, searchText: '' });
|
||||||
|
let users = null;
|
||||||
|
if (initialSearch) {
|
||||||
|
if (props.searchFirstName)
|
||||||
|
users = await _services.searchUsersNew('', `FirstName:a*`, false);
|
||||||
|
else users = await _services.searchUsersNew('a', '', true);
|
||||||
|
} else {
|
||||||
|
if (props.searchFirstName)
|
||||||
|
users = await _services.searchUsersNew('', `FirstName:${alphaKey}*`, false);
|
||||||
|
else users = await _services.searchUsersNew(`${alphaKey}`, '', true);
|
||||||
|
}
|
||||||
|
setstate({
|
||||||
|
...state,
|
||||||
|
searchText: '',
|
||||||
|
indexSelectedKey: initialSearch ? 'A' : state.indexSelectedKey,
|
||||||
|
users:
|
||||||
|
users && users.PrimarySearchResults
|
||||||
|
? users.PrimarySearchResults
|
||||||
|
: null,
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: "",
|
||||||
|
hasError: false
|
||||||
});
|
});
|
||||||
const orderOptions: IDropdownOption[] = [
|
};
|
||||||
{ key: "FirstName", text: "First Name" },
|
|
||||||
{ key: "LastName", text: "Last Name" },
|
|
||||||
{ key: "Department", text: "Department" },
|
|
||||||
{ key: "Location", text: "Location" },
|
|
||||||
{ key: "JobTitle", text: "Job Title" }
|
|
||||||
];
|
|
||||||
const color = props.context.microsoftTeams ? "white" : "";
|
|
||||||
// Paging
|
|
||||||
const [pagedItems, setPagedItems] = useState<any[]>([]);
|
|
||||||
const [pageSize, setPageSize] = useState<number>(props.pageSize ? props.pageSize : 10);
|
|
||||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
|
||||||
|
|
||||||
const _onPageUpdate = async (pageno?: number) => {
|
const _searchUsers = async (searchText: string) => {
|
||||||
var currentPge = (pageno) ? pageno : currentPage;
|
try {
|
||||||
var startItem = ((currentPge - 1) * pageSize);
|
setstate({ ...state, searchText: searchText, isLoading: true });
|
||||||
var endItem = currentPge * pageSize;
|
if (searchText.length > 0) {
|
||||||
let filItems = slice(state.users, startItem, endItem);
|
const searchProps: string[] = props.searchProps && props.searchProps.length > 0 ?
|
||||||
setCurrentPage(currentPge);
|
props.searchProps.split(',') : ['FirstName', 'LastName', 'WorkEmail', 'Department'];
|
||||||
setPagedItems(filItems);
|
let qryText = '';
|
||||||
};
|
const finalSearchText: string = searchText ? searchText.replace(/ /g, '+') : searchText;
|
||||||
|
if (props.clearTextSearchProps) {
|
||||||
const diretoryGrid =
|
const tmpCTProps: string[] = props.clearTextSearchProps.indexOf(',') >= 0 ? props.clearTextSearchProps.split(',') : [props.clearTextSearchProps];
|
||||||
pagedItems && pagedItems.length > 0
|
if (tmpCTProps.length > 0) {
|
||||||
? pagedItems.map((user: any) => {
|
searchProps.map((srchprop, index) => {
|
||||||
return (
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
<PersonaCard
|
const ctPresent: any[] = tmpCTProps.filter( (o) => { return o.toLowerCase() == srchprop.toLowerCase(); });
|
||||||
context={props.context}
|
if (ctPresent.length > 0) {
|
||||||
profileProperties={{
|
if (index == searchProps.length - 1) {
|
||||||
DisplayName: user.PreferredName,
|
qryText += `${srchprop}:${searchText}*`;
|
||||||
Title: user.JobTitle,
|
} else qryText += `${srchprop}:${searchText}* OR `;
|
||||||
PictureUrl: user.PictureURL,
|
} else {
|
||||||
Email: user.WorkEmail,
|
if (index == searchProps.length - 1) {
|
||||||
Department: user.Department,
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
WorkPhone: user.WorkPhone,
|
} else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
Location: user.OfficeNumber
|
}
|
||||||
? user.OfficeNumber
|
});
|
||||||
: user.BaseOfficeLocation
|
} else {
|
||||||
}}
|
searchProps.map((srchprop, index) => {
|
||||||
/>
|
if (index == searchProps.length - 1)
|
||||||
);
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
})
|
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
: [];
|
});
|
||||||
const _loadAlphabets = () => {
|
}
|
||||||
let alphabets: string[] = [];
|
|
||||||
for (let i = 65; i < 91; i++) {
|
|
||||||
alphabets.push(
|
|
||||||
String.fromCharCode(i)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
setaz(alphabets);
|
|
||||||
};
|
|
||||||
|
|
||||||
const _alphabetChange = async (item?: PivotItem, ev?: React.MouseEvent<HTMLElement>) => {
|
|
||||||
setstate({ ...state, searchText: "", indexSelectedKey: item.props.itemKey, isLoading: true });
|
|
||||||
setalphaKey(item.props.itemKey);
|
|
||||||
setCurrentPage(1);
|
|
||||||
};
|
|
||||||
const _searchByAlphabets = async (initialSearch: boolean) => {
|
|
||||||
setstate({ ...state, isLoading: true, searchText: '' });
|
|
||||||
let users = null;
|
|
||||||
if (initialSearch) {
|
|
||||||
if (props.searchFirstName)
|
|
||||||
users = await _services.searchUsersNew('', `FirstName:a*`, false);
|
|
||||||
else users = await _services.searchUsersNew('a', '', true);
|
|
||||||
} else {
|
} else {
|
||||||
if (props.searchFirstName)
|
searchProps.map((srchprop, index) => {
|
||||||
users = await _services.searchUsersNew('', `FirstName:${alphaKey}*`, false);
|
if (index == searchProps.length - 1)
|
||||||
else users = await _services.searchUsersNew(`${alphaKey}`, '', true);
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
|
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
console.log(qryText);
|
||||||
|
const users = await _services.searchUsersNew('', qryText, false);
|
||||||
setstate({
|
setstate({
|
||||||
...state,
|
...state,
|
||||||
searchText: '',
|
searchText: searchText,
|
||||||
indexSelectedKey: initialSearch ? 'A' : state.indexSelectedKey,
|
indexSelectedKey: '0',
|
||||||
users:
|
users:
|
||||||
users && users.PrimarySearchResults
|
users && users.PrimarySearchResults
|
||||||
? users.PrimarySearchResults
|
? users.PrimarySearchResults
|
||||||
: null,
|
: null,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: "",
|
errorMessage: "",
|
||||||
hasError: false
|
hasError: false
|
||||||
});
|
});
|
||||||
};
|
setalphaKey('0');
|
||||||
|
} else {
|
||||||
let _searchUsers = async (searchText: string) => {
|
setstate({ ...state, searchText: '' });
|
||||||
try {
|
|
||||||
setstate({ ...state, searchText: searchText, isLoading: true });
|
|
||||||
if (searchText.length > 0) {
|
|
||||||
let searchProps: string[] = props.searchProps && props.searchProps.length > 0 ?
|
|
||||||
props.searchProps.split(',') : ['FirstName', 'LastName', 'WorkEmail', 'Department'];
|
|
||||||
let qryText: string = '';
|
|
||||||
let finalSearchText: string = searchText ? searchText.replace(/ /g, '+') : searchText;
|
|
||||||
if (props.clearTextSearchProps) {
|
|
||||||
let tmpCTProps: string[] = props.clearTextSearchProps.indexOf(',') >= 0 ? props.clearTextSearchProps.split(',') : [props.clearTextSearchProps];
|
|
||||||
if (tmpCTProps.length > 0) {
|
|
||||||
searchProps.map((srchprop, index) => {
|
|
||||||
let ctPresent: any[] = filter(tmpCTProps, (o) => { return o.toLowerCase() == srchprop.toLowerCase(); });
|
|
||||||
if (ctPresent.length > 0) {
|
|
||||||
if(index == searchProps.length - 1) {
|
|
||||||
qryText += `${srchprop}:${searchText}*`;
|
|
||||||
} else qryText += `${srchprop}:${searchText}* OR `;
|
|
||||||
} else {
|
|
||||||
if(index == searchProps.length - 1) {
|
|
||||||
qryText += `${srchprop}:${finalSearchText}*`;
|
|
||||||
} else qryText += `${srchprop}:${finalSearchText}* OR `;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
searchProps.map((srchprop, index) => {
|
|
||||||
if (index == searchProps.length - 1)
|
|
||||||
qryText += `${srchprop}:${finalSearchText}*`;
|
|
||||||
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
searchProps.map((srchprop, index) => {
|
|
||||||
if (index == searchProps.length - 1)
|
|
||||||
qryText += `${srchprop}:${finalSearchText}*`;
|
|
||||||
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
console.log(qryText);
|
|
||||||
const users = await _services.searchUsersNew('', qryText, false);
|
|
||||||
setstate({
|
|
||||||
...state,
|
|
||||||
searchText: searchText,
|
|
||||||
indexSelectedKey: '0',
|
|
||||||
users:
|
|
||||||
users && users.PrimarySearchResults
|
|
||||||
? users.PrimarySearchResults
|
|
||||||
: null,
|
|
||||||
isLoading: false,
|
|
||||||
errorMessage: "",
|
|
||||||
hasError: false
|
|
||||||
});
|
|
||||||
setalphaKey('0');
|
|
||||||
} else {
|
|
||||||
setstate({ ...state, searchText: '' });
|
|
||||||
_searchByAlphabets(true);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
setstate({ ...state, errorMessage: err.message, hasError: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _searchBoxChanged = (newvalue: string): void => {
|
|
||||||
setCurrentPage(1);
|
|
||||||
_searchUsers(newvalue);
|
|
||||||
};
|
|
||||||
_searchUsers = debounce(500, _searchUsers);
|
|
||||||
|
|
||||||
const _sortPeople = async (sortField: string) => {
|
|
||||||
let _users = [...state.users];
|
|
||||||
_users = _users.sort((a: any, b: any) => {
|
|
||||||
switch (sortField) {
|
|
||||||
// Sorte by FirstName
|
|
||||||
case "FirstName":
|
|
||||||
const aFirstName = a.FirstName ? a.FirstName : "";
|
|
||||||
const bFirstName = b.FirstName ? b.FirstName : "";
|
|
||||||
if (aFirstName.toUpperCase() < bFirstName.toUpperCase()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (aFirstName.toUpperCase() > bFirstName.toUpperCase()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
// Sort by LastName
|
|
||||||
case "LastName":
|
|
||||||
const aLastName = a.LastName ? a.LastName : "";
|
|
||||||
const bLastName = b.LastName ? b.LastName : "";
|
|
||||||
if (aLastName.toUpperCase() < bLastName.toUpperCase()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (aLastName.toUpperCase() > bLastName.toUpperCase()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
// Sort by Location
|
|
||||||
case "Location":
|
|
||||||
const aBaseOfficeLocation = a.BaseOfficeLocation
|
|
||||||
? a.BaseOfficeLocation
|
|
||||||
: "";
|
|
||||||
const bBaseOfficeLocation = b.BaseOfficeLocation
|
|
||||||
? b.BaseOfficeLocation
|
|
||||||
: "";
|
|
||||||
if (
|
|
||||||
aBaseOfficeLocation.toUpperCase() <
|
|
||||||
bBaseOfficeLocation.toUpperCase()
|
|
||||||
) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
aBaseOfficeLocation.toUpperCase() >
|
|
||||||
bBaseOfficeLocation.toUpperCase()
|
|
||||||
) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
// Sort by JobTitle
|
|
||||||
case "JobTitle":
|
|
||||||
const aJobTitle = a.JobTitle ? a.JobTitle : "";
|
|
||||||
const bJobTitle = b.JobTitle ? b.JobTitle : "";
|
|
||||||
if (aJobTitle.toUpperCase() < bJobTitle.toUpperCase()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (aJobTitle.toUpperCase() > bJobTitle.toUpperCase()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
// Sort by Department
|
|
||||||
case "Department":
|
|
||||||
const aDepartment = a.Department ? a.Department : "";
|
|
||||||
const bDepartment = b.Department ? b.Department : "";
|
|
||||||
if (aDepartment.toUpperCase() < bDepartment.toUpperCase()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (aDepartment.toUpperCase() > bDepartment.toUpperCase()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setstate({ ...state, users: _users, searchString: sortField });
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPageSize(props.pageSize);
|
|
||||||
if (state.users) _onPageUpdate();
|
|
||||||
}, [state.users, props.pageSize]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (alphaKey.length > 0 && alphaKey != "0") _searchByAlphabets(false);
|
|
||||||
}, [alphaKey]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
_loadAlphabets();
|
|
||||||
_searchByAlphabets(true);
|
_searchByAlphabets(true);
|
||||||
}, [props]);
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setstate({ ...state, errorMessage: err.message, hasError: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const _searchBoxChanged = (newvalue: string): void => {
|
||||||
<div className={styles.directory}>
|
setCurrentPage(1);
|
||||||
<WebPartTitle displayMode={props.displayMode} title={props.title}
|
_searchUsers(newvalue);
|
||||||
updateProperty={props.updateProperty} />
|
};
|
||||||
<div className={styles.searchBox}>
|
//_searchUsers = debounce(500, _searchUsers);
|
||||||
<SearchBox placeholder={strings.SearchPlaceHolder} className={styles.searchTextBox}
|
|
||||||
onSearch={_searchUsers}
|
const _sortPeople = async (sortField: string) => {
|
||||||
value={state.searchText}
|
let _users = [...state.users];
|
||||||
onChange={_searchBoxChanged} />
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
<div>
|
_users = _users.sort((a: any, b: any) => {
|
||||||
<Pivot className={styles.alphabets} linkFormat={PivotLinkFormat.tabs}
|
|
||||||
selectedKey={state.indexSelectedKey} onLinkClick={_alphabetChange}
|
|
||||||
linkSize={PivotLinkSize.normal} >
|
switch (sortField) {
|
||||||
{az.map((index: string) => {
|
|
||||||
return (
|
// Sort by Location
|
||||||
<PivotItem headerText={index} itemKey={index} key={index} />
|
case "Location":
|
||||||
);
|
if ((a.BaseOfficeLocation||"").toUpperCase() < (b.BaseOfficeLocation||"").toUpperCase()) {
|
||||||
})}
|
return -1;
|
||||||
</Pivot>
|
}
|
||||||
</div>
|
if ((a.BaseOfficeLocation||"").toUpperCase() > (b.BaseOfficeLocation||"").toUpperCase()) {
|
||||||
</div>
|
return 1;
|
||||||
{state.isLoading ? (
|
}
|
||||||
<div style={{ marginTop: '10px' }}>
|
return 0;
|
||||||
<Spinner size={SpinnerSize.large} label={strings.LoadingText} />
|
|
||||||
</div>
|
break;
|
||||||
) : (
|
break;
|
||||||
<>
|
|
||||||
{state.hasError ? (
|
default:
|
||||||
<div style={{ marginTop: '10px' }}>
|
if ((a[sortField]||"").toUpperCase() < (a[sortField]||"").toUpperCase()) {
|
||||||
<MessageBar messageBarType={MessageBarType.error}>
|
return -1;
|
||||||
{state.errorMessage}
|
}
|
||||||
</MessageBar>
|
if ((a[sortField]||"").toUpperCase() > (a[sortField]||"").toUpperCase()) {
|
||||||
</div>
|
return 1;
|
||||||
) : (
|
}
|
||||||
<>
|
return 0;
|
||||||
{!pagedItems || pagedItems.length == 0 ? (
|
|
||||||
<div className={styles.noUsers}>
|
break;
|
||||||
<Icon
|
}
|
||||||
iconName={"ProfileSearch"}
|
});
|
||||||
style={{ fontSize: "54px", color: color }}
|
setstate({ ...state, users: _users, searchString: sortField });
|
||||||
/>
|
};
|
||||||
<Label>
|
|
||||||
<span style={{ marginLeft: 5, fontSize: "26px", color: color }}>
|
useEffect(() => {
|
||||||
{strings.DirectoryMessage}
|
setPageSize(props.pageSize);
|
||||||
</span>
|
if (state.users) _onPageUpdate();
|
||||||
</Label>
|
}, [state.users, props.pageSize]);
|
||||||
</div>
|
|
||||||
) : (
|
useEffect(() => {
|
||||||
<>
|
if (alphaKey.length > 0 && alphaKey != "0") _searchByAlphabets(false);
|
||||||
<div style={{ width: '100%', display: 'inline-block' }}>
|
}, [alphaKey]);
|
||||||
<Paging
|
|
||||||
totalItems={state.users.length}
|
useEffect(() => {
|
||||||
itemsCountPerPage={pageSize}
|
_loadAlphabets();
|
||||||
onPageUpdate={_onPageUpdate}
|
_searchByAlphabets(true);
|
||||||
currentPage={currentPage} />
|
}, [props]);
|
||||||
</div>
|
|
||||||
<div className={styles.dropDownSortBy}>
|
return (
|
||||||
<Stack horizontal horizontalAlign="center" wrap tokens={wrapStackTokens}>
|
<div className={styles.directory}>
|
||||||
<Dropdown
|
<WebPartTitle displayMode={props.displayMode} title={props.title}
|
||||||
placeholder={strings.DropDownPlaceHolderMessage}
|
updateProperty={props.updateProperty} />
|
||||||
label={strings.DropDownPlaceLabelMessage}
|
<div className={styles.searchBox}>
|
||||||
options={orderOptions}
|
<SearchBox placeholder={strings.SearchPlaceHolder} className={styles.searchTextBox}
|
||||||
selectedKey={state.searchString}
|
onSearch={_searchUsers}
|
||||||
onChange={(ev: any, value: IDropdownOption) => {
|
value={state.searchText}
|
||||||
_sortPeople(value.key.toString());
|
onChange={(ev,newVal) =>_searchBoxChanged(newVal)} />
|
||||||
}}
|
<div>
|
||||||
styles={{ dropdown: { width: 200 } }}
|
<Pivot className={styles.alphabets} linkFormat={PivotLinkFormat.tabs}
|
||||||
/>
|
selectedKey={state.indexSelectedKey} onLinkClick={_alphabetChange}
|
||||||
</Stack>
|
linkSize={PivotLinkSize.normal} >
|
||||||
</div>
|
{az.map((index: string) => {
|
||||||
<Stack horizontal horizontalAlign={props.useSpaceBetween?"space-between":"center"} wrap tokens={wrapStackTokens}>
|
return (
|
||||||
{diretoryGrid}
|
<PivotItem headerText={index} itemKey={index} key={index} />
|
||||||
</Stack>
|
);
|
||||||
<div style={{ width: '100%', display: 'inline-block' }}>
|
})}
|
||||||
<Paging
|
</Pivot>
|
||||||
totalItems={state.users.length}
|
|
||||||
itemsCountPerPage={pageSize}
|
|
||||||
onPageUpdate={_onPageUpdate}
|
|
||||||
currentPage={currentPage} />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
|
{state.isLoading ? (
|
||||||
|
<div style={{ marginTop: '10px' }}>
|
||||||
|
<Spinner size={SpinnerSize.large} label={strings.LoadingText} />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{state.hasError ? (
|
||||||
|
<div style={{ marginTop: '10px' }}>
|
||||||
|
<MessageBar messageBarType={MessageBarType.error}>
|
||||||
|
{state.errorMessage}
|
||||||
|
</MessageBar>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{!pagedItems || pagedItems.length == 0 ? (
|
||||||
|
<div className={styles.noUsers}>
|
||||||
|
<Icon
|
||||||
|
iconName={"ProfileSearch"}
|
||||||
|
style={{ fontSize: "54px", color: color }}
|
||||||
|
/>
|
||||||
|
<Label>
|
||||||
|
<span style={{ marginLeft: 5, fontSize: "26px", color: color }}>
|
||||||
|
{strings.DirectoryMessage}
|
||||||
|
</span>
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div style={{ width: '100%', display: 'inline-block' }}>
|
||||||
|
<Paging
|
||||||
|
totalItems={state.users.length}
|
||||||
|
itemsCountPerPage={pageSize}
|
||||||
|
onPageUpdate={_onPageUpdate}
|
||||||
|
currentPage={currentPage} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.dropDownSortBy}>
|
||||||
|
<Stack horizontal horizontalAlign="center" wrap tokens={wrapStackTokens}>
|
||||||
|
<Dropdown
|
||||||
|
placeholder={strings.DropDownPlaceHolderMessage}
|
||||||
|
label={strings.DropDownPlaceLabelMessage}
|
||||||
|
options={orderOptions}
|
||||||
|
selectedKey={state.searchString}
|
||||||
|
onChange={(ev, value) => {
|
||||||
|
_sortPeople(value.key.toString());
|
||||||
|
}}
|
||||||
|
styles={{ dropdown: { width: 200 } }}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
<Stack horizontal horizontalAlign={props.useSpaceBetween ? "space-between" : "center"} wrap tokens={wrapStackTokens}>
|
||||||
|
{diretoryGrid}
|
||||||
|
</Stack>
|
||||||
|
<div style={{ width: '100%', display: 'inline-block' }}>
|
||||||
|
<Paging
|
||||||
|
totalItems={state.users.length}
|
||||||
|
itemsCountPerPage={pageSize}
|
||||||
|
onPageUpdate={_onPageUpdate}
|
||||||
|
currentPage={currentPage} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DirectoryHook;
|
export default DirectoryHook;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
export interface IDirectoryState {
|
export interface IDirectoryState {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
users: any;
|
users: any;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.paginationContainer {
|
.paginationContainer {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -30,4 +32,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,10 @@ const Paging: React.FC<IPagingProps> = (props) => {
|
||||||
<div className={styles.searchWp__paginationContainer__pagination}>
|
<div className={styles.searchWp__paginationContainer__pagination}>
|
||||||
<Pagination
|
<Pagination
|
||||||
activePage={currentPage}
|
activePage={currentPage}
|
||||||
firstPageText={<i className='ms-Icon ms-Icon--DoubleChevronLeft' aria-hidden='true'></i>}
|
firstPageText={<i className='ms-Icon ms-Icon--DoubleChevronLeft' aria-hidden='true' />}
|
||||||
lastPageText={<i className='ms-Icon ms-Icon--DoubleChevronRight' aria-hidden='true'></i>}
|
lastPageText={<i className='ms-Icon ms-Icon--DoubleChevronRight' aria-hidden='true' />}
|
||||||
prevPageText={<i className='ms-Icon ms-Icon--ChevronLeft' aria-hidden='true'></i>}
|
prevPageText={<i className='ms-Icon ms-Icon--ChevronLeft' aria-hidden='true' />}
|
||||||
nextPageText={<i className='ms-Icon ms-Icon--ChevronRight' aria-hidden='true'></i>}
|
nextPageText={<i className='ms-Icon ms-Icon--ChevronRight' aria-hidden='true' />}
|
||||||
activeLinkClass={styles.active}
|
activeLinkClass={styles.active}
|
||||||
itemsCountPerPage={props.itemsCountPerPage}
|
itemsCountPerPage={props.itemsCountPerPage}
|
||||||
totalItemsCount={props.totalItems}
|
totalItemsCount={props.totalItems}
|
||||||
|
@ -48,4 +48,4 @@ const Paging: React.FC<IPagingProps> = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Paging;
|
export default Paging;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export interface IPersonaCardState {
|
export interface IPersonaCardState {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
livePersonaCard: any;
|
livePersonaCard: any;
|
||||||
pictureUrl: string;
|
pictureUrl: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export interface IUserProperties {
|
export interface IUserProperties {
|
||||||
Department: string;
|
Department: string;
|
||||||
MobilePhone?: String;
|
MobilePhone?: string;
|
||||||
PictureUrl: string;
|
PictureUrl: string;
|
||||||
Title: string;
|
Title: string;
|
||||||
DisplayName: string;
|
DisplayName: string;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.personaContainer {
|
.personaContainer {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -2,9 +2,7 @@ import * as React from 'react';
|
||||||
import styles from './PersonaCard.module.scss';
|
import styles from './PersonaCard.module.scss';
|
||||||
import { IPersonaCardProps } from './IPersonaCardProps';
|
import { IPersonaCardProps } from './IPersonaCardProps';
|
||||||
import { IPersonaCardState } from './IPersonaCardState';
|
import { IPersonaCardState } from './IPersonaCardState';
|
||||||
import {
|
import { Log } from '@microsoft/sp-core-library';
|
||||||
Log, Environment, EnvironmentType,
|
|
||||||
} from '@microsoft/sp-core-library';
|
|
||||||
import { SPComponentLoader } from '@microsoft/sp-loader';
|
import { SPComponentLoader } from '@microsoft/sp-loader';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -15,14 +13,13 @@ import {
|
||||||
Icon,
|
Icon,
|
||||||
} from 'office-ui-fabric-react';
|
} from 'office-ui-fabric-react';
|
||||||
|
|
||||||
const EXP_SOURCE: string = 'SPFxDirectory';
|
const EXP_SOURCE = 'SPFxDirectory';
|
||||||
const LIVE_PERSONA_COMPONENT_ID: string =
|
const LIVE_PERSONA_COMPONENT_ID = '914330ee-2df2-4f6e-a858-30c23a812408';
|
||||||
'914330ee-2df2-4f6e-a858-30c23a812408';
|
|
||||||
|
|
||||||
export class PersonaCard extends React.Component<
|
export class PersonaCard extends React.Component<
|
||||||
IPersonaCardProps,
|
IPersonaCardProps,
|
||||||
IPersonaCardState
|
IPersonaCardState
|
||||||
> {
|
> {
|
||||||
constructor(props: IPersonaCardProps) {
|
constructor(props: IPersonaCardProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -34,26 +31,15 @@ export class PersonaCard extends React.Component<
|
||||||
* @memberof PersonaCard
|
* @memberof PersonaCard
|
||||||
*/
|
*/
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
if (Environment.type !== EnvironmentType.Local) {
|
const sharedLibrary = await this._loadSPComponentById(
|
||||||
const sharedLibrary = await this._loadSPComponentById(
|
LIVE_PERSONA_COMPONENT_ID
|
||||||
LIVE_PERSONA_COMPONENT_ID
|
);
|
||||||
);
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const livePersonaCard: any = sharedLibrary.LivePersonaCard;
|
const livePersonaCard: any = sharedLibrary.LivePersonaCard;
|
||||||
this.setState({ livePersonaCard: livePersonaCard });
|
this.setState({ livePersonaCard: livePersonaCard });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param {IPersonaCardProps} prevProps
|
|
||||||
* @param {IPersonaCardState} prevState
|
|
||||||
* @memberof PersonaCard
|
|
||||||
*/
|
|
||||||
public componentDidUpdate(
|
|
||||||
prevProps: IPersonaCardProps,
|
|
||||||
prevState: IPersonaCardState
|
|
||||||
): void { }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -111,8 +97,8 @@ export class PersonaCard extends React.Component<
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
{this.props.profileProperties.Location ? (
|
{this.props.profileProperties.Location ? (
|
||||||
<div className={styles.textOverflow}>
|
<div className={styles.textOverflow}>
|
||||||
<Icon iconName="Poi" style={{ fontSize: '12px' }} />
|
<Icon iconName="Poi" style={{ fontSize: '12px' }} />
|
||||||
|
@ -122,8 +108,8 @@ export class PersonaCard extends React.Component<
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
</Persona>
|
</Persona>
|
||||||
</div>
|
</div>
|
||||||
</DocumentCard>
|
</DocumentCard>
|
||||||
|
@ -133,8 +119,10 @@ export class PersonaCard extends React.Component<
|
||||||
* Load SPFx component by id, SPComponentLoader is used to load the SPFx components
|
* Load SPFx component by id, SPComponentLoader is used to load the SPFx components
|
||||||
* @param componentId - componentId, guid of the component library
|
* @param componentId - componentId, guid of the component library
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
private async _loadSPComponentById(componentId: string): Promise<any> {
|
private async _loadSPComponentById(componentId: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const component: any = await SPComponentLoader.loadComponentById(
|
const component: any = await SPComponentLoader.loadComponentById(
|
||||||
componentId
|
componentId
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
{
|
{
|
||||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-4.5/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule" : true,
|
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
@ -14,27 +13,27 @@
|
||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
"inlineSources": false,
|
"inlineSources": false,
|
||||||
"strictNullChecks": false,
|
"strictNullChecks": false,
|
||||||
|
"noImplicitAny": true,
|
||||||
"noUnusedLocals": false,
|
"noUnusedLocals": false,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types",
|
"./node_modules/@types",
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"es6-promise",
|
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es5",
|
"es5",
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
"src/**/*.tsx"
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
}
|
||||||
"lib"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
|
||||||
"rules": {
|
|
||||||
"class-name": false,
|
|
||||||
"export-name": false,
|
|
||||||
"forin": false,
|
|
||||||
"label-position": false,
|
|
||||||
"member-access": true,
|
|
||||||
"no-arg": false,
|
|
||||||
"no-console": false,
|
|
||||||
"no-construct": false,
|
|
||||||
"no-duplicate-variable": true,
|
|
||||||
"no-eval": false,
|
|
||||||
"no-function-expression": true,
|
|
||||||
"no-internal-module": true,
|
|
||||||
"no-shadowed-variable": true,
|
|
||||||
"no-switch-case-fall-through": true,
|
|
||||||
"no-unnecessary-semicolons": true,
|
|
||||||
"no-unused-expression": true,
|
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-with-statement": true,
|
|
||||||
"semicolon": true,
|
|
||||||
"trailing-comma": false,
|
|
||||||
"typedef": false,
|
|
||||||
"typedef-whitespace": false,
|
|
||||||
"use-named-parameter": true,
|
|
||||||
"variable-name": false,
|
|
||||||
"whitespace": false
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue