Merge pull request #2083 from aakashbhardwaj619/reactPageNavigatorUpgrade
react-page-navigator SPFx upgrade and code refactoring
This commit is contained in:
commit
cf9b0fefee
|
@ -1,25 +0,0 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -12,6 +12,7 @@ lib
|
|||
solution
|
||||
temp
|
||||
*.sppkg
|
||||
release
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"environment": "spo",
|
||||
"framework": "react",
|
||||
"isCreatingSolution": true,
|
||||
"version": "1.9.1",
|
||||
"version": "1.12.1",
|
||||
"libraryName": "navigator",
|
||||
"libraryId": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
||||
"packageManager": "npm",
|
||||
|
|
|
@ -8,22 +8,29 @@ When added to a Vertical Section it can be used as a Contents table for the page
|
|||
|
||||
![Page Navigator](./assets/PageNavigator.gif)
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
## Compatibility
|
||||
|
||||
![version](https://img.shields.io/badge/version-1.9.1-green.svg)
|
||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-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 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")
|
||||
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to the page structure")
|
||||
![Hosted Workbench Partially](https://img.shields.io/badge/Hosted%20Workbench-Partially-yellow.svg "The solution needs to run on a hosted page to work as intended")
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|September 5, 2019|Initial release
|
||||
1.1|October 20, 2021|SPFx Upgraded to 1.12.1 and code refactored
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- git clone the repo
|
||||
- npm i
|
||||
- gulp bundle --ship
|
||||
- gulp package-solution --ship
|
||||
- `git clone` the repo
|
||||
- `npm i`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- Add the app package to Site Collection App Catalog and Install the App
|
||||
- Add the web part to a page in the Site Collection
|
||||
|
||||
|
@ -31,10 +38,20 @@ Version|Date|Comments
|
|||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react-page-navigator|Aakash Bhardwaj
|
||||
react-page-navigator|[Aakash Bhardwaj](https://github.com/aakashbhardwaj619)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||
|
||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||
|
||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||
|
||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-page-navigator" />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"This web part fetches all the automatically added Header anchor tags in a SharePoint page and displays them in a Navigation component."
|
||||
],
|
||||
"creationDateTime": "2019-09-05",
|
||||
"updateDateTime": "2019-09-05",
|
||||
"updateDateTime": "2021-10-20",
|
||||
"products": [
|
||||
"SharePoint",
|
||||
"Office"
|
||||
|
@ -21,7 +21,7 @@
|
|||
},
|
||||
{
|
||||
"key": "SPFX-VERSION",
|
||||
"value": "1.9.1"
|
||||
"value": "1.12.1"
|
||||
}
|
||||
],
|
||||
"thumbnails": [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "temp/deploy"
|
||||
"deployCdnPath": "./release/assets/"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./temp/deploy/",
|
||||
"workingDir": "./release/assets/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "navigator",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"developer": {
|
||||
"name": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"websiteUrl": "",
|
||||
"mpnId": ""
|
||||
},
|
||||
"name": "react-page-navigator",
|
||||
"id": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
||||
"version": "1.0.0.0",
|
||||
"version": "1.1.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
|
|
|
@ -25,5 +25,12 @@ gulp.task('dev', gulpSequence('clean', 'bundle', 'package-solution'));
|
|||
* Custom Framework Specific gulp tasks
|
||||
*/
|
||||
|
||||
var getTasks = build.rig.getTasks;
|
||||
build.rig.getTasks = function () {
|
||||
var result = getTasks.call(build.rig);
|
||||
|
||||
result.set('serve', result.get('serve-deprecated'));
|
||||
|
||||
return result;
|
||||
};
|
||||
build.initialize(gulp);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,9 +3,6 @@
|
|||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
|
@ -15,36 +12,35 @@
|
|||
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "1.9.1",
|
||||
"@microsoft/sp-lodash-subset": "1.9.1",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.9.1",
|
||||
"@microsoft/sp-webpart-base": "1.9.1",
|
||||
"@microsoft/sp-core-library": "1.12.1",
|
||||
"@microsoft/sp-lodash-subset": "1.12.1",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.12.1",
|
||||
"@microsoft/sp-property-pane": "1.12.1",
|
||||
"@microsoft/sp-webpart-base": "1.12.1",
|
||||
"@pnp/pnpjs": "^1.3.5",
|
||||
"@pnp/spfx-controls-react": "1.14.0",
|
||||
"@pnp/spfx-property-controls": "1.16.0",
|
||||
"@types/es6-promise": "0.0.33",
|
||||
"@types/react": "16.8.8",
|
||||
"@types/react-dom": "16.8.3",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"office-ui-fabric-react": "^6.182.0",
|
||||
"react": "16.8.5",
|
||||
"react-dom": "16.8.5"
|
||||
"office-ui-fabric-react": "7.156.0",
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "16.8.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/rush-stack-compiler-3.3": "0.1.7",
|
||||
"@microsoft/sp-build-web": "1.9.1",
|
||||
"@microsoft/sp-module-interfaces": "1.9.1",
|
||||
"@microsoft/sp-tslint-rules": "1.9.1",
|
||||
"@microsoft/sp-webpart-workbench": "1.9.1",
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/mocha": "2.2.38",
|
||||
"@types/react": "^16.7.22",
|
||||
"@microsoft/rush-stack-compiler-3.7": "0.2.3",
|
||||
"@microsoft/sp-build-web": "1.12.1",
|
||||
"@microsoft/sp-module-interfaces": "1.12.1",
|
||||
"@microsoft/sp-tslint-rules": "1.12.1",
|
||||
"@microsoft/sp-webpart-workbench": "1.12.1",
|
||||
"@types/es6-promise": "0.0.33",
|
||||
"@types/react": "16.9.36",
|
||||
"@types/react-dom": "16.9.8",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
||||
"ajv": "~5.2.2",
|
||||
"gulp": "~3.9.1",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-sequence": "1.0.0",
|
||||
"jest": "^23.6.0"
|
||||
}
|
||||
|
|
|
@ -3,18 +3,49 @@ import { WebPartContext } from '@microsoft/sp-webpart-base';
|
|||
import { SPHttpClient } from '@microsoft/sp-http';
|
||||
|
||||
export class SPService {
|
||||
/* Array to store all unique anchor URLs */
|
||||
private static allUrls: string[] = [];
|
||||
|
||||
/**
|
||||
* Returns the unique Anchor URL for a heading
|
||||
* @param headingValue The text value of the heading
|
||||
* @returns anchorUrl
|
||||
*/
|
||||
private static GetAnchorUrl(headingValue: string): string {
|
||||
let urlExists = true;
|
||||
// .replace(/'|?|\|/| |&/g, "-") replaces any blanks and special characters (list is for sure not complete) with "-"
|
||||
// .replace(/--+/g, "-") replaces any additional - with only one -; e.g. --- get replaced with -, -- get replaced with - etc.
|
||||
let anchorUrl = `#${headingValue
|
||||
.replace(/\'|\?|\\|\/| |\&/g, "-")
|
||||
.replace(/--+/g, "-")}`.toLowerCase();
|
||||
let urlSuffix = 1;
|
||||
while (urlExists === true) {
|
||||
urlExists = (this.allUrls.indexOf(anchorUrl) === -1) ? false : true;
|
||||
if (urlExists) {
|
||||
anchorUrl = anchorUrl + `-${urlSuffix}`;
|
||||
urlSuffix++;
|
||||
}
|
||||
}
|
||||
return anchorUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Anchor Links for Nav element
|
||||
* @param context Web part context
|
||||
* @returns anchorLinks
|
||||
*/
|
||||
public static async GetAnchorLinks(context: WebPartContext) {
|
||||
let anchorLinks: INavLink[] = [];
|
||||
const anchorLinks: INavLink[] = [];
|
||||
|
||||
try {
|
||||
/* Page ID on which the web part is added */
|
||||
let pageId = context.pageContext.listItem.id;
|
||||
const pageId = context.pageContext.listItem.id;
|
||||
|
||||
/* Get the canvasContent1 data for the page which consists of all the HTML */
|
||||
let data = await context.spHttpClient.get(`${context.pageContext.web.absoluteUrl}/_api/sitepages/pages(${pageId})`, SPHttpClient.configurations.v1);
|
||||
let jsonData = await data.json();
|
||||
let canvasContent1 = jsonData.CanvasContent1;
|
||||
let canvasContent1JSON: any[] = JSON.parse(canvasContent1);
|
||||
const data = await context.spHttpClient.get(`${context.pageContext.web.absoluteUrl}/_api/sitepages/pages(${pageId})`, SPHttpClient.configurations.v1);
|
||||
const jsonData = await data.json();
|
||||
const canvasContent1 = jsonData.CanvasContent1;
|
||||
const canvasContent1JSON: any[] = JSON.parse(canvasContent1);
|
||||
|
||||
/* Initialize variables to be used for sorting and adding the Navigation links */
|
||||
let headingIndex = 0;
|
||||
|
@ -22,9 +53,6 @@ export class SPService {
|
|||
let headingOrder = 0;
|
||||
let prevHeadingOrder = 0;
|
||||
|
||||
/* Array to store all unique anchor URLs */
|
||||
let allUrls: string[] = [];
|
||||
|
||||
/* Traverse through all the Text web parts in the page */
|
||||
canvasContent1JSON.map((webPart) => {
|
||||
if (webPart.innerHTML) {
|
||||
|
@ -34,28 +62,14 @@ export class SPService {
|
|||
/* The Header Text value */
|
||||
// .replace(/<.+?>/gi, "") replaces in the headingValue any html tags like <strong> </strong>
|
||||
// .replace(/&.+;/gi, "") replaces in the headingValue any &****; tags like
|
||||
let headingValue = HTMLString.substring(HTMLString.search(/<h[1-4]>/g) + 4, HTMLString.search(/<\/h[1-4]>/g))
|
||||
const headingValue = HTMLString.substring(HTMLString.search(/<h[1-4]>/g) + 4, HTMLString.search(/<\/h[1-4]>/g))
|
||||
.replace(/<.+?>/gi, "")
|
||||
.replace(/\&.+\;/gi, "");
|
||||
|
||||
headingOrder = parseInt(HTMLString.charAt(HTMLString.search(/<h[1-4]>/g) + 2));
|
||||
|
||||
/* Check if same anchorUrl already exists */
|
||||
let urlExists = true;
|
||||
// .replace(/'|?|\|/| |&/g, "-") replaces any blanks and special characters (list is for sure not complete) with "-"
|
||||
// .replace(/--+/g, "-") replaces any additional - with only one -; e.g. --- get replaced with -, -- get replaced with - etc.
|
||||
let anchorUrl = `#${headingValue
|
||||
.replace(/\'|\?|\\|\/| |\&/g, "-")
|
||||
.replace(/--+/g, "-")}`.toLowerCase();
|
||||
let urlSuffix = 1;
|
||||
while (urlExists === true) {
|
||||
urlExists = (allUrls.indexOf(anchorUrl) === -1) ? false : true;
|
||||
if (urlExists) {
|
||||
anchorUrl = anchorUrl + `-${urlSuffix}`;
|
||||
urlSuffix++;
|
||||
}
|
||||
}
|
||||
allUrls.push(anchorUrl);
|
||||
const anchorUrl = this.GetAnchorUrl(headingValue);
|
||||
this.allUrls.push(anchorUrl);
|
||||
|
||||
/* Add links to Nav element */
|
||||
if (anchorLinks.length === 0) {
|
||||
|
@ -63,33 +77,42 @@ export class SPService {
|
|||
} else {
|
||||
if (headingOrder <= prevHeadingOrder) {
|
||||
/* Adding or Promoting links */
|
||||
if (headingOrder === 2) {
|
||||
anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
headingIndex++;
|
||||
subHeadingIndex = -1;
|
||||
} else {
|
||||
if (headingOrder === 4) {
|
||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
} else if (headingOrder === 3) {
|
||||
switch (headingOrder) {
|
||||
case 2:
|
||||
anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
headingIndex++;
|
||||
subHeadingIndex = -1;
|
||||
break;
|
||||
case 4:
|
||||
if (subHeadingIndex > -1) {
|
||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
} else {
|
||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
subHeadingIndex++;
|
||||
}
|
||||
subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Making sub links */
|
||||
if (headingOrder === 3) {
|
||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
subHeadingIndex++;
|
||||
subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
|
||||
} else {
|
||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
if (subHeadingIndex > -1) {
|
||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
} else {
|
||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prevHeadingOrder = headingOrder;
|
||||
|
||||
/* Replace the added header links from the string so they don't get processed again */
|
||||
HTMLString = HTMLString.replace(`<h${headingOrder}>`, '');
|
||||
HTMLString = HTMLString.replace(`</h${headingOrder}>`, '');
|
||||
HTMLString = HTMLString.replace(`<h${headingOrder}>`, '').replace(`</h${headingOrder}>`, '');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -97,7 +120,7 @@ export class SPService {
|
|||
console.log(error);
|
||||
}
|
||||
|
||||
console.log(anchorLinks);
|
||||
console.log('anchorLinks', anchorLinks);
|
||||
return anchorLinks;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,8 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneTextField
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
|
||||
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
||||
import * as strings from 'PageNavigatorWebPartStrings';
|
||||
import PageNavigator from './components/PageNavigator';
|
||||
import { IPageNavigatorProps } from './components/IPageNavigatorProps';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.7/includes/tsconfig-web.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
@ -19,20 +19,18 @@
|
|||
"./node_modules/@microsoft"
|
||||
],
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection"
|
||||
"es2015.collection",
|
||||
"es2015.promise"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"lib"
|
||||
]
|
||||
"exclude": []
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
||||
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"export-name": false,
|
||||
|
|
Loading…
Reference in New Issue