react-page-nav SPFx upgrade and code refactoring
This commit is contained in:
parent
1911f8a5c8
commit
abb9e5a720
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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