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 solution
temp temp
*.sppkg *.sppkg
release
# Coverage directory used by tools like istanbul # Coverage directory used by tools like istanbul
coverage coverage

View File

@ -18,7 +18,7 @@
"environment": "spo", "environment": "spo",
"framework": "react", "framework": "react",
"isCreatingSolution": true, "isCreatingSolution": true,
"version": "1.9.1", "version": "1.12.1",
"libraryName": "navigator", "libraryName": "navigator",
"libraryId": "065ee566-e00d-4058-bbfd-356c8d9a8005", "libraryId": "065ee566-e00d-4058-bbfd-356c8d9a8005",
"packageManager": "npm", "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 ## 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 history
Version|Date|Comments Version|Date|Comments
-------|----|-------- -------|----|--------
1.0|September 5, 2019|Initial release 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 ## 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." "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", "creationDateTime": "2019-09-05",
"updateDateTime": "2019-09-05", "updateDateTime": "2021-10-20",
"products": [ "products": [
"SharePoint", "SharePoint",
"Office" "Office"
@ -21,7 +21,7 @@
}, },
{ {
"key": "SPFX-VERSION", "key": "SPFX-VERSION",
"value": "1.9.1" "value": "1.12.1"
} }
], ],
"thumbnails": [ "thumbnails": [

View File

@ -1,4 +1,4 @@
{ {
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json", "$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", "$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": "navigator", "container": "navigator",
"accessKey": "<!-- ACCESS KEY -->" "accessKey": "<!-- ACCESS KEY -->"

View File

@ -1,9 +1,16 @@
{ {
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json", "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": { "solution": {
"developer": {
"name": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"websiteUrl": "",
"mpnId": ""
},
"name": "react-page-navigator", "name": "react-page-navigator",
"id": "065ee566-e00d-4058-bbfd-356c8d9a8005", "id": "065ee566-e00d-4058-bbfd-356c8d9a8005",
"version": "1.0.0.0", "version": "1.1.0.0",
"includeClientSideAssets": true, "includeClientSideAssets": true,
"isDomainIsolated": false "isDomainIsolated": false
}, },

View File

@ -25,5 +25,12 @@ gulp.task('dev', gulpSequence('clean', 'bundle', 'package-solution'));
* Custom Framework Specific gulp tasks * 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); build.initialize(gulp);

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,6 @@
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"main": "lib/index.js", "main": "lib/index.js",
"engines": {
"node": ">=0.10.0"
},
"scripts": { "scripts": {
"build": "gulp bundle", "build": "gulp bundle",
"clean": "gulp clean", "clean": "gulp clean",
@ -15,36 +12,35 @@
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll" "test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
}, },
"dependencies": { "dependencies": {
"@microsoft/sp-core-library": "1.9.1", "@microsoft/sp-core-library": "1.12.1",
"@microsoft/sp-lodash-subset": "1.9.1", "@microsoft/sp-lodash-subset": "1.12.1",
"@microsoft/sp-office-ui-fabric-core": "1.9.1", "@microsoft/sp-office-ui-fabric-core": "1.12.1",
"@microsoft/sp-webpart-base": "1.9.1", "@microsoft/sp-property-pane": "1.12.1",
"@microsoft/sp-webpart-base": "1.12.1",
"@pnp/pnpjs": "^1.3.5", "@pnp/pnpjs": "^1.3.5",
"@pnp/spfx-controls-react": "1.14.0", "@pnp/spfx-controls-react": "1.14.0",
"@pnp/spfx-property-controls": "1.16.0", "@pnp/spfx-property-controls": "1.16.0",
"@types/es6-promise": "0.0.33", "office-ui-fabric-react": "7.156.0",
"@types/react": "16.8.8", "react": "16.9.0",
"@types/react-dom": "16.8.3", "react-dom": "16.9.0"
"@types/webpack-env": "1.13.1",
"office-ui-fabric-react": "^6.182.0",
"react": "16.8.5",
"react-dom": "16.8.5"
}, },
"resolutions": { "resolutions": {
"@types/react": "16.8.8" "@types/react": "16.8.8"
}, },
"devDependencies": { "devDependencies": {
"@microsoft/rush-stack-compiler-3.3": "0.1.7", "@microsoft/rush-stack-compiler-3.3": "0.1.7",
"@microsoft/sp-build-web": "1.9.1", "@microsoft/rush-stack-compiler-3.7": "0.2.3",
"@microsoft/sp-module-interfaces": "1.9.1", "@microsoft/sp-build-web": "1.12.1",
"@microsoft/sp-tslint-rules": "1.9.1", "@microsoft/sp-module-interfaces": "1.12.1",
"@microsoft/sp-webpart-workbench": "1.9.1", "@microsoft/sp-tslint-rules": "1.12.1",
"@types/chai": "3.4.34", "@microsoft/sp-webpart-workbench": "1.12.1",
"@types/mocha": "2.2.38", "@types/es6-promise": "0.0.33",
"@types/react": "^16.7.22", "@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", "@voitanos/jest-preset-spfx-react16": "^1.1.0",
"ajv": "~5.2.2", "ajv": "~5.2.2",
"gulp": "~3.9.1", "gulp": "4.0.2",
"gulp-sequence": "1.0.0", "gulp-sequence": "1.0.0",
"jest": "^23.6.0" "jest": "^23.6.0"
} }

View File

@ -3,18 +3,49 @@ import { WebPartContext } from '@microsoft/sp-webpart-base';
import { SPHttpClient } from '@microsoft/sp-http'; import { SPHttpClient } from '@microsoft/sp-http';
export class SPService { 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) { public static async GetAnchorLinks(context: WebPartContext) {
let anchorLinks: INavLink[] = []; const anchorLinks: INavLink[] = [];
try { try {
/* Page ID on which the web part is added */ /* 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 */ /* 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); const data = await context.spHttpClient.get(`${context.pageContext.web.absoluteUrl}/_api/sitepages/pages(${pageId})`, SPHttpClient.configurations.v1);
let jsonData = await data.json(); const jsonData = await data.json();
let canvasContent1 = jsonData.CanvasContent1; const canvasContent1 = jsonData.CanvasContent1;
let canvasContent1JSON: any[] = JSON.parse(canvasContent1); const canvasContent1JSON: any[] = JSON.parse(canvasContent1);
/* Initialize variables to be used for sorting and adding the Navigation links */ /* Initialize variables to be used for sorting and adding the Navigation links */
let headingIndex = 0; let headingIndex = 0;
@ -22,9 +53,6 @@ export class SPService {
let headingOrder = 0; let headingOrder = 0;
let prevHeadingOrder = 0; let prevHeadingOrder = 0;
/* Array to store all unique anchor URLs */
let allUrls: string[] = [];
/* Traverse through all the Text web parts in the page */ /* Traverse through all the Text web parts in the page */
canvasContent1JSON.map((webPart) => { canvasContent1JSON.map((webPart) => {
if (webPart.innerHTML) { if (webPart.innerHTML) {
@ -34,28 +62,14 @@ export class SPService {
/* The Header Text value */ /* The Header Text value */
// .replace(/<.+?>/gi, "") replaces in the headingValue any html tags like <strong> </strong> // .replace(/<.+?>/gi, "") replaces in the headingValue any html tags like <strong> </strong>
// .replace(/&.+;/gi, "") replaces in the headingValue any &****; tags like &nbsp; // .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, "")
.replace(/\&.+\;/gi, ""); .replace(/\&.+\;/gi, "");
headingOrder = parseInt(HTMLString.charAt(HTMLString.search(/<h[1-4]>/g) + 2)); headingOrder = parseInt(HTMLString.charAt(HTMLString.search(/<h[1-4]>/g) + 2));
/* Check if same anchorUrl already exists */ const anchorUrl = this.GetAnchorUrl(headingValue);
let urlExists = true; this.allUrls.push(anchorUrl);
// .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);
/* Add links to Nav element */ /* Add links to Nav element */
if (anchorLinks.length === 0) { if (anchorLinks.length === 0) {
@ -63,33 +77,42 @@ export class SPService {
} else { } else {
if (headingOrder <= prevHeadingOrder) { if (headingOrder <= prevHeadingOrder) {
/* Adding or Promoting links */ /* Adding or Promoting links */
if (headingOrder === 2) { switch (headingOrder) {
case 2:
anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true }); anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
headingIndex++; headingIndex++;
subHeadingIndex = -1; subHeadingIndex = -1;
} else { break;
if (headingOrder === 4) { case 4:
if (subHeadingIndex > -1) {
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true }); anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
} else if (headingOrder === 3) { } else {
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true }); anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
subHeadingIndex++;
} }
break;
default:
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
break;
} }
} else { } else {
/* Making sub links */ /* Making sub links */
if (headingOrder === 3) { if (headingOrder === 3) {
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true }); anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
subHeadingIndex++; subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
} else { } else {
if (subHeadingIndex > -1) {
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true }); 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; prevHeadingOrder = headingOrder;
/* Replace the added header links from the string so they don't get processed again */ /* 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}>`, '').replace(`</h${headingOrder}>`, '');
HTMLString = HTMLString.replace(`</h${headingOrder}>`, '');
} }
} }
}); });
@ -97,7 +120,7 @@ export class SPService {
console.log(error); console.log(error);
} }
console.log(anchorLinks); console.log('anchorLinks', anchorLinks);
return anchorLinks; return anchorLinks;
} }
} }

View File

@ -1,12 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDom from 'react-dom'; import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library'; import { Version } from '@microsoft/sp-core-library';
import { import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
BaseClientSideWebPart, import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import * as strings from 'PageNavigatorWebPartStrings'; import * as strings from 'PageNavigatorWebPartStrings';
import PageNavigator from './components/PageNavigator'; import PageNavigator from './components/PageNavigator';
import { IPageNavigatorProps } from './components/IPageNavigatorProps'; 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": { "compilerOptions": {
"target": "es5", "target": "es5",
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
@ -19,20 +19,18 @@
"./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"
], ],
"exclude": [ "exclude": []
"node_modules",
"lib"
]
} }

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": { "rules": {
"class-name": false, "class-name": false,
"export-name": false, "export-name": false,