react-page-nav SPFx upgrade and code refactoring

This commit is contained in:
Aakash Bhardwaj 2021-10-20 10:40:41 +05:30
parent 1911f8a5c8
commit abb9e5a720
15 changed files with 16635 additions and 8166 deletions

View File

@ -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

View File

@ -12,6 +12,7 @@ lib
solution
temp
*.sppkg
release
# Coverage directory used by tools like istanbul
coverage

View File

@ -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",

View File

@ -10,13 +10,14 @@ When added to a Vertical Section it can be used as a Contents table for the page
## Used SharePoint Framework Version
![version](https://img.shields.io/badge/version-1.9.1-green.svg)
![version](https://img.shields.io/badge/version-1.12.1-green.svg)
## 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

View File

@ -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": [

View File

@ -1,4 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
"deployCdnPath": "./release/assets/"
}

View File

@ -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 -->"

View File

@ -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
},

View File

@ -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

View File

@ -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"
}

View File

@ -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 &nbsp;
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;
}
}

View File

@ -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';

View File

@ -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": []
}

View File

@ -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,