Merge pull request #3649 from ValerasNarbutas/update-version-and-fix-react-accordion-dynamic-section

This commit is contained in:
Hugo Bernier 2023-04-02 21:42:43 -04:00 committed by GitHub
commit 6aa4639d5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 3651 additions and 4148 deletions

View File

@ -1,7 +1,7 @@
// For more information on how to run this SPFx project in a VS Code Remote Container, please visit https://aka.ms/spfx-devcontainer
{
"name": "SPFx 1.10.0",
"image": "docker.io/m365pnp/spfx:1.10.0",
"name": "SPFx 1.16.1",
"image": "docker.io/m365pnp/spfx:1.16.1",
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
@ -12,8 +12,7 @@
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
4321,
35729,
5432
35729
],
"portsAttributes": {
"4321": {
@ -22,11 +21,12 @@
"onAutoForward": "silent",
"requireLocalPort": true
},
"5432": {
"protocol": "https",
"label": "Workbench",
"onAutoForward": "silent"
},
// Not needed for SPFx>= 1.12.1
// "5432": {
// "protocol": "https",
// "label": "Workbench",
// "onAutoForward": "silent"
// },
"35729": {
"protocol": "https",
"label": "LiveReload",

View File

@ -7,9 +7,11 @@ echo
echo -e "\e[1;94mGenerating dev certificate\e[0m"
gulp trust-dev-cert
# Convert the generated PEM certificate to a CER certificate
openssl x509 -inform PEM -in ~/.rushstack/rushstack-serve.pem -outform DER -out ./spfx-dev-cert.cer
cp ~/.gcb-serve-data/gcb-serve.cer ./spfx-dev-cert.cer
cp ~/.gcb-serve-data/gcb-serve.cer ./spfx-dev-cert.pem
# Copy the PEM ecrtificate for non-Windows hosts
cp ~/.rushstack/rushstack-serve.pem ./spfx-dev-cert.pem
## add *.cer to .gitignore to prevent certificates from being saved in repo
if ! grep -Fxq '*.cer' ./.gitignore

View File

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

View File

@ -30,3 +30,6 @@ obj
# Styles Generated Code
*.scss.ts
release
.heft

View File

@ -0,0 +1,16 @@
!dist
config
gulpfile.js
release
src
temp
tsconfig.json
tslint.json
*.log
.yo-rc.json
.vscode

View File

@ -38,8 +38,8 @@
| 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. |
![SPFx 1.10.0](https://img.shields.io/badge/SPFx-1.10.0-green.svg)
![Node.js v10](https://img.shields.io/badge/Node.js-v10-green.svg)
![SPFx 1.16.1](https://img.shields.io/badge/SPFx-1.16.1-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)
![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")
@ -61,6 +61,7 @@ Please create the list as described above
* [Erik Benke](https://github.com/ejbenke)
* [Ari Gunawan](https://github.com/AriGunawan)
* [Valeras Narbutas](https://github.com/ValerasNarbutas)
## Version history
@ -69,6 +70,7 @@ Please create the list as described above
| 1.0 | September 20, 2020 | Reused [Erik Benke] and [Mike Zimmerman] web part |
| 1.1 | September 20, 2020 | Added Support for Dynamic Column selection for reuseability, Dynamic Property Selection for Columns |
| 1.8 | August 8, 2021 | Add configuration for sorting the items |
| 2.0 | April 2, 2023 | Upgarde to SPFX 1.16.1 |

View File

@ -20,7 +20,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.10.0"
"value": "1.16.1"
},
{
"key": "SPFX-TEAMSTAB",

View File

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

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": "react-accordion",
"accessKey": "<!-- ACCESS KEY -->"

View File

@ -3,9 +3,38 @@
"solution": {
"name": "Accordion Section FAQ Builder",
"id": "bf6fa974-fd40-45a3-80e9-e826abe025b9",
"version": "1.7.0.0",
"version": "2.0.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true
"skipFeatureDeployment": true,
"developer": {
"name": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"websiteUrl": "",
"mpnId": "Undefined-1.15.0"
},
"metadata": {
"shortDescription": {
"default": "react-accordion description"
},
"longDescription": {
"default": "react-accordion description"
},
"screenshotPaths": [],
"videoUrl": "",
"categories": []
},
"features": [
{
"title": "react-accordion ReactAccordionWebPart Feature",
"description": "The feature that activates ReactAccordionWebPart from the react-accordion solution.",
"id": "061da2cd-f680-4da5-ab30-40a8ba1aafd8",
"version": "2.0.0.0",
"componentIds": [
"061da2cd-f680-4da5-ab30-40a8ba1aafd8"
]
}
]
},
"paths": {
"zippedPackage": "solution/DynamicFAQ-Accordion.sppkg"

View File

@ -0,0 +1,3 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json"
}

View File

@ -1,10 +1,6 @@
{
"$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,
"https": true,
"initialPage": "https://localhost:5432/workbench",
"api": {
"port": 5432,
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
}
"initialPage": "https://enter-your-SharePoint-site/_layouts/workbench.aspx",
}

View File

@ -4,4 +4,13 @@ const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
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

@ -4,7 +4,7 @@
"version": "1.6.0",
"private": true,
"engines": {
"node": ">=0.10.0"
"node": ">=16.13.0 <17.0.0"
},
"scripts": {
"build": "gulp bundle",
@ -12,40 +12,46 @@
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.10.0",
"@microsoft/sp-lodash-subset": "1.10.0",
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
"@microsoft/sp-property-pane": "1.10.0",
"@microsoft/sp-webpart-base": "1.10.0",
"@pnp/common": "^2.0.10",
"@pnp/logging": "^2.0.10",
"@pnp/odata": "^2.0.10",
"@pnp/sp": "^2.0.10",
"@pnp/pnpjs": "2.0.10",
"@microsoft/sp-adaptive-card-extension-base": "1.16.1",
"@microsoft/sp-core-library": "1.16.1",
"@microsoft/sp-lodash-subset": "1.16.1",
"@microsoft/sp-office-ui-fabric-core": "1.16.1",
"@microsoft/sp-property-pane": "1.16.1",
"@microsoft/sp-tslint-rules": "^1.16.1",
"@microsoft/sp-webpart-base": "1.16.1",
"@pnp/common": "^2.15.0",
"@pnp/graph": "^1.3.11",
"@pnp/logging": "^3.13.0",
"@pnp/odata": "^2.15.0",
"@pnp/pnpjs": "^2.15.0",
"@pnp/sp": "^3.13.0",
"@pnp/spfx-controls-react": "1.14.0",
"@pnp/spfx-property-controls": "1.19.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.189.2",
"react": "16.8.5",
"office-ui-fabric-react": "7.199.1",
"react": "17.0.1",
"react-accessible-accordion": "^3.0.0",
"react-dom": "16.8.5"
"react-dom": "17.0.1",
"tslib": "2.3.1"
},
"resolutions": {
"@types/react": "16.8.8"
},
"devDependencies": {
"@microsoft/rush-stack-compiler-2.9": "0.7.7",
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
"@microsoft/eslint-config-spfx": "1.16.1",
"@microsoft/eslint-plugin-spfx": "1.16.1",
"@microsoft/rush-stack-compiler-4.5": "0.2.2",
"@microsoft/sp-build-web": "1.16.1",
"@microsoft/sp-module-interfaces": "1.10.0",
"@microsoft/sp-tslint-rules": "1.10.0",
"@microsoft/sp-webpart-workbench": "1.12.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2",
"gulp": "~3.9.1"
"@microsoft/sp-module-interfaces": "1.16.1",
"@rushstack/eslint-config": "2.5.1",
"@types/react": "17.0.45",
"@types/react-dom": "17.0.17",
"@types/webpack-env": "1.15.2",
"ajv": "6.12.5",
"eslint": "8.7.0",
"eslint-plugin-react-hooks": "4.3.0",
"gulp": "4.0.2",
"typescript": "4.5.5",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1"
}
}

View File

@ -0,0 +1,21 @@
import { WebPartContext } from "@microsoft/sp-webpart-base";
// import pnp, pnp logging system, and any other selective imports needed
import { spfi, SPFI, SPFx } from "@pnp/sp";
import { LogLevel, PnPLogging } from "@pnp/logging";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/batching";
import "@pnp/sp/fields";
let _sp: SPFI = null;
export const getSP = (context?: WebPartContext): SPFI => {
if (context != null) {
//You must add the @pnp/logging package to include the PnPLogging behavior it is no longer a peer dependency
// The LogLevel set's at what level a message will be written to the console
_sp = spfi().using(SPFx(context)).using(PnPLogging(LogLevel.Warning));
}
return _sp;
};

View File

@ -4,15 +4,11 @@ import { Version } from "@microsoft/sp-core-library";
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import {
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneToggle,
PropertyPaneDropdown,
IPropertyPaneDropdownOption,
} from "@microsoft/sp-property-pane";
import { sp } from "@pnp/sp/presets/all";
import "core-js/es6/array";
import "es6-map/implement";
import "core-js/modules/es6.array.find";
import {
PropertyFieldListPicker,
PropertyFieldListPickerOrderBy,
@ -21,10 +17,10 @@ import {
import * as strings from "ReactAccordionWebPartStrings";
import ReactAccordion from "./components/ReactAccordion";
import { IReactAccordionProps } from "./components/IReactAccordionProps";
import { string } from "prop-types";
import { Webs } from "@pnp/sp/webs";
import { Lists } from "@pnp/sp/lists";
import { IField, FieldTypes } from "@pnp/sp/fields";
import { getSP } from "../../utils/pnpjs-config"
import { SPFI } from "@pnp/sp";
import { IField, IFieldInfo } from "@pnp/sp/fields";
export interface IReactAccordionWebPartProps {
listId: string;
@ -42,19 +38,22 @@ export interface IReactAccordionWebPartProps {
export default class ReactAccordionWebPart extends BaseClientSideWebPart<
IReactAccordionWebPartProps
> {
private listColumns: IPropertyPaneDropdownOption[];
private _sp: SPFI;
private listColumns: IPropertyPaneDropdownOption[];spfxContext
private allListColumns: IPropertyPaneDropdownOption[];
private columnChoices: IPropertyPaneDropdownOption[];
private columnsDropdownDisabled: boolean = true;
private choicesDropdownDisabled: boolean = true;
private columnsDropdownDisabled = true;
private choicesDropdownDisabled = true;
public onInit(): Promise<void> {
return super.onInit().then((_) => {
sp.setup({
spfxContext: this.context,
});
});
protected async onInit(): Promise<void> {
super.onInit();
//Initialize our _sp object that we can then use in other packages without having to pass around the context.
// Check out pnpjsConfig.ts for an example of a project setup file.
this._sp = getSP(this.context);
}
public render(): void {
@ -99,21 +98,21 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
return new Promise<IPropertyPaneDropdownOption[]>(
(
resolve: (options: IPropertyPaneDropdownOption[]) => void,
reject: (error: any) => void
reject: (error) => void
) => {
if (!this.properties.listId) {
console.log("No List Selected");
return null;
}
var spListColumns = sp.web.lists
const spListColumns = this._sp.web.lists
.getById(this.properties.listId)
.fields.filter(
"ReadOnlyField eq false and Hidden eq false and TypeAsString eq 'Choice'"
)
.get();
();
spListColumns.then((columnResult) => {
let listColumns = [];
const listColumns = [];
columnResult.forEach((column) => {
listColumns.push({
key: column.Title,
@ -121,6 +120,8 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
});
});
resolve(listColumns);
}).catch((error) => {
reject(error);
});
}
);
@ -129,19 +130,19 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
return new Promise<IPropertyPaneDropdownOption[]>(
(
resolve: (options: IPropertyPaneDropdownOption[]) => void,
reject: (error: any) => void
reject: (error) => void
) => {
if (!this.properties.listId) {
console.log("No List Selected");
return null;
}
var spListColumns = sp.web.lists
const spListColumns = this._sp.web.lists
.getById(this.properties.listId)
.fields.filter("ReadOnlyField eq false and Hidden eq false")
.get();
();
spListColumns.then((columnResult) => {
let listColumns = [];
const listColumns = [];
columnResult.forEach((column) => {
listColumns.push({
key: column.InternalName,
@ -149,6 +150,8 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
});
});
resolve(listColumns);
}).catch((error) => {
reject(error);
});
}
);
@ -158,21 +161,22 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
return new Promise<IPropertyPaneDropdownOption[]>(
(
resolve: (options: IPropertyPaneDropdownOption[]) => void,
reject: (error: any) => void
reject: (error) => void
) => {
if (!this.properties.columnTitle) {
console.log("No Columns Selected");
return null;
}
const categoryField: IField = sp.web.lists
const categoryField: IField = this._sp.web.lists
.getById(this.properties.listId)
.fields.getByInternalNameOrTitle(this.properties.columnTitle);
let choices: any = categoryField.select("Choices")();
const choices: Promise<IFieldInfo> = categoryField.select("Choices")();
choices.then((result) => {
//console.clear();
//console.log(result.Choices);
let columnChoices = [];
// console.clear();
// console.log(result.Choices);
const columnChoices = [];
result.Choices.forEach((choice) => {
columnChoices.push({
key: choice,
@ -180,6 +184,8 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
});
});
resolve(columnChoices);
}).catch((error) => {
reject(error);
});
}
);
@ -230,15 +236,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<
}
}
protected onPropertyPaneFieldChanged(
propertyPath: string,
oldValue: any,
newValue: any
): void {
// push new list value
// communicate loading items
protected onPropertyPaneFieldChanged(): void {
if (this.properties.listId) {
this.context.statusRenderer.displayLoadingIndicator(
this.domElement,

View File

@ -1,5 +1,5 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
@import '~office-ui-fabric-react/dist/sass/References.scss';
@import '~@fluentui/react/dist/sass/References.scss';
.reactAccordion {
.container {

View File

@ -1,16 +1,16 @@
/* tslint:disable */
require("./ReactAccordion.module.css");
const styles = {
reactAccordion: 'reactAccordion_b579c085',
container: 'container_b579c085',
row: 'row_b579c085',
column: 'column_b579c085',
'ms-Grid': 'ms-Grid_b579c085',
title: 'title_b579c085',
subTitle: 'subTitle_b579c085',
description: 'description_b579c085',
button: 'button_b579c085',
label: 'label_b579c085'
reactAccordion: 'reactAccordion_d9565bf5',
container: 'container_d9565bf5',
row: 'row_d9565bf5',
column: 'column_d9565bf5',
'ms-Grid': 'ms-Grid_d9565bf5',
title: 'title_d9565bf5',
subTitle: 'subTitle_d9565bf5',
description: 'description_d9565bf5',
button: 'button_d9565bf5',
label: 'label_d9565bf5'
};
export default styles;

View File

@ -1,7 +1,6 @@
import * as React from "react";
import styles from "./ReactAccordion.module.scss";
import { IReactAccordionProps } from "./IReactAccordionProps";
import { sp } from "@pnp/sp/presets/all";
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
import "./reactAccordion.css";
@ -13,10 +12,12 @@ import {
AccordionItemButton,
AccordionItemPanel,
} from "react-accessible-accordion";
import { getSP } from "../../../utils/pnpjs-config";
import { SPFI } from "@pnp/sp";
export interface IReactAccordionState {
items: Array<any>;
choices: Array<any>;
items: Array<string>;
choices: Array<string>;
allowMultipleExpanded: boolean;
allowZeroExpanded: boolean;
}
@ -25,15 +26,20 @@ export default class ReactAccordion extends React.Component<
IReactAccordionProps,
IReactAccordionState
> {
private _sp: SPFI;
constructor(props: IReactAccordionProps) {
super(props);
this.state = {
items: new Array<any>(),
choices: new Array<any>(),
items: new Array<string>(),
choices: new Array<string>(),
allowMultipleExpanded: this.props.allowMultipleExpanded,
allowZeroExpanded: this.props.allowZeroExpanded,
};
this._sp = getSP();
this.getListItems();
}
@ -53,7 +59,7 @@ export default class ReactAccordion extends React.Component<
</OrderBy>`;
}
let query = `<View>
const query = `<View>
<Query>
<Where>
<Eq>
@ -65,17 +71,17 @@ export default class ReactAccordion extends React.Component<
</Query>
</View>`;
let theAccordianList = sp.web.lists.getById(this.props.listId);
const theAccordianList = this._sp.web.lists.getById(this.props.listId);
theAccordianList
.getItemsByCAMLQuery({
ViewXml: query,
}) //.select("Title", "Answer", "Category")
.then((results: Array<any>) => {
.then((results: Array<string>) => {
this.setState({
items: results,
});
})
.catch((error: any) => {
.catch((error) => {
console.log("Failed to get list items!");
console.log(error);
});
@ -124,9 +130,9 @@ export default class ReactAccordion extends React.Component<
allowZeroExpanded={allowZeroExpanded}
allowMultipleExpanded={allowMultipleExpanded}
>
{this.state.items.map((item: any) => {
{this.state.items.map((item: string) => {
return (
<AccordionItem>
<AccordionItem key={item}>
<AccordionItemHeading>
<AccordionItemButton
title={item[this.props.accordianTitleColumn]}

View File

@ -1,5 +1,5 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
@ -14,25 +14,24 @@
"inlineSources": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"noImplicitAny": false,
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
],
"types": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
"es2015.collection",
"es2015.promise",
"es2015"
]
},
"include": [
"src/**/*.ts"
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

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