|
@ -0,0 +1,25 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Build generated files
|
||||
dist
|
||||
lib
|
||||
solution
|
||||
temp
|
||||
*.sppkg
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Visual Studio files
|
||||
.ntvs_analysis.dat
|
||||
.vs
|
||||
bin
|
||||
obj
|
||||
|
||||
# Resx Generated Code
|
||||
*.resx.ts
|
||||
|
||||
# Styles Generated Code
|
||||
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"isCreatingSolution": false,
|
||||
"environment": "spo",
|
||||
"version": "1.10.0",
|
||||
"libraryName": "r-fx-portal",
|
||||
"libraryId": "955d006f-7cc7-461f-8c5d-29593aebac61",
|
||||
"packageManager": "npm",
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
# Private Folder Manager
|
||||
|
||||
## Summary
|
||||
|
||||
This sample provides a webpart that can be used to manage Document Libraries with Secured Subfolders. The use case this was developed for is a Request for Proposal site. A Document library is created for each RFP and subfolders are created within that Library for each external supplier invited to participate in that RFP.
|
||||
|
||||
The application manages all the security groups set up for the various libraries and folders so that suppliers only see RFP's they were ivited to participate in and only thier folders.
|
||||
|
||||
|
||||
![mainpanel](assets/HomeScreen.png "Main Screen")
|
||||
|
||||
![AddingAlibrary](assets/AddALibrary.png "Add A library")
|
||||
|
||||
![ManagingFolders](assets/ManageFolders.png "Manage Folders")
|
||||
|
||||
![AddingAfolder](assets/AddAFolder.png "Add a folder")
|
||||
|
||||
![Configuration](assets/Configuration.png "Configuration")
|
||||
|
||||
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
||||
|
||||
|
||||
|
||||
## Applies to
|
||||
|
||||
* [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
|
||||
* [Microsoft 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
|
||||
|
||||
> Update accordingly as needed.
|
||||
> DELETE THIS PARAGRAPH BEFORE SUBMITTING
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react Private Folder Manager | [Russell Gove](https://github.com/russgove) ([@russgove](https://twitter.com/russgove))
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|July 2, 2021|Initial release
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
* Clone this repository
|
||||
* in the command line run:
|
||||
* `npm install`
|
||||
* `gulp serve`
|
||||
|
||||
Create two Lists to hold the List of RFX's and the list of RFX Folders.
|
||||
The lists must have the schemas below (using site content types is not needed)
|
||||
|
||||
The RFX List:
|
||||
![rfx](assets/RFX.PNG "RFX")
|
||||
(The title was renamed to RFX Number)
|
||||
|
||||
The RFX Folder List
|
||||
![rfxfolders](assets/RFXFolders.PNG "RFXFolders")
|
||||
(The RFx column is a lookup to the Title/RFX Number in the RFx list)
|
||||
|
||||
The scripts folder contains some feeble attempts to generate these lists using a sitescript at the last minute.
|
||||
If anyone is good at that , I could use some help!
|
||||
|
||||
## Features
|
||||
|
||||
Description of the web part with possible additional details than in short summary.
|
||||
This Web Part illustrates the following concepts on top of the SharePoint Framework:
|
||||
|
||||
* topic 1
|
||||
* topic 2
|
||||
* topic 3
|
||||
|
||||
|
||||
|
||||
## Disclaimer
|
||||
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||
|
||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
||||
|
||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
||||
|
||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/YOUR-SOLUTION-NAME" />
|
||||
|
||||
This package produces the following:
|
||||
|
||||
* lib/* - intermediate-stage commonjs build artifacts
|
||||
* dist/* - the bundled script, along with other resources
|
||||
* deploy/* - all resources which should be uploaded to a CDN.
|
||||
|
||||
### Build options
|
||||
|
||||
gulp clean - TODO
|
||||
gulp test - TODO
|
||||
gulp serve - TODO
|
||||
gulp bundle - TODO
|
||||
gulp package-solution - TODO
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"vendor-maintenance-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/vendorMaintenance/VendorMaintenanceWebPart.js",
|
||||
"manifest": "./src/webparts/vendorMaintenance/VendorMaintenanceWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"request-maintenance-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/requestMaintenance/RequestMaintenanceWebPart.js",
|
||||
"manifest": "./src/webparts/requestMaintenance/RequestMaintenanceWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"VendorMaintenanceWebPartStrings": "lib/webparts/vendorMaintenance/loc/{locale}.js",
|
||||
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
|
||||
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js",
|
||||
"RequestMaintenanceWebPartStrings": "lib/webparts/requestMaintenance/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "r-fx-portal",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "r-fx-portal-client-side-solution",
|
||||
"id": "955d006f-7cc7-461f-8c5d-29593aebac61",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/r-fx-portal.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
|
||||
"serveConfigurations": {
|
||||
"default": {
|
||||
"pageUrl": "https://russellwgove.sharepoint.com/sites/ReactPrivateLibraries/_layouts/15/workbench.aspx"
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
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.`);
|
||||
|
||||
build.initialize(require('gulp'));
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "r-fx-portal",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/applicationinsights-react-js": "3.0.3",
|
||||
"@microsoft/applicationinsights-web": "2.5.8",
|
||||
"@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.6",
|
||||
"@pnp/logging": "2.0.6",
|
||||
"@pnp/odata": "2.0.6",
|
||||
"@pnp/polyfill-ie11": "2.0.2",
|
||||
"@pnp/sp": "2.0.6",
|
||||
"@pnp/spfx-controls-react": "1.20.0",
|
||||
"@pnp/spfx-property-controls": "1.20.0",
|
||||
"@types/es6-promise": "0.0.33",
|
||||
"@types/react": "16.8.8",
|
||||
"@types/react-csv": "1.1.1",
|
||||
"@types/react-dom": "16.8.3",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"date-fns": "2.16.1",
|
||||
"office-ui-fabric-react": "6.189.2",
|
||||
"react": "16.8.5",
|
||||
"react-csv": "2.0.3",
|
||||
"react-dom": "16.8.5"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "16.8.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "1.10.0",
|
||||
"@microsoft/sp-tslint-rules": "1.10.0",
|
||||
"@microsoft/sp-module-interfaces": "1.10.0",
|
||||
"@microsoft/sp-webpart-workbench": "1.10.0",
|
||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/mocha": "2.2.38",
|
||||
"ajv": "~5.2.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
cd C:\Users\trwg1\sp-dev-fx-webparts\samples\react-private-libraries\scripts\
|
||||
#connect-pnponline -Url "https://russellwgove.sharepoint.com/sites/deleteme"
|
||||
$it=Get-Content '.\rfx.json'-Raw
|
||||
Add-PNPSiteScript -Title "RFx Lists" -Content $it
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json",
|
||||
"actions": [{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Text' DisplayName='Closing Date' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{2701f2bf-d45f-4672-9774-6dab88b9792d}' Name='rfxClosingDate' StaticName='rfxClosingDate' MaxLength='255' Customization='' PITarget='' PIAttribute = '' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='User' DisplayName='Contract Specialist' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{843f09c7-19cb-4889-8b39-d3132643568c}' Name='rfxContractSpecialist' StaticName='rfxContractSpecialist' ShowField='ImnName' UserSelectionScope='0' UserSelectionMode = 'PeopleOnly' List='UserInfo' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Note' DisplayName='Description' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' Sortable='FALSE' ID='{a04fc484-b807-4fef-a970-cbd007deeb87}' Name='rfxDescription' StaticName='rfxDescription' RichText='TRUE' RichTextMode='FullHtml' IsolateStyles = 'TRUE' AppendOnly='FALSE' NumLines='6' UnlimitedLengthInDocumentLibrary='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute = '' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Owners Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{34889607-f472-4d16-8f5b-b5ba6617c6cd}' Name='rfxOwnersGroupId' StaticName='rfxOwnersGroupId' Percentage='FALSE' Customization='' PITarget='' PrimaryPITarget = '' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Members Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{a395c515-2e66-4009-9704-64533250b082}' Name='rfxLibraryMembersGroupId' StaticName='rfxLibraryMembersGroupId' Percentage='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Visitors Group Id' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly = 'FALSE' CanToggleHidden='FALSE' ID='{b0f7ea7e-1bf3-44d7-a293-9b1c6b6af67c}' Name='rfxLibraryVisitorsGroupId' StaticName='rfxLibraryVisitorsGroupId' Percentage='FALSE' Customization = '' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createContentType",
|
||||
"name": "RFX",
|
||||
"id": "0x0100C654015369B79E4DA6572D4FE4C0BFBD",
|
||||
"description": "",
|
||||
"parentId": "0x01",
|
||||
"hidden": false,
|
||||
"group": "_RFX",
|
||||
"subactions": [{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxClosingDate"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxContractSpecialist"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxDescription"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxOwnersGroupId"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxLibraryMembersGroupId"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxLibraryVisitorsGroupId"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json",
|
||||
"actions": [{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": null,
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Folder Visitors Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{0c44d811-1669-4109-b2ae-133c764e2eb3}' Name='rfxFolderVisitorsGroupId' StaticName='rfxFolderVisitorsGroupId' Percentage='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Folder Members Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{26b670d4-2d58-4798-becf-f869a3b28497}' Name='rfxFolderMembersGroupId' StaticName='rfxFolderMembersGroupId' Percentage='FALSE' Customization='' PITarget = '' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Text' DisplayName='Closing Date' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{2701f2bf-d45f-4672-9774-6dab88b9792d}' Name='rfxClosingDate' StaticName='rfxClosingDate' MaxLength='255' Customization='' PITarget='' PrimaryPITarget='' PIAttribute = '' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='User' DisplayName='Contract Specialist' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{843f09c7-19cb-4889-8b39-d3132643568c}' Name='rfxContractSpecialist' StaticName='rfxContractSpecialist' ShowField='ImnName' UserSelectionScope='0' UserSelectionMode = 'PeopleOnly' List='UserInfo' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Note' DisplayName='Description' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' Sortable='FALSE' ID='{a04fc484-b807-4fef-a970-cbd007deeb87}' Name='rfxDescription' StaticName='rfxDescription' RichText='TRUE' RichTextMode='FullHtml' IsolateStyles = 'TRUE' AppendOnly='FALSE' NumLines='6' UnlimitedLengthInDocumentLibrary='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute = '' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Owners Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{34889607-f472-4d16-8f5b-b5ba6617c6cd}' Name='rfxOwnersGroupId' StaticName='rfxOwnersGroupId' Percentage='FALSE' Customization='' PITarget='' PrimaryPITarget = '' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Members Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{a395c515-2e66-4009-9704-64533250b082}' Name='rfxLibraryMembersGroupId' StaticName='rfxLibraryMembersGroupId' Percentage='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createSiteColumnXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Visitors Group Id' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly = 'FALSE' CanToggleHidden='FALSE' ID='{b0f7ea7e-1bf3-44d7-a293-9b1c6b6af67c}' Name='rfxLibraryVisitorsGroupId' StaticName='rfxLibraryVisitorsGroupId' Percentage='FALSE' Customization = '' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />",
|
||||
"pushChanges": true
|
||||
},
|
||||
{
|
||||
"verb": "createContentType",
|
||||
"name": "RFXFolder",
|
||||
"id": "0x010061598027686ADA4CA1D35CA1D0DEC987",
|
||||
"description": "",
|
||||
"parentId": "0x01",
|
||||
"hidden": false,
|
||||
"group": "_RFX",
|
||||
"subactions": [{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "RFx"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxFolderVisitorsGroupId"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxFolderMembersGroupId"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"verb": "createContentType",
|
||||
"name": "RFX",
|
||||
"id": "0x0100C654015369B79E4DA6572D4FE4C0BFBD",
|
||||
"description": "",
|
||||
"parentId": "0x01",
|
||||
"hidden": false,
|
||||
"group": "_RFX",
|
||||
"subactions": [{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxClosingDate"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxContractSpecialist"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxDescription"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxOwnersGroupId"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxLibraryMembersGroupId"
|
||||
},
|
||||
{
|
||||
"verb": "addSiteColumn",
|
||||
"internalName": "rfxLibraryVisitorsGroupId"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"verb": "createSPList",
|
||||
"listName": "RFxs",
|
||||
"templateType": 100,
|
||||
"subactions": [{
|
||||
"verb": "addContentType",
|
||||
"name": "RFX",
|
||||
"id": "0x0100C654015369B79E4DA6572D4FE4C0BFBD"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field ID='{fa564e0f-0c70-4ab9-b863-0177e6ddd247}' Type='Text' Name='Title' DisplayName='RFx Number' Required='TRUE' SourceID='http://schemas.microsoft.com/sharepoint/v3' StaticName='Title' FromBaseType='TRUE' Indexed='TRUE' EnforceUniqueValues='TRUE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' MaxLength = '255' Sealed='FALSE' Customization='' PITarget='' PrimaryPITarget='' PIAttribute='' PrimaryPIAttribute='' Aggregation='' Node='' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Text' DisplayName='Closing Date' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{2701f2bf-d45f-4672-9774-6dab88b9792d}' Name='rfxClosingDate' StaticName='rfxClosingDate' MaxLength='255' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Members Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' ID='{a395c515-2e66-4009-9704-64533250b082}' Name='rfxLibraryMembersGroupId' StaticName='rfxLibraryMembersGroupId' Percentage='FALSE' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Library Visitors Group Id' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly = 'FALSE' CanToggleHidden='FALSE' ID='{b0f7ea7e-1bf3-44d7-a293-9b1c6b6af67c}' Name='rfxLibraryVisitorsGroupId' StaticName='rfxLibraryVisitorsGroupId' Percentage='FALSE' /> "
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Owners Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID='{34889607-f472-4d16-8f5b-b5ba6617c6cd}' Name='rfxOwnersGroupId' StaticName='rfxOwnersGroupId' Percentage='FALSE' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Note' DisplayName='Description' Group='Custom Columns' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' Sortable='FALSE' ID='{a04fc484-b807-4fef-a970-cbd007deeb87}' Name='rfxDescription' StaticName='rfxDescription' RichText='TRUE' RichTextMode='FullHtml' IsolateStyles='TRUE' AppendOnly='FALSE' NumLines='6' UnlimitedLengthInDocumentLibrary='FALSE' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='User' DisplayName='Contract Specialist' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden = 'FALSE' ID = '{843f09c7-19cb-4889-8b39-d3132643568c}' Name = 'rfxContractSpecialist' StaticName = 'rfxContractSpecialist' ShowField = 'ImnName' UserSelectionScope = '0' UserSelectionMode = 'PeopleOnly' List = 'UserInfo' / > "
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"verb": "addSPView",
|
||||
"name": "All Items",
|
||||
"viewFields": [
|
||||
"LinkTitle",
|
||||
"rfxClosingDate",
|
||||
"rfxContractSpecialist",
|
||||
"rfxOwnersGroupId",
|
||||
"rfxLibraryMembersGroupId",
|
||||
"rfxLibraryVisitorsGroupId"
|
||||
],
|
||||
"query": "",
|
||||
"rowLimit": 30,
|
||||
"isPaged": true,
|
||||
"makeDefault": true,
|
||||
"replaceViewFields": true
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"verb": "createSPList",
|
||||
"listName": "RFXFolders",
|
||||
"templateType": 100,
|
||||
"subactions": [{
|
||||
"verb": "addContentType",
|
||||
"name": "RFXFolder",
|
||||
"id": "0x010061598027686ADA4CA1D35CA1D0DEC987"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field ID='{fa564e0f-0c70-4ab9-b863-0177e6ddd247}' Type='Text' Name='Title' DisplayName='Folder Name' Required='TRUE' SourceID='http://schemas.microsoft.com /sharepoint/v3' StaticName='Title' FromBaseType='TRUE' EnforceUniqueValues='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' MaxLength='255' Sealed = 'FALSE' Customization = '' PITarget = '' PrimaryPITarget = '' PIAttribute = '' PrimaryPIAttribute = '' Aggregation = '' Node = '' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Folder Visitors Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' ID='{0c44d811-1669-4109-b2ae-133c764e2eb3}' Name='rfxFolderVisitorsGroupId' StaticName='rfxFolderVisitorsGroupId' Percentage='FALSE' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field Type='Number' DisplayName='Folder Members Group Id' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' ID='{26b670d4-2d58-4798-becf-f869a3b28497}' Name='rfxFolderMembersGroupId' StaticName='rfxFolderMembersGroupId' Percentage='FALSE' />"
|
||||
},
|
||||
{
|
||||
"verb": "addSPLookupFieldXml",
|
||||
"schemaXml": "<Field Type='Lookup' DisplayName='RFx' Group='_RFX' EnforceUniqueValues='FALSE' Required='FALSE' Hidden='FALSE' ReadOnly='FALSE' CanToggleHidden='FALSE' ID=' { dc4715d2 - d74f - 41 bc - 80 cb - ed55ef102a7a } ' Name=' RFx ' StaticName=' RFx ' ShowField=' Title ' UnlimitedLengthInDocumentLibrary=' FALSE ' />",
|
||||
"targetListName": "RFxs"
|
||||
},
|
||||
|
||||
{
|
||||
"verb": "addSPFieldXml",
|
||||
"schemaXml": "<Field ID='{5f190d91-3dbc-4489-9878-3c092caf35b6}' Hidden='TRUE' ReadOnly='TRUE' Type='Computed' Name='LinkTitle2' DisplayName='Folder Name' DisplayNameSrcField = 'Title' ClassInfo = 'Menu' AuthoringInfo = '(linked to item with edit menu) (old)' SourceID='http://schemas.microsoft.com/sharepoint/v3' StaticName = 'LinkTitle2' FromBaseType = 'TRUE' > < FieldRefs > < FieldRef Name = 'Title' / > < FieldRef Name = 'LinkTitleNoMenu' / > < FieldRef Name = '_EditMenuTableStart' / > < FieldRef Name = '_EditMenuTableEnd' / > < /FieldRefs > < DisplayPattern > < FieldSwitch > < Expr > < GetVar Name = 'FreeForm' / > < /Expr><Case Value='TRUE'><Field Name='LinkTitleNoMenu' / > < /Case><Default><Field Name='_EditMenuTableStart' / > <SetVar Name = 'ShowAccessibleIcon' Value = '1' / > < Field Name = 'LinkTitleNoMenu' / > < SetVar Name = 'ShowAccessibleIcon' Value = '0' / > < Field Name = '_EditMenuTableEnd' / > < /Default></FieldSwitch > < /DisplayPattern></Field > "
|
||||
}, {
|
||||
"verb": "addSPView",
|
||||
"name": "All Items",
|
||||
"viewFields": [
|
||||
"LinkTitle",
|
||||
"RFx",
|
||||
"rfxFolderVisitorsGroupId",
|
||||
"rfxFolderMembersGroupId"
|
||||
],
|
||||
"query": "",
|
||||
"rowLimit": 30,
|
||||
"isPaged": true,
|
||||
"makeDefault": true,
|
||||
"replaceViewFields": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,11 @@
|
|||
export interface IActivity {
|
||||
userEmail: string;
|
||||
userDisplayName: string;
|
||||
driveItemType: string;
|
||||
driveItemName: string;
|
||||
driveItemParentReference: string;
|
||||
activityRecordedTime:Date;
|
||||
action:string;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export interface IDrive {
|
||||
description: string;
|
||||
id: string;
|
||||
name: string;
|
||||
webUrl: string;
|
||||
driveType: string;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
export interface IRFx {
|
||||
title: string;
|
||||
closingDate:Date;
|
||||
contractSpecialist:{
|
||||
EMail:string
|
||||
};
|
||||
contractSpecialistId:number;
|
||||
id:number; //the id of the listitem that holds the doclib title and securitygroup name
|
||||
// internalSecurityGroupId:number;members
|
||||
libraryMembersGroupId:number;
|
||||
//externalSecurityGroupId:number;;visitors
|
||||
libraryVisitorsGroupId:number;
|
||||
libraryOwnersGroupId:number;
|
||||
description:string;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
export interface IRFxFolder {
|
||||
title: string;
|
||||
id:number; //the id of the listitem that holds the doclib title and securitygroup name
|
||||
folderMembersGroupId:number;
|
||||
folderVisitorsGroupId:number;
|
||||
rfxId:number;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export interface IVendor {
|
||||
title: string;
|
||||
membersGroup:string;
|
||||
id:number; //the id of the listitem that holds the doclib title and securitygroup name
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import { SeverityLevel } from '@microsoft/applicationinsights-web';
|
||||
import { ApplicationInsights } from '@microsoft/applicationinsights-web';
|
||||
import { ReactPlugin } from '@microsoft/applicationinsights-react-js';
|
||||
|
||||
import {
|
||||
ILogEntry,
|
||||
ILogListener,
|
||||
LogLevel
|
||||
} from "@pnp/logging";
|
||||
|
||||
class CustomListener implements ILogListener {
|
||||
private appInsights: ApplicationInsights;
|
||||
private instrumentationKey: string;
|
||||
constructor(instrumentationKey: string) {
|
||||
this.instrumentationKey = instrumentationKey;
|
||||
this.appInsights = this.getApplicationInsights();
|
||||
}
|
||||
|
||||
public log(entry: ILogEntry): void {
|
||||
|
||||
if (entry.level == LogLevel.Error)
|
||||
this.appInsights.trackException({
|
||||
error: new Error(entry.message),
|
||||
severityLevel: SeverityLevel.Error
|
||||
});
|
||||
else if (entry.level == LogLevel.Warning)
|
||||
this.appInsights.trackException({
|
||||
error: new Error(entry.message),
|
||||
severityLevel: SeverityLevel.Warning
|
||||
});
|
||||
else if (entry.level == LogLevel.Info)
|
||||
this.appInsights.trackException({
|
||||
error: new Error(entry.message),
|
||||
severityLevel: SeverityLevel.Information
|
||||
});
|
||||
else
|
||||
this.appInsights.trackException({
|
||||
error: new Error(entry.message),
|
||||
severityLevel: SeverityLevel.Verbose
|
||||
});
|
||||
this.appInsights.trackTrace({ message: entry.message });
|
||||
}
|
||||
|
||||
private getApplicationInsights(): ApplicationInsights {
|
||||
debugger;
|
||||
const reactPlugin = new ReactPlugin();
|
||||
const applicationInsights = new ApplicationInsights({
|
||||
config: {
|
||||
instrumentationKey: this.instrumentationKey,
|
||||
extensions: [reactPlugin]
|
||||
|
||||
}
|
||||
});
|
||||
applicationInsights.loadAppInsights();
|
||||
return applicationInsights;
|
||||
}
|
||||
}
|
||||
|
||||
export default CustomListener;
|
|
@ -0,0 +1,218 @@
|
|||
import { sp, SPHttpClient } from "@pnp/sp";
|
||||
import { ISiteGroup, ISiteGroupInfo } from '@pnp/sp/site-groups';
|
||||
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
|
||||
import { IViewInfo } from '@pnp/sp/views';
|
||||
import { IRoleDefinition, IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
import { escape, findIndex, find } from '@microsoft/sp-lodash-subset';
|
||||
import { IItem } from "@pnp/sp/items";
|
||||
import { IRFxFolder } from '../models/IRFxFolder';
|
||||
|
||||
export default class RFXUtilities {
|
||||
public roleDefs: IRoleDefinitionInfo[];
|
||||
/**
|
||||
* Sets the parent of a group to another group using JSOM calls (this is not supported in rest)
|
||||
* @param groupId -- the ID of the group whose parent will be changed
|
||||
* @param ownerGroupId -- the id of the group that will become the parent
|
||||
*/
|
||||
public static async setGroupOwner(groupId: number, ownerGroupId: number): Promise<void> {
|
||||
const client = new SPHttpClient();
|
||||
await Promise.all([sp.web.select("Url").get(), sp.site.select("Id").get()])
|
||||
.then(async (siteData) => {
|
||||
const siteObj = siteData[0];
|
||||
const siteId = siteData[1];
|
||||
const endpoint = siteObj.Url + `/_vti_bin/client.svc/ProcessQuery`;
|
||||
const body = `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="15.0.0.0" ApplicationName=".NET Library" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009">
|
||||
<Actions>
|
||||
<SetProperty Id="1" ObjectPathId="2" Name="Owner">
|
||||
<Parameter ObjectPathId="3" />
|
||||
</SetProperty>
|
||||
<Method Name="Update" Id="4" ObjectPathId="2" />
|
||||
</Actions>
|
||||
<ObjectPaths>
|
||||
<Identity Id="2" Name="740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:${siteId.Id}:g:${groupId}" />
|
||||
<Identity Id="3" Name="740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:${siteId.Id}:g:${ownerGroupId}" />
|
||||
</ObjectPaths>
|
||||
</Request>`;
|
||||
await client.post(endpoint, {
|
||||
headers: {
|
||||
"content-type": "text/xml"
|
||||
},
|
||||
body: body
|
||||
})
|
||||
.then((response) => {
|
||||
return response.json().then((r) => {
|
||||
if (r[0].ErrorInfo) {
|
||||
return Promise.reject(r[0].ErrorInfo.ErrorMessage);
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets the ID of a roledefinition with the given name
|
||||
*
|
||||
* @public
|
||||
* @param {string} roleDefinitionName The name of the roleDefinition whose ID we want to get
|
||||
* @returns {Promise<number>} The ID if the roleDefinition. If not found this will be -1
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static getRoledefId(roleDefinitionName: string, roleDefinitions: Array<IRoleDefinitionInfo>): number {
|
||||
for (const def of roleDefinitions) {
|
||||
if (def.Name === roleDefinitionName) {
|
||||
return def.Id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants a group access to a library
|
||||
*
|
||||
* @public
|
||||
* @param {string} libraryName The name of the library to grant access to
|
||||
* @param {string} groupName The name of the group to gtrant access for
|
||||
* @param {string} roleName The role to assign the group to on this library
|
||||
* @returns {Promise<any>}
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static async grantGroupAccessToLibrary(libraryName: string, groupId: number, roleName: string, roleDefinitions: Array<IRoleDefinitionInfo>): Promise<any> {
|
||||
|
||||
const roleDefId = await RFXUtilities.getRoledefId(roleName, roleDefinitions);
|
||||
if (roleDefId === -1) {
|
||||
return Promise.reject(`"Role ${roleName} not found`);
|
||||
}
|
||||
return sp.web.lists.getByTitle(libraryName).roleAssignments.add(groupId, roleDefId);
|
||||
}
|
||||
|
||||
public static async removeAccessToLibrary(libraryName: string, principalId: number, roleName: string, roleDefinitions: Array<IRoleDefinitionInfo>): Promise<any> {
|
||||
|
||||
const roleDefId = await RFXUtilities.getRoledefId(roleName, roleDefinitions);
|
||||
if (roleDefId === -1) {
|
||||
return Promise.reject(`"Role ${roleName} not found`);
|
||||
}
|
||||
return sp.web.lists.getByTitle(libraryName).roleAssignments.remove(principalId, roleDefId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determinse if a SiteGroup with the given name exists
|
||||
*
|
||||
* @public
|
||||
* @param {string} groupName The name of the SiteGroup we want to check
|
||||
* @returns {Promise<boolean>} True if SiteGroup exists , otherwise false
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static doesGroupExist(groupName: string): Promise<boolean> {
|
||||
return sp.web.siteGroups.getByName(groupName).get()
|
||||
.then((list) => {
|
||||
return true;
|
||||
})
|
||||
.catch((e) => {
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Grants a group access to the site
|
||||
// *
|
||||
// * @public
|
||||
// * @param {string} groupName The group name to be granted access
|
||||
// * @param {string} roleName The role to assign the group to on this site
|
||||
// * @returns {Promise<any>}
|
||||
// * @memberof DocLibSecurity
|
||||
// */
|
||||
// // public static async grantNewGroupAccessToSite(groupName: string, roleName: string, roleDefinitions: Array<IRoleDefinitionInfo>): Promise<any> {
|
||||
|
||||
// // const roleDefId = await this.getRoledefId(roleName, roleDefinitions);
|
||||
// // const grp = await sp.web.siteGroups.getByName(groupName).get();
|
||||
// // return sp.web.roleAssignments.add(grp.Id, roleDefId);
|
||||
|
||||
// // }
|
||||
|
||||
public static async grantGroupIdAccessToSite(groupId: number, roleName: string, roleDefinitions: Array<IRoleDefinitionInfo>): Promise<any> {
|
||||
const roleDefId = await this.getRoledefId(roleName, roleDefinitions);
|
||||
return sp.web.roleAssignments.add(groupId, roleDefId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the default view of the selected lbrary
|
||||
*
|
||||
* @public
|
||||
* @param {string} title -- the Title of the doclib to open
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static linkToLibrary(title: string): void {
|
||||
|
||||
sp.web.lists.getByTitle(title).defaultView.get()
|
||||
.then((view: IViewInfo) => {
|
||||
window.location.pathname = view.ServerRelativeUrl;
|
||||
});
|
||||
}
|
||||
public static linkToFolder(folder: IRFxFolder, rfxListName: string): void {
|
||||
let ifrx = sp.web.lists.getByTitle(rfxListName).items.getById(folder.rfxId).get()
|
||||
.then((rfx) => {
|
||||
sp.web.lists.getByTitle(rfx["Title"]).rootFolder.folders.getByName(folder.title).get()
|
||||
.then((item) => {
|
||||
debugger;
|
||||
window.location.pathname = item.ServerRelativeUrl;
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Naviates to the Group Maintenance page for the selected Group
|
||||
*
|
||||
* @public
|
||||
* @param {string} groupName The name of the Group
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static linkToGroup(groupName: string, webServerRelativeUrl: string): void {
|
||||
|
||||
sp.web.siteGroups.getByName(groupName).get()
|
||||
.then((grp: ISiteGroupInfo) => {
|
||||
let newUrl = `${window.location.origin}${webServerRelativeUrl}/_layouts/15/people.aspx?MembershipGroupId=${grp.Id}`;
|
||||
window.location.href = newUrl;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Naviates to the Group Maintenance page for the selected Group
|
||||
*
|
||||
* @public
|
||||
* @param {string} groupName The name of the Group
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static linkToGroupById(groupId: number, webServerRelativeUrl: string): void {
|
||||
|
||||
let newUrl = `${window.location.origin}${webServerRelativeUrl}/_layouts/15/people.aspx?MembershipGroupId=${groupId}`;
|
||||
window.location.href = newUrl;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delets a group with the given name
|
||||
*
|
||||
* @public
|
||||
* @param {string} groupName the name of the group to remove
|
||||
* @returns {Promise<void>}
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
public static deletegroup(groupName: string): Promise<void> {
|
||||
|
||||
return sp.web.siteGroups.getByName(groupName).get()
|
||||
.then((grp: ISiteGroupInfo) => {
|
||||
sp.web.siteGroups.removeById(grp.Id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static getSiteGroupName(siteGroupId: number, siteGroups: Array<ISiteGroupInfo>): string {
|
||||
let sg: ISiteGroupInfo = find(siteGroups, (sgx) => {
|
||||
return sgx.Id === siteGroupId;
|
||||
});
|
||||
if (sg) {
|
||||
return sg.Title;
|
||||
}
|
||||
else { return (`*${siteGroupId}*`); }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "bad86476-e6ad-4162-92a5-4663ed8bb68d",
|
||||
"alias": "RequestMaintenanceWebPart",
|
||||
"componentType": "WebPart",
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": [
|
||||
"SharePointWebPart"
|
||||
],
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
"group": {
|
||||
"default": "Other"
|
||||
},
|
||||
"title": {
|
||||
"default": "RequestMaintenance"
|
||||
},
|
||||
"description": {
|
||||
"default": "RequestMaintenance description"
|
||||
},
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"rfxListTitle": "RFXs",
|
||||
"rfxFoldersListTitle": "RFXFolders",
|
||||
"archiveLibraryTitle": "Archive",
|
||||
"enablePrivateFolders": true,
|
||||
"roleDefinitionForLibraryMembersGroupOnSite": "Read",
|
||||
"roleDefinitionForLibraryMembersGroupOnLibrary": "Contribute",
|
||||
"roleDefinitionForLibraryMembersGroupOnFolder": "Contribute",
|
||||
"roleDefinitionForLibraryVisitorsGroupOnSite": "Read",
|
||||
"roleDefinitionForLibraryVisitorsGroupOnLibrary": "Read",
|
||||
"roleDefinitionForLibraryVisitorsGroupOnFolder": "Read",
|
||||
"roleDefinitionForFolderMembersOnSite": "Read",
|
||||
"roleDefinitionForFolderMembersOnLibrary": "Read",
|
||||
"roleDefinitionForFolderMembersOnFolder": "Edit",
|
||||
"roleDefinitionForFolderVisitorsOnSite": "Read",
|
||||
"roleDefinitionForFolderVisitorsOnLibrary": "Read",
|
||||
"roleDefinitionForFolderVisitorsOnFolder": "Read"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
import CustomListener from "../../utilities/CustomListener";
|
||||
import { IRequestMaintenanceProps } from './components/IRequestMaintenanceProps';
|
||||
import RequestMaintenance from './components/RequestMaintenance';
|
||||
import { IPropertyPaneConfiguration, PropertyPaneDropdown, PropertyPaneTextField, PropertyPaneToggle } from '@microsoft/sp-property-pane';
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
import { setup as pnpSetup } from "@pnp/common";
|
||||
import { ConsoleListener, Logger, LogLevel } from "@pnp/logging";
|
||||
import { sp } from "@pnp/sp";
|
||||
import { IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
import { ISiteGroupInfo } from '@pnp/sp/site-groups';
|
||||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import * as strings from 'RequestMaintenanceWebPartStrings';
|
||||
|
||||
import "@pnp/sp/security";
|
||||
import "@pnp/sp/site-groups/web";
|
||||
import "@pnp/sp/site-groups/web";
|
||||
import "@pnp/sp/site-users";
|
||||
import "@pnp/sp/webs";
|
||||
|
||||
//mport { ISiteUser } from '@pnp/sp/site-users';
|
||||
export interface IRequestMaintenanceWebPartProps {
|
||||
rfxListTitle: string; // the name of the list that holds all the RFX Info
|
||||
rfxFoldersListTitle: string;// the name of the list that holds all the RFX folder Info
|
||||
instrumentationKey: string; // app insights key
|
||||
archiveLibraryTitle: string;
|
||||
enablePrivateFolders: boolean;
|
||||
|
||||
|
||||
roleDefinitionForLibraryMembersGroupOnLibrary: string;// each new RFX library has an group created for internal users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryMembersGroupOnSite: string; // each new RFX library has an group created for internal users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryMembersGroupOnFolder: string; // each new RFX library has an group created for internal users. What role should that group have on trghe site (READ)
|
||||
|
||||
roleDefinitionForLibraryVisitorsGroupOnLibrary: string;// each new RFX library has an group created for external users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryVisitorsGroupOnSite: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryVisitorsGroupOnFolder: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
|
||||
roleDefinitionForFolderMembersOnFolder: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderMembersOnLibrary: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderMembersOnSite: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
|
||||
roleDefinitionForFolderVisitorsOnFolder: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderVisitorsOnLibrary: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderVisitorsOnSite: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
|
||||
allowGroupNameChanges: boolean;
|
||||
|
||||
}
|
||||
|
||||
export default class RequestMaintenanceWebPart extends BaseClientSideWebPart<IRequestMaintenanceWebPartProps> {
|
||||
private vistorsGroup: ISiteGroupInfo;
|
||||
private ownersGroup: ISiteGroupInfo;
|
||||
private membersGroup: ISiteGroupInfo;
|
||||
private roleDefinitions: IRoleDefinitionInfo[];
|
||||
private roleDefinitionsDropdownDisabled: boolean;
|
||||
// private currentUser:ISiteUser;
|
||||
public render(): void {
|
||||
|
||||
const element: React.ReactElement<IRequestMaintenanceProps> = React.createElement(
|
||||
RequestMaintenance,
|
||||
{
|
||||
siteOwnersGroup: this.ownersGroup, // Site owners groupw will be given full contyrol on new libraros
|
||||
rfxListTitle: this.properties.rfxListTitle, // the name of the list that holds all the RFX Info
|
||||
rfxFoldersListTitle: this.properties.rfxFoldersListTitle, // the name of the list that holds all the RFX Info
|
||||
webServerRelativeUrl: this.context.pageContext.web.serverRelativeUrl,
|
||||
archiveLibraryTitle: this.properties.archiveLibraryTitle,
|
||||
enablePrivateFolders: this.properties.enablePrivateFolders,
|
||||
roleDefinitions: this.roleDefinitions,
|
||||
|
||||
roleDefinitionForLibraryMembersGroupOnSite: this.properties.roleDefinitionForLibraryMembersGroupOnSite, // each new RFX library has an group created for internal users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryMembersGroupOnLibrary: this.properties.roleDefinitionForLibraryMembersGroupOnLibrary,// each new RFX library has an group created for internal users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryMembersGroupOnFolder: this.properties.roleDefinitionForLibraryMembersGroupOnFolder,// each new RFX library has an group created for internal users. What role should that group have on trghe library (Contribute)
|
||||
|
||||
roleDefinitionForLibraryVisitorsGroupOnSite: this.properties.roleDefinitionForLibraryVisitorsGroupOnSite, // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryVisitorsGroupOnLibrary: this.properties.roleDefinitionForLibraryVisitorsGroupOnLibrary,// each new RFX library has an group created for external users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryVisitorsGroupOnFolder: this.properties.roleDefinitionForLibraryVisitorsGroupOnFolder,// each new RFX library has an group created for external users. What role should that group have on trghe library (Contribute)
|
||||
|
||||
roleDefinitionForFolderVisitorsOnFolder: this.properties.roleDefinitionForFolderVisitorsOnFolder, // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderVisitorsOnLibrary: this.properties.roleDefinitionForFolderVisitorsOnLibrary, // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderVisitorsOnSite: this.properties.roleDefinitionForFolderVisitorsOnSite, // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
|
||||
|
||||
roleDefinitionForFolderMembersOnFolder: this.properties.roleDefinitionForFolderMembersOnFolder, // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForFolderMembersOnLibrary: this.properties.roleDefinitionForFolderMembersOnLibrary,
|
||||
roleDefinitionForFolderMembersOnSite: this.properties.roleDefinitionForFolderMembersOnSite,
|
||||
|
||||
|
||||
allowGroupNameChanges: this.properties.allowGroupNameChanges
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected onDispose(): void {
|
||||
ReactDom.unmountComponentAtNode(this.domElement);
|
||||
}
|
||||
|
||||
public onInit(): Promise<any> {
|
||||
|
||||
|
||||
//sessionStorage.setItem("spfx-debug", ""); //// REMOVE THIS
|
||||
return super.onInit().then(_ => {
|
||||
pnpSetup({
|
||||
spfxContext: this.context
|
||||
});
|
||||
Logger.activeLogLevel = LogLevel.Warning;
|
||||
Logger.subscribe(new ConsoleListener());
|
||||
if (this.properties.instrumentationKey) {
|
||||
Logger.subscribe(new CustomListener(this.properties.instrumentationKey));
|
||||
}
|
||||
let groupsPromise = this.getGroups();
|
||||
let roledefPromise = this.getRoleDefinitions();
|
||||
|
||||
|
||||
return Promise.all([groupsPromise, roledefPromise]);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public getRoleDefinitions(): Promise<void> {
|
||||
return sp.site.rootWeb.roleDefinitions.get().then((rds) => {
|
||||
this.roleDefinitions = rds;
|
||||
});
|
||||
}
|
||||
|
||||
public getGroups(): Promise<any> {
|
||||
let promises: Array<Promise<any>> = [];
|
||||
promises.push(sp.web.associatedVisitorGroup()
|
||||
.then((g) => {
|
||||
this.vistorsGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
// Gets the associated members group of a web
|
||||
promises.push(sp.web.associatedMemberGroup()
|
||||
.then((g) => {
|
||||
this.membersGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
|
||||
// Gets the associated owners group of a web
|
||||
promises.push(sp.web.associatedOwnerGroup()
|
||||
.then((g) => {
|
||||
this.ownersGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
return Promise.all(promises);
|
||||
|
||||
}
|
||||
|
||||
protected onPropertyPaneConfigurationStart(): void {
|
||||
|
||||
if (this.roleDefinitions) { return; }
|
||||
this.getRoleDefinitions().then((e) => {
|
||||
this.roleDefinitionsDropdownDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('rfxListTitle', {
|
||||
label: strings.rfxListTitleLabel
|
||||
}),
|
||||
PropertyPaneTextField('rfxFoldersListTitle', {
|
||||
label: strings.rfxFoldersListTitleLabel
|
||||
}),
|
||||
PropertyPaneTextField('archiveLibraryTitle', {
|
||||
label: strings.archiveLibraryTitle
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryMembersGroupOnSite', {
|
||||
label: strings.roleDefinitionForLibraryMembersGroupOnSite,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryMembersGroupOnLibrary', {
|
||||
label: strings.roleDefinitionForLibraryMembersGroupOnLibrary,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryMembersGroupOnFolder', {
|
||||
label: strings.roleDefinitionForLibraryMembersGroupOnFolder,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryVisitorsGroupOnSite', {
|
||||
label: strings.roleDefinitionForLibraryVisitorsGroupOnSite,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryVisitorsGroupOnLibrary', {
|
||||
label: strings.roleDefinitionForLibraryVisitorsGroupOnLibrary,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForLibraryVisitorsGroupOnFolder', {
|
||||
label: strings.roleDefinitionForLibraryVisitorsGroupOnFolder,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
PropertyPaneDropdown('roleDefinitionForFolderMembersOnSite', {
|
||||
label: strings.roleDefinitionForFolderMembersOnSite,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForFolderMembersOnLibrary', {
|
||||
label: strings.roleDefinitionForFolderMembersOnLibrary,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForFolderMembersOnFolder', {
|
||||
label: strings.roleDefinitionForFolderMembersOnFolder,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
PropertyPaneDropdown('roleDefinitionForFolderVisitorsOnSite', {
|
||||
label: strings.roleDefinitionForFolderVisitorsOnSite,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForFolderVisitorsOnLibrary', {
|
||||
label: strings.roleDefinitionForFolderVisitorsOnLibrary,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
PropertyPaneDropdown('roleDefinitionForFolderVisitorsOnFolder', {
|
||||
label: strings.roleDefinitionForFolderVisitorsOnFolder,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
}),
|
||||
|
||||
PropertyPaneToggle('allowGroupNameChanges', {
|
||||
label: strings.allowGroupNameChanges,
|
||||
}),
|
||||
|
||||
PropertyPaneToggle('enablePrivateFolders', {
|
||||
label:strings.privateFolders,
|
||||
offText:strings.privateFoldersDisabled,
|
||||
onText: strings.privateFoldersEnabled,
|
||||
}),
|
||||
PropertyPaneTextField('instrumentationKey', {
|
||||
label: strings.instrumentationKey
|
||||
}),
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { ISiteGroupInfo } from "@pnp/sp/site-groups";
|
||||
import { IRoleDefinition, IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
|
||||
|
||||
import { ISiteUser } from "@pnp/sp/site-users";
|
||||
|
||||
import { SPHttpClient, SPHttpClientResponse, SPHttpClientConfiguration } from '@microsoft/sp-http';
|
||||
|
||||
export interface IRequestMaintenanceProps {
|
||||
|
||||
siteOwnersGroup:ISiteGroupInfo; // Site owners groupw will be given full contyrol on new libraros
|
||||
rfxListTitle:string; // the name of the list that holds all the RFX Info
|
||||
rfxFoldersListTitle:string; // the name of the list that holds all the RFX Folder Info
|
||||
archiveLibraryTitle:string; // the name of the library that ther archive button moves stuff to.
|
||||
webServerRelativeUrl:string;
|
||||
roleDefinitions:Array<IRoleDefinitionInfo>;// all role definitions on the site
|
||||
roleDefinitionForLibraryMembersGroupOnLibrary:string;// each new RFX library has an group created for internal users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryMembersGroupOnSite: string; // each new RFX library has an group created for internal users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryMembersGroupOnFolder: string; // each new RFX library has an group created for internal users. What role should that group have on trghe site (READ)
|
||||
|
||||
roleDefinitionForLibraryVisitorsGroupOnLibrary:string;// each new RFX library has an group created for external users. What role should that group have on trghe library (Contribute)
|
||||
roleDefinitionForLibraryVisitorsGroupOnSite: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
roleDefinitionForLibraryVisitorsGroupOnFolder: string; // each new RFX library has an group created for external users. What role should that group have on trghe site (READ)
|
||||
|
||||
roleDefinitionForFolderMembersOnFolder:string;
|
||||
roleDefinitionForFolderMembersOnLibrary:string;
|
||||
roleDefinitionForFolderMembersOnSite:string;
|
||||
|
||||
|
||||
roleDefinitionForFolderVisitorsOnFolder:string;
|
||||
roleDefinitionForFolderVisitorsOnLibrary:string;
|
||||
roleDefinitionForFolderVisitorsOnSite:string;
|
||||
|
||||
allowGroupNameChanges:boolean;
|
||||
enablePrivateFolders:boolean;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
import { ISiteGroupInfo } from "@pnp/sp/site-groups";
|
||||
import { IRoleDefinition, IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
import { IRFx } from '../../../models/IRFx';
|
||||
import { IRFxFolder } from '../../../models/IRFxFolder';
|
||||
import { IActivity } from '../../../models/IActivity';
|
||||
import { ISiteUser } from "@pnp/sp/site-users";
|
||||
export interface IRequestMaintenanceState {
|
||||
currentUserId: number;
|
||||
currentUserEMail: string;
|
||||
currentUserLoginName: string;
|
||||
selectedRfx: IRFx;
|
||||
showFolders: boolean;
|
||||
rfxFolders:Array<IRFxFolder>;
|
||||
rfxs: Array<IRFx>;
|
||||
siteGroups: ISiteGroupInfo[];
|
||||
showAddNewLibrary: boolean;
|
||||
isUpdating: boolean;
|
||||
invalidCharacters: boolean;
|
||||
// used when adding an rfx::
|
||||
newRfxId: string;
|
||||
newRfxDescription: string;
|
||||
newRFxClosingDate: Date;
|
||||
newRFxLibraryMembersGroupName: string;
|
||||
newRFxLibraryVisitorsGroupName: string;
|
||||
newRFxLibraryOwnersGroupName: string;
|
||||
|
||||
showAddNewFolder: boolean;
|
||||
|
||||
newFolderName:string;
|
||||
newFolderMembersGroupName:string;
|
||||
newFolderVisitorsGroupName:string;
|
||||
|
||||
showActivity:boolean;
|
||||
activities:Array<IActivity>;
|
||||
|
||||
mainSelectedItemsCount:number;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
.requestMaintenance {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.row {
|
||||
@include ms-Grid-row;
|
||||
@include ms-fontColor-white;
|
||||
background-color: $ms-color-themeDark;
|
||||
padding: 20px;
|
||||
}
|
||||
.column {
|
||||
@include ms-Grid-col;
|
||||
@include ms-lg10;
|
||||
@include ms-xl8;
|
||||
@include ms-xlPush2;
|
||||
@include ms-lgPush1;
|
||||
}
|
||||
.title {
|
||||
@include ms-font-xl;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
.subTitle {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
.commandBar button {
|
||||
border-width: 0px;
|
||||
}
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 3200px;
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: $ms-color-themePrimary;
|
||||
border-color: $ms-color-themePrimary;
|
||||
color: $ms-color-white;
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: $ms-font-size-m;
|
||||
font-weight: $ms-font-weight-regular;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
.label {
|
||||
font-weight: $ms-font-weight-semibold;
|
||||
font-size: $ms-font-size-m;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
32
samples/react-private-libraries/src/webparts/requestMaintenance/loc/en-us.js
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"instrumentationKey": "App Insights instrumentation key",
|
||||
"privateFoldersEnabled": "Private folders enabled",
|
||||
"privateFoldersDisabled": "Private folders enabled",
|
||||
"privateFolders": "Private Folders",
|
||||
"rfxListTitleLabel": "RFX List",
|
||||
"rfxFoldersListTitleLabel": "RFX Folders List",
|
||||
"roleDefinitionForLibraryMembersGroupOnLibrary": "Permission for library members on Libraries",
|
||||
"roleDefinitionForLibraryMembersGroupOnSite": "Permission for library members on Site",
|
||||
"roleDefinitionForLibraryMembersGroupOnFolder": "Permission for library members on Folders",
|
||||
|
||||
"roleDefinitionForLibraryVisitorsGroupOnLibrary": "Permission for library visitors on Libraries",
|
||||
"roleDefinitionForLibraryVisitorsGroupOnSite": "Permission for library visitors on Site",
|
||||
"roleDefinitionForLibraryVisitorsGroupOnFolder": "Permission for library visitors on Folders",
|
||||
|
||||
"roleDefinitionForFolderMembersOnFolder": "Permission for Folder members on Folders",
|
||||
"roleDefinitionForFolderMembersOnLibrary": "Permission for Folder members on Library",
|
||||
"roleDefinitionForFolderMembersOnSite": "Permission for Folder members on Site",
|
||||
|
||||
"roleDefinitionForFolderVisitorsOnFolder": "Permission for Folder visitors on Folders",
|
||||
"roleDefinitionForFolderVisitorsOnLibrary": "Permission for Folder visitors on Library",
|
||||
"roleDefinitionForFolderVisitorsOnSite": "Permission for Folder visitors on Site",
|
||||
|
||||
"allowGroupNameChanges": "Allow users to change generated security group names",
|
||||
|
||||
"archiveLibraryTitle": "Archive Library"
|
||||
|
||||
}
|
||||
});
|
37
samples/react-private-libraries/src/webparts/requestMaintenance/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
declare interface IRequestMaintenanceWebPartStrings {
|
||||
instrumentationKey:string;
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
rfxListTitleLabel:string;
|
||||
rfxFoldersListTitleLabel:string;
|
||||
archiveLibraryTitle:string;
|
||||
privateFoldersEnabled:string;
|
||||
privateFoldersDisabled:string;
|
||||
privateFolders:string;
|
||||
|
||||
// Library member permissions
|
||||
roleDefinitionForLibraryMembersGroupOnLibrary:string;
|
||||
roleDefinitionForLibraryMembersGroupOnSite:string;
|
||||
roleDefinitionForLibraryMembersGroupOnFolder:string;
|
||||
|
||||
|
||||
// library visitor permissions
|
||||
roleDefinitionForLibraryVisitorsGroupOnLibrary:string;
|
||||
roleDefinitionForLibraryVisitorsGroupOnSite:string;
|
||||
roleDefinitionForLibraryVisitorsGroupOnFolder:string;
|
||||
|
||||
// folder member permissions
|
||||
roleDefinitionForFolderMembersOnFolder:string;
|
||||
roleDefinitionForFolderMembersOnLibrary:string;
|
||||
roleDefinitionForFolderMembersOnSite:string;
|
||||
|
||||
roleDefinitionForFolderVisitorsOnFolder:string;
|
||||
roleDefinitionForFolderVisitorsOnLibrary:string;
|
||||
roleDefinitionForFolderVisitorsOnSite:string;
|
||||
allowGroupNameChanges:string;
|
||||
}
|
||||
|
||||
declare module 'RequestMaintenanceWebPartStrings' {
|
||||
const strings: IRequestMaintenanceWebPartStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "dca49132-f256-4f99-8509-864d663d4d3b",
|
||||
"alias": "VendorMaintenanceWebPart",
|
||||
"componentType": "WebPart",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": ["SharePointWebPart"],
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "VendorMaintenance" },
|
||||
"description": { "default": "VendorMaintenance description" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "VendorMaintenance"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
IPropertyPaneConfiguration,
|
||||
|
||||
PropertyPaneTextField, PropertyPaneDropdown, IPropertyPaneDropdownOption
|
||||
} from '@microsoft/sp-property-pane';
|
||||
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
|
||||
import * as strings from 'VendorMaintenanceWebPartStrings';
|
||||
import VendorMaintenance from './components/VendorMaintenance';
|
||||
import { IVendorMaintenanceProps } from './components/IVendorMaintenanceProps';
|
||||
import { ISiteGroupInfo } from '@pnp/sp/site-groups';
|
||||
export interface IVendorMaintenanceWebPartProps {
|
||||
ownersGroup: string;
|
||||
roleDefinitionForSite: string;
|
||||
}
|
||||
import { setup as pnpSetup } from "@pnp/common";
|
||||
import { sp } from "@pnp/sp";
|
||||
import "@pnp/sp/site-groups/web";
|
||||
import "@pnp/sp/webs";
|
||||
import "@pnp/sp/site-groups/web";
|
||||
|
||||
import "@pnp/sp/security";
|
||||
import { IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
|
||||
import { SPHttpClient, SPHttpClientResponse, SPHttpClientConfiguration } from '@microsoft/sp-http';
|
||||
|
||||
export default class VendorMaintenanceWebPart extends BaseClientSideWebPart<IVendorMaintenanceWebPartProps> {
|
||||
private vistorsGroup: ISiteGroupInfo;
|
||||
private ownersGroup: ISiteGroupInfo;
|
||||
private membersGroup: ISiteGroupInfo;
|
||||
private roleDefinitions: IRoleDefinitionInfo[];
|
||||
private roleDefinitionsDropdownDisabled: boolean = true;
|
||||
public onInit(): Promise<any> {
|
||||
|
||||
debugger;
|
||||
//sessionStorage.setItem("spfx-debug", ""); //// REMOVE THIS
|
||||
return super.onInit().then(_ => {
|
||||
pnpSetup({
|
||||
spfxContext: this.context
|
||||
});
|
||||
let groupsPromise = this.getGroups();
|
||||
let roledefPromise = this.getRoleDefinitions();
|
||||
|
||||
|
||||
return Promise.all([groupsPromise, roledefPromise]);
|
||||
|
||||
});
|
||||
}
|
||||
public getGroups(): Promise<any> {
|
||||
let promises: Array<Promise<any>> = [];
|
||||
promises.push(sp.web.associatedVisitorGroup()
|
||||
.then((g) => {
|
||||
this.vistorsGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
// Gets the associated members group of a web
|
||||
promises.push(sp.web.associatedMemberGroup()
|
||||
.then((g) => {
|
||||
this.membersGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
|
||||
// Gets the associated owners group of a web
|
||||
promises.push(sp.web.associatedOwnerGroup()
|
||||
.then((g) => {
|
||||
this.ownersGroup = g;
|
||||
})
|
||||
.catch((e) => {
|
||||
debugger;
|
||||
}));
|
||||
|
||||
return Promise.all(promises);
|
||||
|
||||
}
|
||||
public getRoleDefinitions(): Promise<void> {
|
||||
|
||||
return sp.site.rootWeb.roleDefinitions.get().then((rds) => {
|
||||
this.roleDefinitions = rds;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IVendorMaintenanceProps> = React.createElement(
|
||||
VendorMaintenance,
|
||||
{
|
||||
roleDefinitionForSite: this.properties.roleDefinitionForSite,
|
||||
ownersGroup: this.ownersGroup,
|
||||
webServerRelativeUrl: this.context.pageContext.web.serverRelativeUrl,
|
||||
vendorListTitle: "Vendors",
|
||||
roleDefinitions: this.roleDefinitions
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected onDispose(): void {
|
||||
ReactDom.unmountComponentAtNode(this.domElement);
|
||||
}
|
||||
|
||||
protected onPropertyPaneConfigurationStart(): void {
|
||||
debugger;
|
||||
if (this.roleDefinitions) { return; }
|
||||
this.getRoleDefinitions().then((e) => {
|
||||
this.roleDefinitionsDropdownDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
|
||||
PropertyPaneDropdown('roleDefinitionForSite', {
|
||||
label: strings.roleDefinitionForSiteLabel,
|
||||
options: this.roleDefinitions.map((rd) => {
|
||||
debugger;
|
||||
return { key: rd.Name, text: rd.Name };
|
||||
}),
|
||||
|
||||
}),
|
||||
PropertyPaneTextField('ownersGroup', {
|
||||
label: strings.ownersGroupLabel
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { ISiteGroupInfo } from "@pnp/sp/site-groups";
|
||||
import { IRoleDefinition, IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
export interface IVendorMaintenanceProps {
|
||||
ownersGroup:ISiteGroupInfo;
|
||||
vendorListTitle:string;
|
||||
webServerRelativeUrl:string;
|
||||
roleDefinitionForSite: string; //role to give new groups in the site
|
||||
roleDefinitions:Array<IRoleDefinitionInfo>;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { ISiteGroupInfo } from "@pnp/sp/site-groups";
|
||||
import { IVendor } from '../../../models/IVendor';
|
||||
export interface IVendorMaintenanceState {
|
||||
vendors: Array<IVendor>;
|
||||
newVendorTitle:string;
|
||||
newVendorGroupName:string;
|
||||
showAddNew:boolean;
|
||||
isUpdating:boolean; //disable save button while update in progress
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.vendorMaintenance {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.row {
|
||||
@include ms-Grid-row;
|
||||
@include ms-fontColor-white;
|
||||
background-color: $ms-color-themeDark;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.column {
|
||||
@include ms-Grid-col;
|
||||
@include ms-lg10;
|
||||
@include ms-xl8;
|
||||
@include ms-xlPush2;
|
||||
@include ms-lgPush1;
|
||||
}
|
||||
|
||||
.title {
|
||||
@include ms-font-xl;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: $ms-color-themePrimary;
|
||||
border-color: $ms-color-themePrimary;
|
||||
color: $ms-color-white;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: $ms-font-size-m;
|
||||
font-weight: $ms-font-weight-regular;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: $ms-font-weight-semibold;
|
||||
font-size: $ms-font-size-m;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
import * as React from 'react';
|
||||
import { sp, SPHttpClient } from "@pnp/sp";
|
||||
|
||||
import "@pnp/sp/webs";
|
||||
import "@pnp/sp/sites";
|
||||
|
||||
import "@pnp/sp/site-groups";
|
||||
import "@pnp/sp/lists/web";
|
||||
import "@pnp/sp/lists/web";
|
||||
import "@pnp/sp/items";
|
||||
import "@pnp/sp/security/list";
|
||||
import "@pnp/sp/security/web";
|
||||
import "@pnp/sp/folders";
|
||||
import "@pnp/sp/views";
|
||||
|
||||
|
||||
import { DetailsList } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
import { Label } from 'office-ui-fabric-react/lib/Label';
|
||||
import { PrimaryButton, Button } from 'office-ui-fabric-react/lib/Button';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Panel } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { Link } from 'office-ui-fabric-react/lib/Link';
|
||||
import { ISiteGroupInfo } from '@pnp/sp/site-groups';
|
||||
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
|
||||
import { IViewInfo } from '@pnp/sp/views';
|
||||
import { IRoleDefinitionInfo } from '@pnp/sp/security';
|
||||
import styles from './VendorMaintenance.module.scss';
|
||||
import { IVendorMaintenanceProps } from './IVendorMaintenanceProps';
|
||||
import { IVendorMaintenanceState } from './IVendorMaintenanceState';
|
||||
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import { IVendor } from '../../../models/IVendor';
|
||||
import RFXUtilities from '../../../utilities/RFXUtilities';
|
||||
export default class VendorMaintenance extends React.Component<IVendorMaintenanceProps, IVendorMaintenanceState> {
|
||||
|
||||
|
||||
public state = {
|
||||
vendors: [],
|
||||
showAddNew: false,
|
||||
newVendorTitle: null,
|
||||
newVendorGroupName: null,
|
||||
isUpdating: false,
|
||||
invalidCharacters: false
|
||||
};
|
||||
public componentDidMount() {
|
||||
this.fetchVendors();
|
||||
}
|
||||
/**
|
||||
* Fetches the list of vendors (store in a sharepoint list) and updates them in the docLibs State varieble
|
||||
*
|
||||
* @private
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
private fetchVendors() {
|
||||
sp.web.lists.getByTitle(this.props.vendorListTitle).items.orderBy("Title").get().then((items) => {
|
||||
this.setState((current) => ({
|
||||
...current,
|
||||
vendors: items.map((item) => {
|
||||
return { title: item.Title, membersGroup: item["SecurityGroup"], id: item.Id };
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Validates the data to add a new vendor and adds it if valid
|
||||
*
|
||||
* @private
|
||||
* @returns
|
||||
* @memberof DocLibSecurity
|
||||
*/
|
||||
private async validateAndAddVendor() {
|
||||
debugger;
|
||||
this.setState((current) => ({ ...current, isUpdating: true }));
|
||||
//Do validation
|
||||
|
||||
let groupExists = await RFXUtilities.doesGroupExist(this.state.newVendorGroupName);
|
||||
if (groupExists) {
|
||||
alert("A group with this name already exists");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new group
|
||||
await sp.web.siteGroups.add({ "Title": this.state.newVendorGroupName })
|
||||
.catch((e) => {
|
||||
|
||||
alert("there was an error adding the group");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
});
|
||||
const newGroup = await sp.web.siteGroups.getByName(this.state.newVendorGroupName).get();
|
||||
// set the groups owner
|
||||
await RFXUtilities.setGroupOwner(newGroup.Id, this.props.ownersGroup.Id)
|
||||
.catch((e) => {
|
||||
|
||||
alert("there was an setting the owner on the new group");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
});
|
||||
// await RFXUtilities.grantNewGroupAccessToSite(this.state.newVendorGroupName, this.props.roleDefinitionForSite,this.props.roleDefinitions).catch((e) => {
|
||||
|
||||
// alert("there was an error granting access to the site to the new group");
|
||||
// this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
// return;
|
||||
// });
|
||||
debugger;
|
||||
// add an entry to the Secured Libraries list to track this entry
|
||||
await sp.web.lists.getByTitle(this.props.vendorListTitle).items.add({
|
||||
Title: this.state.newVendorTitle,
|
||||
SecurityGroup: this.state.newVendorGroupName
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
alert("there was an updating the List of Libraries");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
});
|
||||
|
||||
|
||||
this.fetchVendors();
|
||||
this.setState((current) => ({ ...current, showAddNew: false, isUpdating: false, newVendorGroupName: "", newVendorTitle: "" }));
|
||||
|
||||
}
|
||||
|
||||
private async deleteVendor(item: IVendor) {
|
||||
this.setState((current) => ({ ...current, isUpdating: true }));
|
||||
//Do validation
|
||||
|
||||
let groupExists = await RFXUtilities.doesGroupExist(item.membersGroup);
|
||||
if (!groupExists) {
|
||||
alert("A group with this name does not exist ");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
}
|
||||
await RFXUtilities.deletegroup(item.membersGroup)
|
||||
.catch((e) => {
|
||||
|
||||
alert("there was an error deleting the group");
|
||||
this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
return;
|
||||
});
|
||||
|
||||
// await RFXUtilities.deleterow(item.id,this.props.vendorListTitle)
|
||||
// .catch((e) => {
|
||||
|
||||
// alert("there was an removing the row from the vendors list");
|
||||
// this.setState((current) => ({ ...current, isUpdating: false }));
|
||||
// return;
|
||||
// });
|
||||
|
||||
|
||||
this.fetchVendors();
|
||||
this.setState((current) => ({ ...current, showAddNew: false, isUpdating: false, newVendorGroupName: "", newVendorTitle: "" }));
|
||||
|
||||
}
|
||||
public render(): React.ReactElement<IVendorMaintenanceProps> {
|
||||
|
||||
return (
|
||||
<div className={styles.vendorMaintenance}>
|
||||
<Panel isOpen={this.state.showAddNew} >
|
||||
<TextField label="Vendor Name" placeholder="enter vendor name" value={this.state.newVendorTitle} onChange={(e, value) => {
|
||||
this.setState((current) => ({
|
||||
...current,
|
||||
newVendorTitle: value.replace(/[&\/\\#,+()$~% "`:;*?<>{}|^!@$']/g, ''),
|
||||
newVendorGroupName: value.replace(/[&\/\\#,+()$~% "`:;*?<>{}|^!@$']/g, '') + " Members"
|
||||
}));
|
||||
}}></TextField>
|
||||
<TextField label="Group Name" placeholder="enter group name" value={this.state.newVendorGroupName}
|
||||
default={this.state.newVendorGroupName} onChange={(e, value) => {
|
||||
this.setState((current) => ({ ...current, newVendorGroupName: value.replace(/[&\/\\#,+()$~% "`:;*?<>{}|^!@$']/g, '') }));
|
||||
}}></TextField>
|
||||
<PrimaryButton disabled={this.state.isUpdating || this.state.invalidCharacters} onClick={(e) => {
|
||||
this.validateAndAddVendor();
|
||||
}}>Add Vendor</PrimaryButton>
|
||||
</Panel>
|
||||
<DetailsList
|
||||
|
||||
items={this.state.vendors}
|
||||
columns={[
|
||||
{
|
||||
key: 'column1', name: 'Vendor Name', fieldName: 'title', minWidth: 100, maxWidth: 200, isResizable: true,
|
||||
onRender: (item: IVendor) => (
|
||||
<Label>{item.title}</Label>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: 'column3', name: 'Security Group', fieldName: 'membersGroup', minWidth: 100, maxWidth: 200, isResizable: true,
|
||||
onRender: (item: IVendor) => (
|
||||
<Link onClick={() => {
|
||||
RFXUtilities.linkToGroup(item.membersGroup, this.props.webServerRelativeUrl);
|
||||
}}>{item.membersGroup}</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: 'edit', name: 'Edit', fieldName: 'edit', minWidth: 100, maxWidth: 200, isResizable: false,
|
||||
onRender: (item: IVendor) => (
|
||||
<Link onClick={() => {
|
||||
this.deleteVendor(item);
|
||||
}}>Delete</Link>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
]}
|
||||
|
||||
>
|
||||
|
||||
</DetailsList>
|
||||
<Button onClick={(e) => this.setState((current) => ({ ...current, showAddNew: true, newVendorGroupName: "", newVendorTitle: "" }))}>Add new Vendor</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
|
||||
"roleDefinitionForSiteLabel": "Role def users get on site",
|
||||
"ownersGroupLabel": "group that owns the groups"
|
||||
}
|
||||
});
|
12
samples/react-private-libraries/src/webparts/vendorMaintenance/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
declare interface IVendorMaintenanceWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
roleDefinitionForSiteLabel: string;
|
||||
ownersGroupLabel: string;
|
||||
|
||||
}
|
||||
|
||||
declare module 'VendorMaintenanceWebPartStrings' {
|
||||
const strings: IVendorMaintenanceWebPartStrings;
|
||||
export = strings;
|
||||
}
|
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "lib",
|
||||
"inlineSources": false,
|
||||
"strictNullChecks": false,
|
||||
"noUnusedLocals": false,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./node_modules/@microsoft"
|
||||
],
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"lib"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
}
|