update to latest spfx
This commit is contained in:
parent
68eef8b764
commit
10d7c60ebd
|
@ -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 }
|
||||||
|
};
|
|
@ -1,3 +1,6 @@
|
||||||
|
.heft
|
||||||
|
release
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
{
|
{
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"environment": "spo",
|
||||||
|
"componentType": "webpart",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"sdkVersions": {
|
||||||
|
"@microsoft/teams-js": "2.9.1",
|
||||||
|
"@microsoft/microsoft-graph-client": "3.0.2"
|
||||||
|
},
|
||||||
|
"nodeVersion": "16.20.0",
|
||||||
"libraryName": "react-property-bag-editor",
|
"libraryName": "react-property-bag-editor",
|
||||||
"libraryId": "12dac38e-b255-44ce-9f06-050571b34d39",
|
"libraryId": "12dac38e-b255-44ce-9f06-050571b34d39",
|
||||||
"framework": "react"
|
"version": "1.17.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,6 +47,8 @@ Version|Date|Comments
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
|
- This project uses the JSOM to interact with the property bag. Therefore in config/config.js you need to change the paths
|
||||||
|
on the externals sp-init,microsoft-ajax,sp-runtime, and sharepoint to point to your tenant.
|
||||||
- in the command line run:
|
- in the command line run:
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `gulp serve`
|
- `gulp serve`
|
||||||
|
|
|
@ -1,26 +1,6 @@
|
||||||
{
|
{
|
||||||
"entries": [
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
{
|
"version": "2.0",
|
||||||
"entry": "./lib/webparts/propertyBagEditor/PropertyBagEditorWebPart.js",
|
|
||||||
"manifest": "./src/webparts/propertyBagEditor/PropertyBagEditorWebPart.manifest.json",
|
|
||||||
"outputPath": "./dist/property-bag-editor.bundle.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"entry": "./lib/webparts/propertyBagDisplay/PropertyBagDisplayWebPart.js",
|
|
||||||
"manifest": "./src/webparts/propertyBagDisplay/PropertyBagDisplayWebPart.manifest.json",
|
|
||||||
"outputPath": "./dist/property-bag-display.bundle.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"entry": "./lib/webparts/propertyBagFilteredSiteList/PropertyBagFilteredSiteListWebPart.js",
|
|
||||||
"manifest": "./src/webparts/propertyBagFilteredSiteList/PropertyBagFilteredSiteListWebPart.manifest.json",
|
|
||||||
"outputPath": "./dist/property-bag-filtered-site-list.bundle.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"entry": "./lib/webparts/propertyBagGlobalNav/PropertyBagGlobalNavWebPart.js",
|
|
||||||
"manifest": "./src/webparts/propertyBagGlobalNav/PropertyBagGlobalNavWebPart.manifest.json",
|
|
||||||
"outputPath": "./dist/property-bag-global-nav.bundle.js"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"externals": {
|
"externals": {
|
||||||
"sp-pnp-js": "https://cdnjs.cloudflare.com/ajax/libs/sp-pnp-js/2.0.1/pnp.min.js",
|
"sp-pnp-js": "https://cdnjs.cloudflare.com/ajax/libs/sp-pnp-js/2.0.1/pnp.min.js",
|
||||||
"sp-init": {
|
"sp-init": {
|
||||||
|
@ -50,9 +30,43 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"localizedResources": {
|
"localizedResources": {
|
||||||
"propertyBagEditorStrings": "webparts/propertyBagEditor/loc/{locale}.js",
|
"propertyBagEditorStrings": "lib/webparts/propertyBagEditor/loc/{locale}.js",
|
||||||
"propertyBagDisplayStrings": "webparts/propertyBagDisplay/loc/{locale}.js",
|
"propertyBagDisplayStrings": "lib/webparts/propertyBagDisplay/loc/{locale}.js",
|
||||||
"propertyBagFilteredSiteListStrings": "webparts/propertyBagFilteredSiteList/loc/{locale}.js",
|
"propertyBagFilteredSiteListStrings": "lib/webparts/propertyBagFilteredSiteList/loc/{locale}.js",
|
||||||
"propertyBagGlobalNavStrings": "webparts/propertyBagGlobalNav/loc/{locale}.js"
|
"propertyBagGlobalNavStrings": "lib/webparts/propertyBagGlobalNav/loc/{locale}.js"
|
||||||
|
},
|
||||||
|
"bundles": {
|
||||||
|
"property-bag-editor-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/propertyBagEditor/PropertyBagEditorWebPart.js",
|
||||||
|
"manifest": "./src/webparts/propertyBagEditor/PropertyBagEditorWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"property-bag-display-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/propertyBagDisplay/PropertyBagDisplayWebPart.js",
|
||||||
|
"manifest": "./src/webparts/propertyBagDisplay/PropertyBagDisplayWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"property-bag-filtered-site-list-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/propertyBagFilteredSiteList/PropertyBagFilteredSiteListWebPart.js",
|
||||||
|
"manifest": "./src/webparts/propertyBagFilteredSiteList/PropertyBagFilteredSiteListWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"property-bag-global-nav-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/propertyBagGlobalNav/PropertyBagGlobalNavWebPart.js",
|
||||||
|
"manifest": "./src/webparts/propertyBagGlobalNav/PropertyBagGlobalNavWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"deployCdnPath": "temp/deploy"
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"workingDir": "./temp/deploy/",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
|
"workingDir": "./release/assets/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "react-property-bag-editor",
|
"container": "react-property-bag-editor",
|
||||||
"accessKey": "<!-- ACCESS KEY -->"
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
|
|
@ -1,5 +1,64 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
"solution": {
|
"solution": {
|
||||||
|
"includeClientSideAssets": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "Russell Gove",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"mpnId": "Undefined-1.15.0"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"shortDescription": {
|
||||||
|
"default": "react-property-bag-editor description"
|
||||||
|
},
|
||||||
|
"longDescription": {
|
||||||
|
"default": "react-property-bag-editor description"
|
||||||
|
},
|
||||||
|
"screenshotPaths": [],
|
||||||
|
"videoUrl": "",
|
||||||
|
"categories": []
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"title": "react-property-bag-editor PropertyBagDisplayWebPart Feature",
|
||||||
|
"description": "The feature that activates PropertyBagDisplayWebPart from the react-property-bag-editor solution.",
|
||||||
|
"id": "fa63037d-d7bd-4d52-894a-b40127773283",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"componentIds": [
|
||||||
|
"fa63037d-d7bd-4d52-894a-b40127773283"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "react-property-bag-editor PropertyBagEditorWebPart Feature",
|
||||||
|
"description": "The feature that activates PropertyBagEditorWebPart from the react-property-bag-editor solution.",
|
||||||
|
"id": "f3ac8a07-2a9b-47a1-8a7e-a093cad63f98",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"componentIds": [
|
||||||
|
"f3ac8a07-2a9b-47a1-8a7e-a093cad63f98"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "react-property-bag-editor PropertyBagFilteredSiteListWebPart Feature",
|
||||||
|
"description": "The feature that activates PropertyBagFilteredSiteListWebPart from the react-property-bag-editor solution.",
|
||||||
|
"id": "b81a6789-e93b-4be5-baa7-59f34004694a",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"componentIds": [
|
||||||
|
"b81a6789-e93b-4be5-baa7-59f34004694a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "react-property-bag-editor PropertyBagGlobalNavWebPart Feature",
|
||||||
|
"description": "The feature that activates PropertyBagGlobalNavWebPart from the react-property-bag-editor solution.",
|
||||||
|
"id": "8634e32b-eda4-483d-8fe9-5f2075339eb8",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"componentIds": [
|
||||||
|
"8634e32b-eda4-483d-8fe9-5f2075339eb8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"name": "react-property-bag-editor-client-side-solution",
|
"name": "react-property-bag-editor-client-side-solution",
|
||||||
"id": "12dac38e-b255-44ce-9f06-050571b34d39",
|
"id": "12dac38e-b255-44ce-9f06-050571b34d39",
|
||||||
"version": "1.0.0.0"
|
"version": "1.0.0.0"
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json"
|
||||||
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
|
||||||
"port": 4321,
|
"port": 4321,
|
||||||
"initialPage": "https://localhost:5432/workbench",
|
"initialPage": "https://{tenantDomain}/_layouts/workbench.aspx",
|
||||||
"https": true,
|
"https": true
|
||||||
"api": {
|
|
||||||
"port": 5432,
|
|
||||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
// Display errors as warnings
|
|
||||||
"displayAsWarning": true,
|
|
||||||
// The TSLint task may have been configured with several custom lint rules
|
|
||||||
// before this config file is read (for example lint rules from the tslint-microsoft-contrib
|
|
||||||
// project). If true, this flag will deactivate any of these rules.
|
|
||||||
"removeExistingRules": true,
|
|
||||||
// When true, the TSLint task is configured with some default TSLint "rules.":
|
|
||||||
"useDefaultConfigAsBase": false,
|
|
||||||
// Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
|
|
||||||
// which are active, other than the list of rules below.
|
|
||||||
"lintConfig": {
|
|
||||||
// Opt-in to Lint rules which help to eliminate bugs in JavaScript
|
|
||||||
"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-case": true,
|
|
||||||
|
|
||||||
"no-unused-variable":"true",
|
|
||||||
|
|
||||||
"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-unused-imports": true,
|
|
||||||
|
|
||||||
|
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-with-statement": true,
|
|
||||||
"semicolon": true,
|
|
||||||
"trailing-comma": false,
|
|
||||||
"typedef": false,
|
|
||||||
"typedef-whitespace": false,
|
|
||||||
"use-named-parameter": true,
|
|
||||||
"valid-typeof": true,
|
|
||||||
"variable-name": false,
|
|
||||||
"whitespace": false,
|
|
||||||
"prefer-const": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||||
"cdnBasePath": "https://rgove3.sharepoint.com/sites/cdn/spfxapps/propertybageditor"
|
"cdnBasePath": "https://rgove3.sharepoint.com/sites/cdn/spfxapps/propertybageditor"
|
||||||
}
|
}
|
|
@ -2,5 +2,13 @@
|
||||||
|
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
const build = require('@microsoft/sp-build-web');
|
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);
|
build.initialize(gulp);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,30 +6,37 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-client-base": "~1.0.0",
|
"@microsoft/sp-adaptive-card-extension-base": "1.17.1",
|
||||||
|
"@microsoft/sp-core-library": "1.17.1",
|
||||||
"@microsoft/sp-core-library": "~1.0.0",
|
"@microsoft/sp-property-pane": "1.17.1",
|
||||||
"@microsoft/sp-webpart-base": "~1.0.0",
|
"@microsoft/sp-webpart-base": "1.17.1",
|
||||||
"@types/react": "0.14.46",
|
|
||||||
"@types/react-addons-shallow-compare": "0.14.17",
|
|
||||||
"@types/react-addons-test-utils": "0.14.15",
|
|
||||||
"@types/react-addons-update": "0.14.14",
|
|
||||||
"@types/react-dom": "0.14.18",
|
|
||||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"office-ui-fabric-react": "^0.69.0",
|
"office-ui-fabric-react": "7.199.1",
|
||||||
"react": "0.14.8",
|
"react": "17.0.1",
|
||||||
"react-dom": "0.14.8",
|
"react-dom": "17.0.1",
|
||||||
"sp-pnp-js": "^2.0.1",
|
"sp-pnp-js": "^2.0.1",
|
||||||
"typescript": "^2.1.5"
|
"tslib": "2.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "~1.0.0",
|
"@microsoft/eslint-config-spfx": "1.17.1",
|
||||||
"@microsoft/sp-module-interfaces": "~1.0.0",
|
"@microsoft/eslint-plugin-spfx": "1.17.1",
|
||||||
"@microsoft/sp-webpart-workbench": "~1.0.0",
|
"@microsoft/rush-stack-compiler-4.5": "0.4.0",
|
||||||
"gulp": "~3.9.1",
|
"@microsoft/sp-build-web": "1.17.1",
|
||||||
"@types/chai": ">=3.4.34 <3.6.0",
|
"@microsoft/sp-module-interfaces": "1.17.1",
|
||||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
"@microsoft/sp-tslint-rules": "1.14.0",
|
||||||
|
"@rushstack/eslint-config": "2.5.1",
|
||||||
|
"@types/es6-promise": "0.0.33",
|
||||||
|
"@types/microsoft-ajax": "^0.0.41",
|
||||||
|
"@types/react": "17.0.45",
|
||||||
|
"@types/react-dom": "17.0.17",
|
||||||
|
"@types/sharepoint": "^2016.1.14",
|
||||||
|
"@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",
|
||||||
|
"tslint-microsoft-contrib": "5.0.0",
|
||||||
|
"typescript": "4.5.5"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp bundle",
|
"build": "gulp bundle",
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -1,22 +1,32 @@
|
||||||
{
|
{
|
||||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "fa63037d-d7bd-4d52-894a-b40127773283",
|
"id": "fa63037d-d7bd-4d52-894a-b40127773283",
|
||||||
"alias": "PropertyBagDisplayWebPart",
|
"alias": "PropertyBagDisplayWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
"version": "0.0.1",
|
"version": "*",
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
"preconfiguredEntries": [{
|
"supportedHosts": [
|
||||||
"groupId": "fa63037d-d7bd-4d52-894a-b40127773283",
|
"SharePointWebPart"
|
||||||
"group": { "default": "Property Bag Navigation" },
|
],
|
||||||
"title": { "default": "Property Bag Display" },
|
"safeWithCustomScriptDisabled": false,
|
||||||
"description": { "default": "Displays all Sites and selected properties, an lets you edit those propertiies" },
|
"preconfiguredEntries": [
|
||||||
"officeFabricIconFontName": "Page",
|
{
|
||||||
"properties": {
|
"groupId": "fa63037d-d7bd-4d52-894a-b40127773283",
|
||||||
"description": "propertyBagDisplay",
|
"group": {
|
||||||
"propertiesToDisplay":
|
"default": "Property Bag Navigation"
|
||||||
"CUSTOMNAVAreaName|AreaName\nCUSTOMNAVBusinessUnit|BusinessUnit\nCUSTOMNAVContinent|Continent\nCUSTOMNAVLocation|Location",
|
},
|
||||||
"siteTemplatesToInclude":
|
"title": {
|
||||||
"STS\nPUBLISHING"
|
"default": "Property Bag Display"
|
||||||
}
|
},
|
||||||
}]
|
"description": {
|
||||||
|
"default": "Displays all Sites and selected properties, an lets you edit those propertiies"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"description": "propertyBagDisplay",
|
||||||
|
"propertiesToDisplay": "CUSTOMNAVAreaName|AreaName\nCUSTOMNAVBusinessUnit|BusinessUnit\nCUSTOMNAVContinent|Continent\nCUSTOMNAVLocation|Location",
|
||||||
|
"siteTemplatesToInclude": "STS\nPUBLISHING"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -2,17 +2,15 @@ import * as React from "react";
|
||||||
import pnp from "sp-pnp-js";
|
import pnp from "sp-pnp-js";
|
||||||
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 {
|
|
||||||
BaseClientSideWebPart,
|
|
||||||
IPropertyPaneConfiguration,
|
|
||||||
PropertyPaneTextField
|
|
||||||
} from "@microsoft/sp-webpart-base";
|
|
||||||
|
|
||||||
import * as strings from "propertyBagDisplayStrings";
|
import * as strings from "propertyBagDisplayStrings";
|
||||||
import PropertyBagDisplay from "./components/PropertyBagDisplay";
|
import PropertyBagDisplay from "./components/PropertyBagDisplay";
|
||||||
import { IPropertyBagDisplayProps } from "./components/IPropertyBagDisplayProps";
|
import { IPropertyBagDisplayProps } from "./components/IPropertyBagDisplayProps";
|
||||||
import { IPropertyBagDisplayWebPartProps } from "./IPropertyBagDisplayWebPartProps";
|
import { IPropertyBagDisplayWebPartProps } from "./IPropertyBagDisplayWebPartProps";
|
||||||
import utils from "../shared/utils";
|
import utils from "../shared/utils";
|
||||||
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
|
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
||||||
export default class PropertyBagDisplayWebPart extends BaseClientSideWebPart<IPropertyBagDisplayWebPartProps> {
|
export default class PropertyBagDisplayWebPart extends BaseClientSideWebPart<IPropertyBagDisplayWebPartProps> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +28,7 @@ export default class PropertyBagDisplayWebPart extends BaseClientSideWebPart<IPr
|
||||||
{
|
{
|
||||||
description: this.properties.description,
|
description: this.properties.description,
|
||||||
propertiesToDisplay: utils.parseMultilineTextToArray(this.properties.propertiesToDisplay),
|
propertiesToDisplay: utils.parseMultilineTextToArray(this.properties.propertiesToDisplay),
|
||||||
siteTemplatesToInclude:utils.parseMultilineTextToArray(this.properties.siteTemplatesToInclude)
|
siteTemplatesToInclude: utils.parseMultilineTextToArray(this.properties.siteTemplatesToInclude)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.helloWorld {
|
.helloWorld {
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { CommandBar } from "office-ui-fabric-react/lib/CommandBar";
|
||||||
import { Label } from "office-ui-fabric-react/lib/Label";
|
import { Label } from "office-ui-fabric-react/lib/Label";
|
||||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
||||||
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
|
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
|
||||||
import { Button, ButtonType } from "office-ui-fabric-react/lib/Button";
|
import { ButtonType, PrimaryButton, DefaultButton } from "office-ui-fabric-react/lib/Button";
|
||||||
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
|
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
|
||||||
import * as md from "../../shared/MessageDisplay";
|
import * as md from "../../shared/MessageDisplay";
|
||||||
import MessageDisplay from "../../shared/MessageDisplay";
|
import MessageDisplay from "../../shared/MessageDisplay";
|
||||||
|
@ -127,7 +127,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
hideMessage={this.removePanelMessage.bind(this)} />
|
hideMessage={this.removePanelMessage.bind(this)} />
|
||||||
|
|
||||||
<div> <Label >Site Title</Label> {this.state.workingStorage.Title}</div>
|
<div> <Label >Site Title</Label> {this.state.workingStorage.Title}</div>
|
||||||
<span> <Label label="" >Site Url</Label> {this.state.workingStorage.Url}</span>
|
<span> <Label >Site Url</Label> {this.state.workingStorage.Url}</span>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -155,7 +155,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
<td>
|
<td>
|
||||||
<Toggle label=""
|
<Toggle label=""
|
||||||
checked={dp.searchable}
|
checked={dp.searchable}
|
||||||
onChanged={this.createSearcheableOnChangedHandler(dp.crawledPropertyName)}
|
onChange={this.createSearcheableOnChangedHandler(dp.crawledPropertyName)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>);
|
</tr>);
|
||||||
|
@ -164,10 +164,10 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
</table>
|
</table>
|
||||||
<Toggle label="Force Crawl"
|
<Toggle label="Force Crawl"
|
||||||
checked={this.state.workingStorage.forceCrawl}
|
checked={this.state.workingStorage.forceCrawl}
|
||||||
onChanged={this.onForceCrawlChange.bind(this)}
|
onChange={this.onForceCrawlChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
<Button default={true} icon="Save" buttonType={ButtonType.hero} value="Save" onClick={this.onSave.bind(this)} >Save</Button>
|
<DefaultButton default={true} iconProps={{ iconName: "Save" }} value="Save" onClick={this.onSave.bind(this)} >Save</DefaultButton>
|
||||||
<Button icon="Cancel" buttonType={ButtonType.normal} value="Cancel" onClick={this.onCancel.bind(this)} >Cancel</Button>
|
<PrimaryButton iconProps={{ iconName: "Cancel" }} value="Cancel" onClick={this.onCancel.bind(this)} >Cancel</PrimaryButton>
|
||||||
|
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
|
@ -248,8 +248,11 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
* @memberOf PropertyBagDisplay
|
* @memberOf PropertyBagDisplay
|
||||||
*/
|
*/
|
||||||
public stopediting() {
|
public stopediting() {
|
||||||
this.state.isediting = false;
|
this.setState((current) => ({
|
||||||
this.setState(this.state);
|
...current,
|
||||||
|
isediting: false,
|
||||||
|
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Caled by the Details list to render a column as a URL rather than text
|
* Caled by the Details list to render a column as a URL rather than text
|
||||||
|
@ -329,18 +332,26 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
* @memberOf PropertyBagDisplay
|
* @memberOf PropertyBagDisplay
|
||||||
*/
|
*/
|
||||||
public componentWillMount() {
|
public componentWillMount() {
|
||||||
this.state.columns = this.setupColumns();
|
// this.state.columns = this.setupColumns();
|
||||||
this.state.managedToCrawedMapping = [];
|
// this.state.managedToCrawedMapping = [];
|
||||||
this.state.managedPropNames = [];
|
// this.state.managedPropNames = [];
|
||||||
|
var initState = {
|
||||||
|
|
||||||
|
columns: this.setupColumns(),
|
||||||
|
managedToCrawedMapping: [],
|
||||||
|
managedPropNames: [],
|
||||||
|
sites: [],
|
||||||
|
errorMessages: []
|
||||||
|
};
|
||||||
for (const prop of this.props.propertiesToDisplay) {
|
for (const prop of this.props.propertiesToDisplay) {
|
||||||
const names: Array<string> = prop.split('|');// crawledpropety/managed property
|
const names: Array<string> = prop.split('|');// crawledpropety/managed property
|
||||||
this.state.managedToCrawedMapping.push(new ManagedToCrawledMappingEntry(names[0], names[1]));
|
initState.managedToCrawedMapping.push(new ManagedToCrawledMappingEntry(names[0], names[1]));
|
||||||
this.state.managedPropNames.push(names[1]);
|
initState.managedPropNames.push(names[1]);
|
||||||
}
|
}
|
||||||
this.state.managedPropNames.unshift("Title");
|
initState.managedPropNames.unshift("Title");
|
||||||
this.state.managedPropNames.unshift("Url");
|
initState.managedPropNames.unshift("Url");
|
||||||
this.state.managedPropNames.unshift("SiteTemplate");
|
initState.managedPropNames.unshift("SiteTemplate");
|
||||||
this.state.managedPropNames.unshift("SiteTemplateId");
|
initState.managedPropNames.unshift("SiteTemplateId");
|
||||||
let querytext = "contentclass:STS_Site ";
|
let querytext = "contentclass:STS_Site ";
|
||||||
if (this.props.siteTemplatesToInclude) {
|
if (this.props.siteTemplatesToInclude) {
|
||||||
if (this.props.siteTemplatesToInclude.length > 0) {
|
if (this.props.siteTemplatesToInclude.length > 0) {
|
||||||
|
@ -353,8 +364,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
else {
|
else {
|
||||||
querytext += "(SiteTemplate=" + siteTemplateParts[0] + " AND SiteTemplateId=" + siteTemplateParts[1] + ")";
|
querytext += "(SiteTemplate=" + siteTemplateParts[0] + " AND SiteTemplateId=" + siteTemplateParts[1] + ")";
|
||||||
}
|
}
|
||||||
if (this.props.siteTemplatesToInclude.indexOf(siteTemplate) !== this.props.siteTemplatesToInclude.length - 1)
|
if (this.props.siteTemplatesToInclude.indexOf(siteTemplate) !== this.props.siteTemplatesToInclude.length - 1) { querytext += " OR "; }
|
||||||
{ querytext += " OR "; }
|
|
||||||
}
|
}
|
||||||
querytext += " )";
|
querytext += " )";
|
||||||
}
|
}
|
||||||
|
@ -362,26 +372,26 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
console.log("Using Query " + querytext);
|
console.log("Using Query " + querytext);
|
||||||
const q: SearchQuery = {
|
const q: SearchQuery = {
|
||||||
Querytext: querytext,
|
Querytext: querytext,
|
||||||
SelectProperties: this.state.managedPropNames,
|
SelectProperties: initState.managedPropNames,
|
||||||
RowLimit: 999,
|
RowLimit: 999,
|
||||||
TrimDuplicates: false
|
TrimDuplicates: false
|
||||||
};
|
};
|
||||||
pnp.sp.search(q).then((results: SearchResults) => {
|
pnp.sp.search(q).then((results: SearchResults) => {
|
||||||
for (const r of results.PrimarySearchResults) {
|
for (const r of results.PrimarySearchResults) {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
for (const dp of this.state.managedPropNames) {
|
for (const dp of initState.managedPropNames) {
|
||||||
obj[dp] = r[dp];
|
obj[dp] = r[dp];
|
||||||
}
|
}
|
||||||
obj.SiteTemplate = obj.SiteTemplate + "#" + obj.SiteTemplateId;
|
obj.SiteTemplate = obj.SiteTemplate + "#" + obj.SiteTemplateId;
|
||||||
this.state.sites.push(obj);
|
initState.sites.push(obj);
|
||||||
}
|
}
|
||||||
debugger;
|
debugger;
|
||||||
this.state.errorMessages.push(new md.Message("Items Recieved"));
|
initState.errorMessages.push(new md.Message("Items Recieved"));
|
||||||
this.setState(this.state);
|
this.setState({ ...initState });
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
debugger;
|
debugger;
|
||||||
this.state.errorMessages.push(new md.Message(err));
|
initState.errorMessages.push(new md.Message(err));
|
||||||
this.setState(this.state);
|
this.setState({ ...initState });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Event Handlers */
|
/** Event Handlers */
|
||||||
|
@ -394,8 +404,8 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
* @memberOf PropertyBagDisplay
|
* @memberOf PropertyBagDisplay
|
||||||
*/
|
*/
|
||||||
public onActiveItemChanged(item?: any, index?: number) {
|
public onActiveItemChanged(item?: any, index?: number) {
|
||||||
this.state.selectedIndex = index;
|
//this.state.selectedIndex = index;
|
||||||
this.setState(this.state);
|
this.setState((current) => ({ ...current, selectedIndex: index }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -419,8 +429,9 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
if (this.state.workingStorage.forceCrawl) {
|
if (this.state.workingStorage.forceCrawl) {
|
||||||
utils.forceCrawl(this.state.workingStorage.Url);
|
utils.forceCrawl(this.state.workingStorage.Url);
|
||||||
}
|
}
|
||||||
this.state.workingStorage = null;
|
// this.state.workingStorage = null;
|
||||||
this.state.isediting = false;
|
// this.state.isediting = false;
|
||||||
|
this.setState((current) => ({ ...current, workingStorage: null, isediting: false }));
|
||||||
|
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
@ -438,9 +449,9 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
* @memberOf PropertyBagDisplay
|
* @memberOf PropertyBagDisplay
|
||||||
*/
|
*/
|
||||||
public onCancel(e?: MouseEvent): void {
|
public onCancel(e?: MouseEvent): void {
|
||||||
this.state.isediting = false;
|
// this.state.isediting = false;
|
||||||
this.state.workingStorage = null;
|
// this.state.workingStorage = null;
|
||||||
this.setState(this.state);
|
this.setState((current) => ({ ...current, workingStorage: null, isediting: false }));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Set the ForceCrawl Value in working storage which can be used to force a crawl of the site
|
* Set the ForceCrawl Value in working storage which can be used to force a crawl of the site
|
||||||
|
@ -485,6 +496,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
* @memberOf PropertyBagDisplay
|
* @memberOf PropertyBagDisplay
|
||||||
*/
|
*/
|
||||||
public onEditItemClicked(e?: MouseEvent): void {
|
public onEditItemClicked(e?: MouseEvent): void {
|
||||||
|
debugger;
|
||||||
console.log("in onEditItemClicked");
|
console.log("in onEditItemClicked");
|
||||||
const selectedSite = this.state.sites[this.state.selectedIndex];
|
const selectedSite = this.state.sites[this.state.selectedIndex];
|
||||||
const web = new Web(selectedSite.Url);
|
const web = new Web(selectedSite.Url);
|
||||||
|
@ -492,17 +504,20 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
const crawledProps: Array<string> = this.props.propertiesToDisplay.map(item => {
|
const crawledProps: Array<string> = this.props.propertiesToDisplay.map(item => {
|
||||||
return item.split("|")[0];
|
return item.split("|")[0];
|
||||||
});
|
});
|
||||||
this.state.workingStorage = _.clone(this.state.sites[this.state.selectedIndex]);
|
let temp = _.clone(this.state.sites[this.state.selectedIndex]);
|
||||||
this.state.workingStorage.searchableProps = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
|
temp.searchableProps = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
|
||||||
this.state.workingStorage.DisplayProps = utils.SelectProperties(r.AllProperties, crawledProps, this.state.workingStorage.searchableProps);
|
temp.DisplayProps = utils.SelectProperties(r.AllProperties, crawledProps, this.state.workingStorage.searchableProps);
|
||||||
this.state.workingStorage.errorMessages = new Array<md.Message>();
|
temp.errorMessages = new Array<md.Message>();
|
||||||
// now add in the managed Prop
|
// now add in the managed Prop
|
||||||
for (const dp of this.state.workingStorage.DisplayProps) {
|
for (const dp of this.state.workingStorage.DisplayProps) {
|
||||||
dp.managedPropertyName =
|
dp.managedPropertyName =
|
||||||
_.find(this.state.managedToCrawedMapping, mtc => { return mtc.crawledPropertyName === dp.crawledPropertyName; }).managedPropertyName;
|
_.find(this.state.managedToCrawedMapping, mtc => { return mtc.crawledPropertyName === dp.crawledPropertyName; }).managedPropertyName;
|
||||||
}
|
}
|
||||||
this.state.isediting = true;
|
this.setState((current) => ({
|
||||||
this.setState(this.state);
|
...current,
|
||||||
|
workingStorage: temp, isediting: true
|
||||||
|
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
console.log("out onEditItemClicked");
|
console.log("out onEditItemClicked");
|
||||||
}
|
}
|
||||||
|
@ -526,15 +541,19 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
|
||||||
column.isSortedDescending = false;
|
column.isSortedDescending = false;
|
||||||
}
|
}
|
||||||
// Sort the items.
|
// Sort the items.
|
||||||
this.state.sites = _.orderBy(this.state.sites, [(site, x, y, z) => {
|
let temp = _.orderBy(this.state.sites, (site) => {
|
||||||
if (site[column.fieldName]) {
|
if (site[column.fieldName]) {
|
||||||
return site[column.fieldName].toLowerCase();
|
return site[column.fieldName].toLowerCase();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}], [column.isSortedDescending ? "desc" : "asc"]);
|
}, [column.isSortedDescending ? "desc" : "asc"]);
|
||||||
this.setState(this.state);
|
this.setState((current) => ({
|
||||||
|
...current,
|
||||||
|
sites: temp
|
||||||
|
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/// <reference types="mocha" />
|
// /// <reference types="mocha" />
|
||||||
|
|
||||||
import { assert } from 'chai';
|
// import { assert } from 'chai';
|
||||||
|
|
||||||
describe('PropertyBagDisplayWebPart', () => {
|
// describe('PropertyBagDisplayWebPart', () => {
|
||||||
it('should do something', () => {
|
// it('should do something', () => {
|
||||||
assert.ok(true);
|
// assert.ok(true);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
{
|
{
|
||||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
|
||||||
"id": "f3ac8a07-2a9b-47a1-8a7e-a093cad63f98",
|
"id": "f3ac8a07-2a9b-47a1-8a7e-a093cad63f98",
|
||||||
"alias": "PropertyBagEditorWebPart",
|
"alias": "PropertyBagEditorWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
"version": "0.0.1",
|
"version": "*",
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
|
"supportedHosts": [
|
||||||
"preconfiguredEntries": [{
|
"SharePointWebPart"
|
||||||
"groupId": "f3ac8a07-2a9b-47a1-8a7e-a093cad63f98",
|
],
|
||||||
"group": { "default": "Property Bag Navigation" },
|
"safeWithCustomScriptDisabled": false,
|
||||||
"title": { "default": "Property Bag Editor" },
|
"preconfiguredEntries": [
|
||||||
"description": { "default": "Lets you edit the properties of an SPSite passed in as a query parameter" },
|
{
|
||||||
"officeFabricIconFontName": "Page",
|
"groupId": "f3ac8a07-2a9b-47a1-8a7e-a093cad63f98",
|
||||||
"properties": {
|
"group": {
|
||||||
"description": "PropertyBagEditor",
|
"default": "Property Bag Navigation"
|
||||||
"propertiesToEdit":
|
},
|
||||||
"CUSTOMNAVAreaName\nCUSTOMNAVBusinessUnit\nCUSTOMNAVContinent\nCUSTOMNAVLocation"
|
"title": {
|
||||||
}
|
"default": "Property Bag Editor"
|
||||||
}]
|
},
|
||||||
|
"description": {
|
||||||
|
"default": "Lets you edit the properties of an SPSite passed in as a query parameter"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"description": "PropertyBagEditor",
|
||||||
|
"propertiesToEdit": "CUSOMNAVAreaName\nCUSOMNAVBusinessUnit\nCUSOMNAVContinent\nCUSOMNAVLocation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -2,12 +2,8 @@ import * as React from "react";
|
||||||
import * as ReactDom from "react-dom";
|
import * as ReactDom from "react-dom";
|
||||||
import { Version, UrlQueryParameterCollection } from "@microsoft/sp-core-library";
|
import { Version, UrlQueryParameterCollection } 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 "propertyBagEditorStrings";
|
import * as strings from "propertyBagEditorStrings";
|
||||||
import PropertyBagEditor from "./components/PropertyBagEditor";
|
import PropertyBagEditor from "./components/PropertyBagEditor";
|
||||||
import { IPropertyBagEditorProps } from "./components/IPropertyBagEditorProps";
|
import { IPropertyBagEditorProps } from "./components/IPropertyBagEditorProps";
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.helloWorld {
|
.helloWorld {
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { Dialog, DialogType } from "office-ui-fabric-react/lib/Dialog";
|
||||||
import { Label } from "office-ui-fabric-react/lib/Label";
|
import { Label } from "office-ui-fabric-react/lib/Label";
|
||||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
||||||
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
|
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
|
||||||
import { Button, ButtonType } from "office-ui-fabric-react/lib/Button";
|
import { PrimaryButton, DefaultButton, ButtonType } from "office-ui-fabric-react/lib/Button";
|
||||||
import DisplayProp from "../../shared/DisplayProp";
|
import DisplayProp from "../../shared/DisplayProp";
|
||||||
|
|
||||||
export interface IPropertyBagEditorState {
|
export interface IPropertyBagEditorState {
|
||||||
|
@ -31,7 +31,7 @@ export interface IPropertyBagEditorState {
|
||||||
export default class PropertyBagEditor extends React.Component<IPropertyBagEditorProps, IPropertyBagEditorState> {
|
export default class PropertyBagEditor extends React.Component<IPropertyBagEditorProps, IPropertyBagEditorState> {
|
||||||
public refs: {
|
public refs: {
|
||||||
[key: string]: React.ReactInstance;
|
[key: string]: React.ReactInstance;
|
||||||
list: DetailsList
|
list: any //DetailsList
|
||||||
};
|
};
|
||||||
public constructor(props: IPropertyBagEditorProps) {
|
public constructor(props: IPropertyBagEditorProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -77,22 +77,26 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
|
||||||
|
|
||||||
const web = new Web(this.props.siteUrl);
|
const web = new Web(this.props.siteUrl);
|
||||||
web.select("Title", "AllProperties").expand("AllProperties").get().then(r => {
|
web.select("Title", "AllProperties").expand("AllProperties").get().then(r => {
|
||||||
|
debugger;
|
||||||
const sp = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
|
const sp = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
|
||||||
const dp = utils.SelectProperties(r.AllProperties, this.props.propertiesToEdit, sp);
|
const dp = utils.SelectProperties(r.AllProperties, this.props.propertiesToEdit, sp);
|
||||||
this.state.searchableProps = sp;
|
// this.state.searchableProps = sp;
|
||||||
this.state.displayProps = dp;
|
// this.state.displayProps = dp;
|
||||||
this.setState(this.state);
|
|
||||||
|
this.setState((current) => ({ ...current, searchableProps: sp, displayProps: dp }))
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** event hadlers */
|
/** event hadlers */
|
||||||
public stopediting() {
|
public stopediting() {
|
||||||
this.state.isediting = false;
|
//this.state.isediting = false;
|
||||||
this.setState(this.state);
|
this.setState((current) => ({ ...current, isediting: false }))
|
||||||
}
|
}
|
||||||
public onActiveItemChanged(item?: any, index?: number) {
|
public onActiveItemChanged(item?: any, index?: number) {
|
||||||
this.state.selectedIndex = index;
|
//this.state.selectedIndex = index;
|
||||||
this.setState(this.state);
|
this.setState((current) => ({ ...current, selectedIndex: index }))
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Gets fired when the user changes the 'Searchable' value in the ui.
|
* Gets fired when the user changes the 'Searchable' value in the ui.
|
||||||
|
@ -127,9 +131,10 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
|
||||||
* @memberOf PropertyBagEditor
|
* @memberOf PropertyBagEditor
|
||||||
*/
|
*/
|
||||||
public onEditItemClicked(e?: MouseEvent): void {
|
public onEditItemClicked(e?: MouseEvent): void {
|
||||||
this.state.isediting = true;
|
//this.state.isediting = true;
|
||||||
this.state.workingStorage = _.clone(this.state.displayProps[this.state.selectedIndex]);
|
//this.state.workingStorage = _.clone(this.state.displayProps[this.state.selectedIndex]);
|
||||||
this.setState(this.state);
|
//this.setState(this.state);
|
||||||
|
this.setState((current) => ({ ...current, isediting: true, workingStorage: _.clone(current.displayProps[current.selectedIndex]) }))
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Saves the item in workingStorage back to sharepoint, then clears workingStorage and stops editing.
|
* Saves the item in workingStorage back to sharepoint, then clears workingStorage and stops editing.
|
||||||
|
@ -139,14 +144,16 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
|
||||||
* @memberOf PropertyBagEditor
|
* @memberOf PropertyBagEditor
|
||||||
*/
|
*/
|
||||||
public onSave(e?: MouseEvent): void {
|
public onSave(e?: MouseEvent): void {
|
||||||
|
debugger;
|
||||||
utils.setSPProperty(this.state.workingStorage.crawledPropertyName, this.state.workingStorage.value, this.props.siteUrl)
|
utils.setSPProperty(this.state.workingStorage.crawledPropertyName, this.state.workingStorage.value, this.props.siteUrl)
|
||||||
.then(value => {
|
.then(value => {
|
||||||
this.changeSearchable(this.state.workingStorage.crawledPropertyName, this.state.workingStorage.searchable)
|
this.changeSearchable(this.state.workingStorage.crawledPropertyName, this.state.workingStorage.searchable)
|
||||||
.then(s => {
|
.then(s => {
|
||||||
this.state.displayProps[this.state.selectedIndex] = this.state.workingStorage;
|
this.state.displayProps[this.state.selectedIndex] = this.state.workingStorage;
|
||||||
this.state.workingStorage = null;
|
// this.state.workingStorage = null;
|
||||||
this.state.isediting = false;
|
// this.state.isediting = false;
|
||||||
this.setState(this.state);
|
// this.setState(this.state);
|
||||||
|
this.setState((current) => ({ ...current, isediting: false, workingStorage: null }))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -158,9 +165,10 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
|
||||||
* @memberOf PropertyBagEditor
|
* @memberOf PropertyBagEditor
|
||||||
*/
|
*/
|
||||||
public onCancel(e?: MouseEvent): void {
|
public onCancel(e?: MouseEvent): void {
|
||||||
this.state.isediting = false;
|
// this.state.isediting = false;
|
||||||
this.state.workingStorage = null;
|
// this.state.workingStorage = null;
|
||||||
this.setState(this.state);
|
// this.setState(this.state);
|
||||||
|
this.setState((current) => ({ ...current, isediting: false, workingStorage: null }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,8 +253,8 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<Button default={true} icon="Save" buttonType={ButtonType.icon} value="Save" onClick={this.onSave.bind(this)} >Save</Button>
|
<DefaultButton default={true} iconProps={{ iconName: "Save" }} value="Save" onClick={this.onSave.bind(this)} >Save</DefaultButton>
|
||||||
<Button icon="Cancel" buttonType={ButtonType.icon} value="Cancel" onClick={this.onCancel.bind(this)} >Cancel</Button>
|
<PrimaryButton iconProps={{ iconName: "Cancel" }} value="Cancel" onClick={this.onCancel.bind(this)} >Cancel</PrimaryButton>
|
||||||
|
|
||||||
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/// <reference types="mocha" />
|
// /// <reference types="mocha" />
|
||||||
|
|
||||||
import { assert } from 'chai';
|
// import { assert } from 'chai';
|
||||||
|
|
||||||
describe('PropertyBagEditorWebPart', () => {
|
// describe('PropertyBagEditorWebPart', () => {
|
||||||
it('should do something', () => {
|
// it('should do something', () => {
|
||||||
assert.ok(true);
|
// assert.ok(true);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
{
|
{
|
||||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "b81a6789-e93b-4be5-baa7-59f34004694a",
|
"id": "b81a6789-e93b-4be5-baa7-59f34004694a",
|
||||||
"alias": "PropertyBagFilteredSiteListWebPart",
|
"alias": "PropertyBagFilteredSiteListWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
"version": "0.0.1",
|
"version": "*",
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
|
"supportedHosts": [
|
||||||
|
"SharePointWebPart"
|
||||||
|
],
|
||||||
|
"safeWithCustomScriptDisabled": false,
|
||||||
"preconfiguredEntries": [
|
"preconfiguredEntries": [
|
||||||
{
|
{
|
||||||
"groupId": "b81a6789-e93b-4be5-baa7-59f34004694a",
|
"groupId": "b81a6789-e93b-4be5-baa7-59f34004694a",
|
||||||
"group": { "default": "Property Bag Navigation" },
|
"group": {
|
||||||
"title": { "default": "Property Bag Site List" },
|
"default": "Property Bag Navigation"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"default": "Property Bag Site List"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"default": "Displays a list of sites with the selected properties"
|
"default": "Displays a list of sites with the selected properties"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
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,
|
// BaseClientSideWebPart,
|
||||||
IPropertyPaneConfiguration,
|
// IPropertyPaneConfiguration,
|
||||||
PropertyPaneTextField,
|
// PropertyPaneTextField,
|
||||||
PropertyPaneToggle, PropertyPaneChoiceGroup
|
// PropertyPaneToggle, PropertyPaneChoiceGroup
|
||||||
} from '@microsoft/sp-webpart-base';
|
// } from '@microsoft/sp-webpart-base';
|
||||||
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
|
import { IPropertyPaneConfiguration, PropertyPaneTextField, PropertyPaneToggle, PropertyPaneChoiceGroup } from "@microsoft/sp-property-pane";
|
||||||
import * as strings from 'propertyBagFilteredSiteListStrings';
|
import * as strings from 'propertyBagFilteredSiteListStrings';
|
||||||
import PropertyBagFilteredSiteList from './components/PropertyBagFilteredSiteList';
|
import PropertyBagFilteredSiteList from './components/PropertyBagFilteredSiteList';
|
||||||
import { IPropertyBagFilteredSiteListProps } from './components/IPropertyBagFilteredSiteListProps';
|
import { IPropertyBagFilteredSiteListProps } from './components/IPropertyBagFilteredSiteListProps';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.helloWorld {
|
.helloWorld {
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|
|
@ -1,35 +1,14 @@
|
||||||
import * as React from "react";
|
|
||||||
import pnp from "sp-pnp-js";
|
|
||||||
import { SortDirection } from "sp-pnp-js";
|
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
|
import * as React from "react";
|
||||||
|
import pnp, { SearchQuery, SearchResults } from "sp-pnp-js";
|
||||||
import DisplayProp from "../../shared/DisplayProp";
|
import DisplayProp from "../../shared/DisplayProp";
|
||||||
import { SearchQuery, SearchResults } from "sp-pnp-js";
|
|
||||||
import { css } from "office-ui-fabric-react";
|
|
||||||
//import styles from "./PropertyBagFilteredSiteList.module.scss";
|
//import styles from "./PropertyBagFilteredSiteList.module.scss";
|
||||||
import { IPropertyBagFilteredSiteListProps } from "./IPropertyBagFilteredSiteListProps";
|
import { CommandBar } from "office-ui-fabric-react/lib/CommandBar";
|
||||||
import { Label } from "office-ui-fabric-react/lib/Label";
|
import { Label } from "office-ui-fabric-react/lib/Label";
|
||||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
import MessageDisplay, * as md from "../../shared/MessageDisplay";
|
||||||
import { Link } from "office-ui-fabric-react/lib/Link";
|
|
||||||
import { List } from "office-ui-fabric-react/lib/List";
|
|
||||||
import { Button, ButtonType } from "office-ui-fabric-react/lib/Button";
|
|
||||||
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
|
|
||||||
import * as md from "../../shared/MessageDisplay";
|
|
||||||
import utils from "../../shared/utils";
|
import utils from "../../shared/utils";
|
||||||
import MessageDisplay from "../../shared/MessageDisplay";
|
import { IPropertyBagFilteredSiteListProps } from "./IPropertyBagFilteredSiteListProps";
|
||||||
import { CommandBar, ICommandBarProps } from "office-ui-fabric-react/lib/CommandBar";
|
|
||||||
import {
|
|
||||||
DetailsList, DetailsListLayoutMode, IColumn, IGroupedList, SelectionMode, CheckboxVisibility, IGroup
|
|
||||||
} from "office-ui-fabric-react/lib/DetailsList";
|
|
||||||
import {
|
|
||||||
GroupedList
|
|
||||||
} from "office-ui-fabric-react/lib/GroupedList";
|
|
||||||
import {
|
|
||||||
IViewport
|
|
||||||
} from "office-ui-fabric-react/lib/utilities/decorators/withViewport";
|
|
||||||
|
|
||||||
import {
|
|
||||||
Panel, PanelType
|
|
||||||
} from "office-ui-fabric-react/lib/Panel";
|
|
||||||
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
|
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||||
export interface IPropertyBagFilteredSiteListState {
|
export interface IPropertyBagFilteredSiteListState {
|
||||||
errorMessages: Array<md.Message>;
|
errorMessages: Array<md.Message>;
|
||||||
|
@ -71,8 +50,7 @@ export class AppliedUserFilter {
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
public managedPropertyName: string,
|
public managedPropertyName: string,
|
||||||
public value: string)
|
public value: string) { }
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
export class UserFilter {
|
export class UserFilter {
|
||||||
|
|
||||||
|
@ -91,7 +69,7 @@ export class UserFilter {
|
||||||
}
|
}
|
||||||
export default class PropertyBagFilteredSiteList extends React.Component<IPropertyBagFilteredSiteListProps, IPropertyBagFilteredSiteListState> {
|
export default class PropertyBagFilteredSiteList extends React.Component<IPropertyBagFilteredSiteListProps, IPropertyBagFilteredSiteListState> {
|
||||||
public constructor(props) {
|
public constructor(props) {
|
||||||
console.log(JSON.stringify("in constructor"));
|
console.log(JSON.stringify("in constructor"));
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { sites: [], filteredSites: [], errorMessages: [], userFilters: [], appliedUserFilters: [] };
|
this.state = { sites: [], filteredSites: [], errorMessages: [], userFilters: [], appliedUserFilters: [] };
|
||||||
}
|
}
|
||||||
|
@ -119,11 +97,17 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public setupUserFilters(userFilterNames: Array<string>) {
|
public setupUserFilters(userFilterNames: Array<string>) {
|
||||||
console.log(JSON.stringify("in extractUserFilterValues"));
|
console.log(JSON.stringify("in extractUserFilterValues"));
|
||||||
this.state.userFilters = [];
|
// this.state.userFilters = [];
|
||||||
|
// for (const userFilterName of userFilterNames) {
|
||||||
|
// this.state.userFilters.push(new UserFilter(userFilterName));
|
||||||
|
// }
|
||||||
|
let userFilters = [];
|
||||||
for (const userFilterName of userFilterNames) {
|
for (const userFilterName of userFilterNames) {
|
||||||
this.state.userFilters.push(new UserFilter(userFilterName));
|
userFilters.push(new UserFilter(userFilterName));
|
||||||
}
|
}
|
||||||
|
this.setState((current) => ({ ...current, userFilters: userFilters }));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,7 +118,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public extractUserFilterValues(r) {
|
public extractUserFilterValues(r) {
|
||||||
console.log(JSON.stringify("in extractUserFilterValues"));
|
console.log(JSON.stringify("in extractUserFilterValues"));
|
||||||
for (const userFilter of this.state.userFilters) {
|
for (const userFilter of this.state.userFilters) {
|
||||||
const value = r[userFilter.managedPropertyName].trim();
|
const value = r[userFilter.managedPropertyName].trim();
|
||||||
if (_.find(userFilter.values, v => { return v === value; })) {
|
if (_.find(userFilter.values, v => { return v === value; })) {
|
||||||
|
@ -157,13 +141,13 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
*
|
*
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public getSites(siteTemplatesToInclude: Array<string>, filters:Array<string>, showQueryText: boolean, userFilters: Array<string>, showSiteDescriptions: boolean) {
|
public getSites(siteTemplatesToInclude: Array<string>, filters: Array<string>, showQueryText: boolean, userFilters: Array<string>, showSiteDescriptions: boolean) {
|
||||||
console.log(JSON.stringify("in getSites"));
|
console.log(JSON.stringify("in getSites"));
|
||||||
const userFilterNameArray = [];
|
const userFilterNameArray = [];
|
||||||
if (userFilters) {
|
if (userFilters) {
|
||||||
for (const userFilter of userFilters) {
|
for (const userFilter of userFilters) {
|
||||||
|
|
||||||
userFilterNameArray.push(userFilter);
|
userFilterNameArray.push(userFilter);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,19 +185,34 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
|
|
||||||
};
|
};
|
||||||
pnp.sp.search(q).then((results: SearchResults) => {
|
pnp.sp.search(q).then((results: SearchResults) => {
|
||||||
this.state.sites = [];
|
// this.state.sites = [];
|
||||||
|
// debugger;
|
||||||
|
// this.setupUserFilters(userFilterNameArray);
|
||||||
|
// for (const r of results.PrimarySearchResults) {
|
||||||
|
// const index = this.state.sites.push(new Site(r.Title, r.Description, r.SPSiteUrl));
|
||||||
|
|
||||||
|
// for (const mp of this.props.userFilters) {
|
||||||
|
// this.state.sites[index-1][mp] = r[mp];
|
||||||
|
// }
|
||||||
|
// this.extractUserFilterValues(r);
|
||||||
|
// }
|
||||||
|
// this.filterSites();
|
||||||
|
// this.setState(this.state);
|
||||||
|
let sites = [];
|
||||||
debugger;
|
debugger;
|
||||||
this.setupUserFilters(userFilterNameArray);
|
this.setupUserFilters(userFilterNameArray);
|
||||||
for (const r of results.PrimarySearchResults) {
|
for (const r of results.PrimarySearchResults) {
|
||||||
const index = this.state.sites.push(new Site(r.Title, r.Description, r.SPSiteUrl));
|
debugger;
|
||||||
|
const index = sites.push(new Site(r.Title, r.Description, r["SPSiteUrl"]));
|
||||||
|
|
||||||
for (const mp of this.props.userFilters) {
|
for (const mp of this.props.userFilters) {
|
||||||
this.state.sites[index-1][mp] = r[mp];
|
sites[index - 1][mp] = r[mp];
|
||||||
}
|
}
|
||||||
this.extractUserFilterValues(r);
|
this.extractUserFilterValues(r);
|
||||||
}
|
}
|
||||||
this.filterSites();
|
debugger;
|
||||||
this.setState(this.state);
|
let filteredSites = this.filterSites(sites);// need to pass sites iun here and return the filtered array!!!
|
||||||
|
this.setState((current) => ({ ...current, filteredSites: filteredSites, sites: sites }));
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
debugger;
|
debugger;
|
||||||
this.state.errorMessages.push(new md.Message(err));
|
this.state.errorMessages.push(new md.Message(err));
|
||||||
|
@ -228,7 +227,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public componentWillMount() {
|
public componentWillMount() {
|
||||||
console.log(JSON.stringify("in componentWillMount"));
|
console.log(JSON.stringify("in componentWillMount"));
|
||||||
this.getSites(this.props.siteTemplatesToInclude, this.props.filters, this.props.showQueryText, this.props.userFilters, this.props.showSiteDescriptions);
|
this.getSites(this.props.siteTemplatesToInclude, this.props.filters, this.props.showQueryText, this.props.userFilters, this.props.showSiteDescriptions);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -241,7 +240,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public componentWillReceiveProps(nextProps: IPropertyBagFilteredSiteListProps, nextContext: any) {
|
public componentWillReceiveProps(nextProps: IPropertyBagFilteredSiteListProps, nextContext: any) {
|
||||||
console.log(JSON.stringify("in componentWillReceiveProps"));
|
console.log(JSON.stringify("in componentWillReceiveProps"));
|
||||||
this.getSites(nextProps.siteTemplatesToInclude, nextProps.filters, nextProps.showQueryText, nextProps.userFilters, nextProps.showSiteDescriptions);
|
this.getSites(nextProps.siteTemplatesToInclude, nextProps.filters, nextProps.showQueryText, nextProps.userFilters, nextProps.showSiteDescriptions);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -255,7 +254,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public conditionallyRenderDescription(site: Site) {
|
public conditionallyRenderDescription(site: Site) {
|
||||||
console.log(JSON.stringify("in conditionallyRenderDescription"));
|
console.log(JSON.stringify("in conditionallyRenderDescription"));
|
||||||
if (this.props.showSiteDescriptions) {
|
if (this.props.showSiteDescriptions) {
|
||||||
return (<Label>{site.description}</Label>);
|
return (<Label>{site.description}</Label>);
|
||||||
}
|
}
|
||||||
|
@ -273,19 +272,19 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
private SetupFilters(): Array<IContextualMenuItem> {
|
private SetupFilters(): Array<IContextualMenuItem> {
|
||||||
console.log(JSON.stringify("in SetupFilters"));
|
console.log(JSON.stringify("in SetupFilters"));
|
||||||
const items = new Array<IContextualMenuItem>();
|
const items = new Array<IContextualMenuItem>();
|
||||||
for (const uf of this.state.userFilters) {
|
for (const uf of this.state.userFilters) {
|
||||||
const item: IContextualMenuItem = {
|
const item: IContextualMenuItem = {
|
||||||
key: uf.managedPropertyName,
|
key: uf.managedPropertyName,
|
||||||
name: uf.managedPropertyName,
|
name: uf.managedPropertyName,
|
||||||
title: uf.managedPropertyName,
|
title: uf.managedPropertyName,
|
||||||
href:null,
|
href: null,
|
||||||
|
|
||||||
}
|
}
|
||||||
item.items = [];
|
item.subMenuProps = { items: [] };
|
||||||
for (const value of uf.values) {
|
for (const value of uf.values) {
|
||||||
item.items.push({
|
item.subMenuProps.items.push({
|
||||||
key: value,
|
key: value,
|
||||||
data: {
|
data: {
|
||||||
managedPropertyName: uf.managedPropertyName,
|
managedPropertyName: uf.managedPropertyName,
|
||||||
|
@ -311,16 +310,16 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public AppliedFilterExists(managedPropertyName: string, value: string): boolean {
|
public AppliedFilterExists(managedPropertyName: string, value: string): boolean {
|
||||||
console.log(JSON.stringify("in AppliedFilterExists"));
|
console.log(JSON.stringify("in AppliedFilterExists"));
|
||||||
|
|
||||||
const selectedFilter = _.find(this.state.appliedUserFilters, af => {
|
const selectedFilter = _.find(this.state.appliedUserFilters, af => {
|
||||||
return (af.managedPropertyName === managedPropertyName && af.value === value);
|
return (af.managedPropertyName === managedPropertyName && af.value === value);
|
||||||
});
|
});
|
||||||
if (selectedFilter) {
|
if (selectedFilter) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,14 +330,24 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public ToggleAppliedUserFilter(item: IContextualMenuItem) {
|
public ToggleAppliedUserFilter(item: IContextualMenuItem) {
|
||||||
console.log(JSON.stringify("in ToggleAppliedUserFilter"));
|
console.log(JSON.stringify("in ToggleAppliedUserFilter"));
|
||||||
if (this.AppliedFilterExists(item.data.managedPropertyName, item.data.value)) {
|
if (this.AppliedFilterExists(item.data.managedPropertyName, item.data.value)) {
|
||||||
this.state.appliedUserFilters = this.state.appliedUserFilters.filter(af => {
|
// this.state.appliedUserFilters = this.state.appliedUserFilters.filter(af => {
|
||||||
return (af.managedPropertyName !== item.data.managedPropertyName || af.value !== item.data.value);
|
// return (af.managedPropertyName !== item.data.managedPropertyName || af.value !== item.data.value);
|
||||||
});
|
// });
|
||||||
|
this.setState((current) => ({
|
||||||
|
...current,
|
||||||
|
appliedUserFilters: current.appliedUserFilters.filter(af => {
|
||||||
|
return (af.managedPropertyName !== item.data.managedPropertyName || af.value !== item.data.value);
|
||||||
|
})
|
||||||
|
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.state.appliedUserFilters.push(new AppliedUserFilter(item.data.managedPropertyName, item.data.value));
|
// this.state.appliedUserFilters.push(new AppliedUserFilter(item.data.managedPropertyName, item.data.value));
|
||||||
|
let temp = this.state.appliedUserFilters;
|
||||||
|
temp.push(new AppliedUserFilter(item.data.managedPropertyName, item.data.value));
|
||||||
|
this.setState((current) => ({ ...current, appliedUserFilters: temp }))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -351,22 +360,24 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
*
|
*
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public filterSites() {
|
public filterSites(sites: Site[]): Site[] {
|
||||||
console.log(JSON.stringify("in filterSites"));
|
console.log(JSON.stringify("in filterSites"));
|
||||||
if (this.state.appliedUserFilters.length === 0) {
|
if (this.state.appliedUserFilters.length === 0) {
|
||||||
this.state.filteredSites = this.state.sites;
|
return sites;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
this.state.filteredSites = this.state.sites.filter(site => {
|
let filteredSites = sites.filter(site => {
|
||||||
debugger;
|
debugger;
|
||||||
for (const auf of this.state.appliedUserFilters) {
|
for (const auf of this.state.appliedUserFilters) {
|
||||||
if (site[auf.managedPropertyName] !== auf.value) {
|
if (site[auf.managedPropertyName] === auf.value) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
return filteredSites;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -381,16 +392,17 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
* @memberOf PropertyBagFilteredSiteList
|
* @memberOf PropertyBagFilteredSiteList
|
||||||
*/
|
*/
|
||||||
public filterOnMetadata(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
|
public filterOnMetadata(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
|
||||||
console.log(JSON.stringify("in filterOnMetadata"));
|
console.log(JSON.stringify("in filterOnMetadata"));
|
||||||
this.ToggleAppliedUserFilter(item);
|
this.ToggleAppliedUserFilter(item);
|
||||||
this.filterSites();
|
// this.filterSites();
|
||||||
this.setState(this.state);
|
// this.setState(this.state);
|
||||||
|
this.setState((current) => ({ ...current, filteredSites: this.filterSites(current.sites) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public doNothing(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
|
public doNothing(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
|
||||||
console.log(JSON.stringify("in doNothing"));
|
console.log(JSON.stringify("in doNothing"));
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,11 +423,13 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
const commandItems: Array<IContextualMenuItem> = this.SetupFilters();
|
const commandItems: Array<IContextualMenuItem> = this.SetupFilters();
|
||||||
console.log(JSON.stringify("commandItems follow"));
|
console.log(JSON.stringify("commandItems follow"));
|
||||||
console.log(JSON.stringify(commandItems));
|
console.log(JSON.stringify(commandItems));
|
||||||
return (
|
return (
|
||||||
<div >
|
<div >
|
||||||
<Label>{this.props.description}</Label>
|
<Label>{this.props.description}</Label>
|
||||||
|
<Label>Sites:{this.state.sites.length}</Label>
|
||||||
|
<Label>FoltererdSites:{this.state.filteredSites.length}</Label>
|
||||||
<CommandBar items={commandItems} />
|
<CommandBar items={commandItems} />
|
||||||
<MessageDisplay
|
<MessageDisplay
|
||||||
messages={this.state.errorMessages}
|
messages={this.state.errorMessages}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/// <reference types="mocha" />
|
// /// <reference types="mocha" />
|
||||||
|
|
||||||
import { assert } from 'chai';
|
// import { assert } from 'chai';
|
||||||
|
|
||||||
describe('PropertyBagFilteredSiteListWebPart', () => {
|
// describe('PropertyBagFilteredSiteListWebPart', () => {
|
||||||
it('should do something', () => {
|
// it('should do something', () => {
|
||||||
assert.ok(true);
|
// assert.ok(true);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
{
|
{
|
||||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "8634e32b-eda4-483d-8fe9-5f2075339eb8",
|
"id": "8634e32b-eda4-483d-8fe9-5f2075339eb8",
|
||||||
"alias": "PropertyBagGlobalNavWebPart",
|
"alias": "PropertyBagGlobalNavWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
"version": "0.0.1",
|
"version": "*",
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
|
"supportedHosts": [
|
||||||
|
"SharePointWebPart"
|
||||||
|
],
|
||||||
|
"safeWithCustomScriptDisabled": false,
|
||||||
"preconfiguredEntries": [
|
"preconfiguredEntries": [
|
||||||
{
|
{
|
||||||
"groupId": "8634e32b-eda4-483d-8fe9-5f2075339eb8",
|
"groupId": "8634e32b-eda4-483d-8fe9-5f2075339eb8",
|
||||||
|
|
|
@ -1,11 +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 utils from "../shared/utils";
|
import utils from "../shared/utils";
|
||||||
import * as strings from 'propertyBagGlobalNavStrings';
|
import * as strings from 'propertyBagGlobalNavStrings';
|
||||||
import PropertyBagGlobalNav from './components/PropertyBagGlobalNav';
|
import PropertyBagGlobalNav from './components/PropertyBagGlobalNav';
|
||||||
|
@ -19,7 +16,7 @@ export default class PropertyBagGlobalNavWebPart extends BaseClientSideWebPart<I
|
||||||
PropertyBagGlobalNav,
|
PropertyBagGlobalNav,
|
||||||
{
|
{
|
||||||
description: this.properties.description,
|
description: this.properties.description,
|
||||||
managedProperties: utils.parseMultilineTextToArray( this.properties.managedProperties),
|
managedProperties: utils.parseMultilineTextToArray(this.properties.managedProperties),
|
||||||
siteTemplatesToInclude: utils.parseMultilineTextToArray(this.properties.siteTemplatesToInclude),
|
siteTemplatesToInclude: utils.parseMultilineTextToArray(this.properties.siteTemplatesToInclude),
|
||||||
filters: utils.parseMultilineTextToArray(this.properties.filters),
|
filters: utils.parseMultilineTextToArray(this.properties.filters),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
export interface IPropertyBagGlobalNavProps {
|
export interface IPropertyBagGlobalNavProps {
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
siteTemplatesToInclude: Array<string>; //STS#1 STS#2 leave off the #1 to get all STS
|
siteTemplatesToInclude: Array<string>; //STS#1 STS#2 leave off the #1 to get all STS
|
||||||
filters: Array<string>; // managedPropertyname=valiust separated by \n (new line)
|
filters: Array<string>; // managedPropertyname=valiust separated by \n (new line)
|
||||||
managedProperties: Array<string>;// managed properties to build the menu from.
|
managedProperties: Array<string>;// managed properties to build the menu from.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import '~@fluentui/react/dist/sass/References.scss';
|
||||||
|
|
||||||
.helloWorld {
|
.helloWorld {
|
||||||
.container {
|
.container {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
|
@ -29,7 +31,7 @@
|
||||||
// Basic Button
|
// Basic Button
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
|
@ -1,30 +1,12 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { IPropertyBagGlobalNavProps } from './IPropertyBagGlobalNavProps';
|
|
||||||
import pnp from "sp-pnp-js";
|
|
||||||
import { SortDirection } from "sp-pnp-js";
|
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import { SearchQuery, SearchResults } from "sp-pnp-js";
|
import * as React from 'react';
|
||||||
import { css } from "office-ui-fabric-react";
|
import pnp, { SearchQuery, SearchResults } from "sp-pnp-js";
|
||||||
|
import { IPropertyBagGlobalNavProps } from './IPropertyBagGlobalNavProps';
|
||||||
|
|
||||||
import { Label } from "office-ui-fabric-react/lib/Label";
|
import { CommandBar } from "office-ui-fabric-react/lib/CommandBar";
|
||||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||||
import { Link } from "office-ui-fabric-react/lib/Link";
|
|
||||||
import { List } from "office-ui-fabric-react/lib/List";
|
|
||||||
import { Button, ButtonType } from "office-ui-fabric-react/lib/Button";
|
|
||||||
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
|
|
||||||
import * as md from "../../shared/MessageDisplay";
|
import * as md from "../../shared/MessageDisplay";
|
||||||
import utils from "../../shared/utils";
|
import utils from "../../shared/utils";
|
||||||
import { CommandBar, ICommandBarProps } from "office-ui-fabric-react/lib/CommandBar";
|
|
||||||
import {
|
|
||||||
DetailsList, DetailsListLayoutMode, IColumn, IGroupedList, SelectionMode, CheckboxVisibility, IGroup
|
|
||||||
} from "office-ui-fabric-react/lib/DetailsList";
|
|
||||||
import {
|
|
||||||
GroupedList
|
|
||||||
} from "office-ui-fabric-react/lib/GroupedList";
|
|
||||||
import {
|
|
||||||
IViewport
|
|
||||||
} from "office-ui-fabric-react/lib/utilities/decorators/withViewport";
|
|
||||||
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
|
|
||||||
export class PropertyBagGlobalNavState {
|
export class PropertyBagGlobalNavState {
|
||||||
public menuitems: Array<IContextualMenuItem>; // The menuItems to display
|
public menuitems: Array<IContextualMenuItem>; // The menuItems to display
|
||||||
public errorMessages: Array<md.Message>;// any error messages
|
public errorMessages: Array<md.Message>;// any error messages
|
||||||
|
@ -43,28 +25,29 @@ export default class PropertyBagGlobalNav extends React.Component<IPropertyBagGl
|
||||||
*
|
*
|
||||||
* @memberOf PropertyBagGlobalNav
|
* @memberOf PropertyBagGlobalNav
|
||||||
*/
|
*/
|
||||||
public addMenuItem(r: any): void {
|
public addMenuItem(items: Array<IContextualMenuItem>, r: any): Array<IContextualMenuItem> {
|
||||||
let currentItem: IContextualMenuItem;
|
let currentItem: IContextualMenuItem;
|
||||||
let currentSet: Array<IContextualMenuItem> = this.state.menuitems;
|
let currentSet: Array<IContextualMenuItem> = items;
|
||||||
debugger;
|
|
||||||
for (const managedProperty of this.props.managedProperties) {
|
for (const managedProperty of this.props.managedProperties) {
|
||||||
if (r[managedProperty]) {// if site does not have this property set
|
if (r[managedProperty]) {// if site does not have this property set
|
||||||
const value = r[managedProperty].trim();
|
const value = r[managedProperty].trim();
|
||||||
currentItem = _.find(currentSet, i => { return i.key === value; });
|
currentItem = _.find(currentSet, i => { return i.key === value; });
|
||||||
if (!currentItem) {
|
if (!currentItem) {
|
||||||
const idx = currentSet.push({ key: value, name: value, items: [] });
|
const idx = currentSet.push({ key: value, name: value, subMenuProps: { items: [] } });
|
||||||
currentItem = currentSet[idx - 1];
|
currentItem = currentSet[idx - 1];
|
||||||
}
|
}
|
||||||
currentSet = currentItem.items;
|
currentSet = currentItem.subMenuProps.items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentItem) { // should have it if site does have this property set
|
if (currentItem) { // should have it if site does have this property set
|
||||||
currentItem.items.push({
|
currentItem.subMenuProps.items.push({
|
||||||
key: r['Title'],
|
key: r['Title'],
|
||||||
name: r['Title'],
|
name: r['Title'],
|
||||||
href: r['SPSiteUrl']
|
href: r['SPSiteUrl']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Gets the list of sites to be displayed in the Menu using the filters specified in
|
* Gets the list of sites to be displayed in the Menu using the filters specified in
|
||||||
|
@ -107,12 +90,20 @@ export default class PropertyBagGlobalNav extends React.Component<IPropertyBagGl
|
||||||
|
|
||||||
};
|
};
|
||||||
pnp.sp.search(q).then((results: SearchResults) => {
|
pnp.sp.search(q).then((results: SearchResults) => {
|
||||||
this.state.menuitems = [];
|
// this.state.menuitems = [];
|
||||||
|
// for (const r of results.PrimarySearchResults) {
|
||||||
|
// this.addMenuItem(r);
|
||||||
|
// }
|
||||||
|
// this.setState(this.state);
|
||||||
|
let menuitems = [];
|
||||||
for (const r of results.PrimarySearchResults) {
|
for (const r of results.PrimarySearchResults) {
|
||||||
this.addMenuItem(r);
|
this.addMenuItem(menuitems, r);
|
||||||
}
|
}
|
||||||
|
debugger;
|
||||||
|
this.setState((current) => ({ ...current, menuitems: menuitems }));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.setState(this.state);
|
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
debugger;
|
debugger;
|
||||||
this.state.errorMessages.push(new md.Message(err));
|
this.state.errorMessages.push(new md.Message(err));
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/// <reference types="mocha" />
|
// /// <reference types="mocha" />
|
||||||
|
|
||||||
import { assert } from 'chai';
|
// import { assert } from 'chai';
|
||||||
|
|
||||||
describe('PropertyBagGlobalNavWebPart', () => {
|
// describe('PropertyBagGlobalNavWebPart', () => {
|
||||||
it('should do something', () => {
|
// it('should do something', () => {
|
||||||
assert.ok(true);
|
// assert.ok(true);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBa
|
||||||
* @class Message
|
* @class Message
|
||||||
*/
|
*/
|
||||||
export class Message {
|
export class Message {
|
||||||
public Id: string;
|
public Id: string;
|
||||||
public text: string;
|
public text: string;
|
||||||
public constructor(msg: string) {
|
public constructor(msg: string) {
|
||||||
this.text = msg;
|
this.text = msg;
|
||||||
this.Id = Guid.newGuid().toString();
|
this.Id = Guid.newGuid().toString();
|
||||||
|
@ -37,15 +37,16 @@ export default class MessageDisplay extends React.Component<IMessageDisplayProps
|
||||||
* @memberOf MessageDisplay
|
* @memberOf MessageDisplay
|
||||||
*/
|
*/
|
||||||
public createDismissHandler = (messageId) => (vale) => {
|
public createDismissHandler = (messageId) => (vale) => {
|
||||||
this.props.hideMessage(messageId);
|
this.props.hideMessage(messageId);
|
||||||
}
|
}
|
||||||
public render(): React.ReactElement<IMessageDisplayProps> {
|
public render(): React.ReactElement<IMessageDisplayProps> {
|
||||||
return (
|
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
{this.props.messages.map((message, y, z) => {
|
{this.props.messages.map((message, y, z) => {
|
||||||
return (
|
return (
|
||||||
<MessageBar
|
<MessageBar
|
||||||
messageBarType={MessageBarType.remove}
|
messageBarType={MessageBarType.error}
|
||||||
isMultiline={true}
|
isMultiline={true}
|
||||||
onDismiss={this.createDismissHandler(message.Id)}>
|
onDismiss={this.createDismissHandler(message.Id)}>
|
||||||
{message.text}
|
{message.text}
|
||||||
|
|
|
@ -134,7 +134,7 @@ export default class utils {
|
||||||
clientContext.load(web);
|
clientContext.load(web);
|
||||||
clientContext.load(webProps);
|
clientContext.load(webProps);
|
||||||
clientContext.executeQueryAsync(
|
clientContext.executeQueryAsync(
|
||||||
(sender, args) => { resolve(); },
|
(sender, args) => { resolve(webProps); },
|
||||||
(sender, args) => { reject(args.get_message()); }
|
(sender, args) => { reject(args.get_message()); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,41 @@
|
||||||
{
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-4.5/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "commonjs",
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"experimentalDecorators": true,
|
||||||
"types": [
|
"types": [
|
||||||
"webpack-env"
|
"webpack-env",
|
||||||
|
"microsoft-ajax",
|
||||||
|
"sharepoint"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es2015.promise",
|
||||||
|
"es5",
|
||||||
|
"dom",
|
||||||
|
"es2015.collection"
|
||||||
|
],
|
||||||
|
"outDir": "lib",
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@microsoft"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
}
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"rulesDirectory": "./config"
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
// Type definitions for Microsoft ODSP projects
|
|
||||||
// Project: ODSP
|
|
||||||
|
|
||||||
/* Global definition for UNIT_TEST builds */
|
|
||||||
declare const UNIT_TEST: boolean;
|
|
|
@ -1,4 +0,0 @@
|
||||||
/// <reference path="@ms/odsp.d.ts" />
|
|
||||||
/// <reference path="assertion-error/assertion-error.d.ts" />
|
|
||||||
/// <reference path="knockout/knockout.d.ts" />
|
|
||||||
/// <referehce path="SP/SP.d.ts />
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,197 @@
|
||||||
|
|
||||||
|
SPFX PROJECT UPGRADE
|
||||||
|
====================
|
||||||
|
|
||||||
|
Upgrades SharePoint Framework project to the specified version
|
||||||
|
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
|
||||||
|
m365 spfx project upgrade [options]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
|
||||||
|
-v, --toVersion [toVersion]
|
||||||
|
The version of SharePoint Framework to which upgrade the project
|
||||||
|
|
||||||
|
--packageManager [packageManager]
|
||||||
|
The package manager you use. Supported managers npm,pnpm,yarn. Default npm
|
||||||
|
|
||||||
|
--shell [shell]
|
||||||
|
The shell you use. Supported shells bash,powershell,cmd. Default bash
|
||||||
|
|
||||||
|
--preview
|
||||||
|
Upgrade project to the latest SPFx preview version
|
||||||
|
|
||||||
|
-f, --outputFile [outputFile]
|
||||||
|
Path to the file where the upgrade report should be stored in. Ignored when output is tour
|
||||||
|
|
||||||
|
-h, --help [help]
|
||||||
|
Output usage information. Optionally, specify which section of command's help you want to see. Allowed values are options, examples, remarks, response, full. Default is full.
|
||||||
|
|
||||||
|
--query [query]
|
||||||
|
JMESPath query string. See http://jmespath.org/ for more information and examples
|
||||||
|
|
||||||
|
-o, --output [output]
|
||||||
|
Output type. json,text,csv,md. Default json
|
||||||
|
|
||||||
|
--verbose
|
||||||
|
Runs command with verbose logging
|
||||||
|
|
||||||
|
--debug
|
||||||
|
Runs command with debug logging
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
REMARKS
|
||||||
|
|
||||||
|
The spfx project upgrade command helps you upgrade your SharePoint Framework project to the specified version. If no version is specified, the command will upgrade to the latest version of the SharePoint Framework it supports (v1.17.2).
|
||||||
|
|
||||||
|
This command doesn't change your project files. Instead, it gives you a report with all steps necessary to upgrade your project to the specified version of the SharePoint Framework. Changing project files is error-prone, especially when it comes to updating your solution's code. This is why at this moment, this command produces a report that you can use yourself to perform the necessary updates and verify that everything is working as expected.
|
||||||
|
|
||||||
|
!!! important
|
||||||
|
Run this command in the folder where the project that you want to upgrade is located. This command doesn't change your project files.
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to SharePoint Framework version 1.5.0 and save the findings in a Markdown file
|
||||||
|
|
||||||
|
m365 spfx project upgrade --toVersion 1.5.0 --output md > "upgrade-report.md"
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to SharePoint Framework version 1.5.0 and show the summary of the findings in the shell
|
||||||
|
|
||||||
|
m365 spfx project upgrade --toVersion 1.5.0 --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the latest preview version
|
||||||
|
|
||||||
|
m365 spfx project upgrade --preview --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the specified preview version
|
||||||
|
|
||||||
|
m365 spfx project upgrade --toVersion 1.12.1-rc.0 --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the latest SharePoint Framework version supported by the CLI for Microsoft 365 using pnpm
|
||||||
|
|
||||||
|
m365 spfx project upgrade --packageManager pnpm --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the latest SharePoint Framework version supported by the CLI for Microsoft 365
|
||||||
|
|
||||||
|
m365 spfx project upgrade --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the latest SharePoint Framework version supported by the CLI for Microsoft 365 using PowerShell
|
||||||
|
|
||||||
|
m365 spfx project upgrade --shell powershell --output text
|
||||||
|
|
||||||
|
|
||||||
|
Get instructions to upgrade the current SharePoint Framework project to the latest version of SharePoint Framework and save the findings in a CodeTour (https://aka.ms/codetour) file
|
||||||
|
|
||||||
|
m365 spfx project upgrade --output tour
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RESPONSE
|
||||||
|
|
||||||
|
When upgrading an SPFx project built using version 1.15.0 to SPFx version 1.15.2, you'll get output similar to following (output is truncated):
|
||||||
|
|
||||||
|
JSON
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "Upgrade SharePoint Framework dependency package @microsoft/sp-core-library",
|
||||||
|
"id": "FN001001",
|
||||||
|
"file": "./package.json",
|
||||||
|
"position": {
|
||||||
|
"line": 15,
|
||||||
|
"character": 5
|
||||||
|
},
|
||||||
|
"resolution": "npm i -SE @microsoft/sp-core-library@1.15.2",
|
||||||
|
"resolutionType": "cmd",
|
||||||
|
"severity": "Required",
|
||||||
|
"title": "@microsoft/sp-core-library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Update version in .yo-rc.json",
|
||||||
|
"id": "FN010001",
|
||||||
|
"file": "./.yo-rc.json",
|
||||||
|
"position": {
|
||||||
|
"line": 5,
|
||||||
|
"character": 5
|
||||||
|
},
|
||||||
|
"resolution": "{\\\n \"@microsoft/generator-sharepoint\": {\\\n \"version\": \"1.15.2\"\\\n }\\\n}",
|
||||||
|
"resolutionType": "json",
|
||||||
|
"severity": "Recommended",
|
||||||
|
"title": ".yo-rc.json version"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
|
Execute in bash
|
||||||
|
-----------------------
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.15.2
|
||||||
|
|
||||||
|
./.yo-rc.json
|
||||||
|
-------------
|
||||||
|
Update version in .yo-rc.json:
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.15.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Markdown
|
||||||
|
|
||||||
|
# Upgrade project HelloWorld to v1.15.2
|
||||||
|
|
||||||
|
Date: 20/11/2022
|
||||||
|
|
||||||
|
## Findings
|
||||||
|
|
||||||
|
Following is the list of steps required to upgrade your project to SharePoint Framework version 1.15.2. Summary of the modifications is included at the end of the report.
|
||||||
|
|
||||||
|
### FN001001 @microsoft/sp-core-library | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-core-library
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
`sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.15.2
|
||||||
|
|
||||||
|
|
||||||
|
File: ./package.json:17:5
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
### Execute script
|
||||||
|
|
||||||
|
`sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.15.2
|
||||||
|
`
|
||||||
|
|
||||||
|
### Modify files
|
||||||
|
|
||||||
|
#### ./.yo-rc.json
|
||||||
|
|
||||||
|
Update version in .yo-rc.json:
|
||||||
|
|
||||||
|
`json
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.15.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue