react site designs manager (#829)
* commit first * Update README.md * Update README.md
|
@ -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,29 @@
|
|||
{
|
||||
"@pnp/generator-spfx": {
|
||||
"framework": "react",
|
||||
"pnpFramework": "reactjs.plus",
|
||||
"pnp-libraries": [
|
||||
"jquery@3",
|
||||
"@pnp/pnpjs",
|
||||
"@pnp/spfx-property-controls",
|
||||
"@pnp/spfx-controls-react"
|
||||
],
|
||||
"pnp-ci": [
|
||||
"azure"
|
||||
],
|
||||
"pnp-vetting": [],
|
||||
"spfxenv": "spo"
|
||||
},
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"environment": "spo",
|
||||
"framework": "react",
|
||||
"plusBeta": true,
|
||||
"isCreatingSolution": true,
|
||||
"version": "1.8.0",
|
||||
"libraryName": "react-manage-sitedesigns",
|
||||
"libraryId": "50025bb6-5fda-4a16-b45e-5f27b19aac72",
|
||||
"packageManager": "npm",
|
||||
"isDomainIsolated": false,
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
# React Site Designs Manager
|
||||
|
||||
## Summary
|
||||
This web part allows tenant administrators to manage site designs through a graphical interface.
|
||||
We can create, edit, delete work whith site scripts associated to a site design, manage permissions and apply site design to one or more sites.
|
||||
|
||||
Only users with Tenant Admin Role are allowed to managed tenant properties.
|
||||
|
||||
## Site Designs List
|
||||
|
||||
![site design list](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen1.jpg)
|
||||
|
||||
## Add, Edit and Delete site designs
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen2.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen3.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen3.1.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen4.jpg)
|
||||
|
||||
|
||||
## Site Designs Rights
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen5.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](/assets/screen6.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen7.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen8.jpg)
|
||||
|
||||
|
||||
|
||||
## Site Design Site Scripts
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen9.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen10.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen11.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen12.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen13.jpg)
|
||||
|
||||
|
||||
|
||||
## Apply Site Design
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen14.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen15.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen16.jpg)
|
||||
|
||||
|
||||
|
||||
![tenant properties](https://github.com/joaojmendes/sp-dev-fx-webparts/blob/dev/samples/react-manage-sitedesigns/assets/screen17.jpg)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/version-GA-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
* [SharePoint Framework](https:/dev.office.com/sharepoint)
|
||||
* [Office 365 tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment)
|
||||
|
||||
> Update accordingly as needed.
|
||||
|
||||
## WebPart Properties
|
||||
|
||||
Property |Type|Required| comments
|
||||
--------------------|----|--------|----------
|
||||
WebPart Title| Text| no|
|
||||
|
||||
|
||||
## Solution
|
||||
The Web Part Use PnPjs library, Office-ui-fabric-react components.
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
Site Design Manager WebPart|João Mendes
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0.0|April 08, 2019|Initial release
|
||||
|
||||
## 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.**
|
||||
|
||||
---
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository
|
||||
- in the command line run:
|
||||
- `npm install`
|
||||
- `gulp build`
|
||||
- `gulp bundle --ship`
|
||||
- `gulp package-solution --ship`
|
||||
- `Add to AppCatalog and deploy`
|
||||
|
||||
|
||||
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/readme-template" />
|
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 97 KiB |
|
@ -0,0 +1,71 @@
|
|||
resources:
|
||||
- repo: self
|
||||
trigger:
|
||||
- master
|
||||
- develop
|
||||
queue:
|
||||
name: Hosted VS2017
|
||||
demands:
|
||||
- npm
|
||||
- node.js
|
||||
|
||||
steps:
|
||||
#install node 8.x
|
||||
- task: NodeTool@0
|
||||
displayName: 'Use Node 8.x'
|
||||
inputs:
|
||||
versionSpec: 8.x
|
||||
checkLatest: true
|
||||
|
||||
#install nodejs modules with npm
|
||||
- task: Npm@1
|
||||
displayName: 'npm install'
|
||||
inputs:
|
||||
workingDir: '$(Build.SourcesDirectory)'
|
||||
verbose: false
|
||||
|
||||
#start unit tests
|
||||
- task: Gulp@0
|
||||
displayName: 'gulp test'
|
||||
inputs:
|
||||
gulpFile: '$(Build.SourcesDirectory)/gulpfile.js'
|
||||
targets: test
|
||||
publishJUnitResults: true
|
||||
testResultsFiles: '**/test-*.xml'
|
||||
#publish test results
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: 'Publish Code Coverage Results $(Build.SourcesDirectory)/temp/coverage/cobertura/cobertura.xml'
|
||||
inputs:
|
||||
codeCoverageTool: Cobertura
|
||||
summaryFileLocation: '$(Build.SourcesDirectory)/temp/coverage/cobertura/cobertura.xml'
|
||||
reportDirectory: '$(Build.SourcesDirectory)/temp/coverage/cobertura'
|
||||
|
||||
#bundle code with gulp
|
||||
- task: Gulp@0
|
||||
displayName: 'gulp bundle'
|
||||
inputs:
|
||||
gulpFile: '$(Build.SourcesDirectory)/gulpfile.js'
|
||||
targets: bundle
|
||||
arguments: '--ship'
|
||||
continueOnError: true
|
||||
|
||||
#package solution with gulp
|
||||
- task: Gulp@0
|
||||
displayName: 'gulp package-solution'
|
||||
inputs:
|
||||
gulpFile: '$(Build.SourcesDirectory)/gulpfile.js'
|
||||
targets: 'package-solution'
|
||||
arguments: '--ship'
|
||||
|
||||
#copy files to artifact repository
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: $(build.artifactstagingdirectory)/drop'
|
||||
inputs:
|
||||
Contents: '**\*.sppkg'
|
||||
TargetFolder: '$(build.artifactstagingdirectory)/drop'
|
||||
|
||||
#publish artifacts
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: drop'
|
||||
inputs:
|
||||
PathtoPublish: '$(build.artifactstagingdirectory)/drop'
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
|
||||
"bundles": {
|
||||
"site-designs-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/siteDesigns/SiteDesignsWebPart.js",
|
||||
"manifest": "./src/webparts/siteDesigns/SiteDesignsWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"SiteDesignsWebPartStrings": "lib/webparts/siteDesigns/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"
|
||||
}
|
||||
}
|
|
@ -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": "react-manage-sitedesigns",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"preset": "@voitanos/jest-preset-spfx-react16",
|
||||
"rootDir": "../src"
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
var existingKarmaConfig = require('@microsoft/sp-build-web/lib/karma/karma.config');
|
||||
var junitReporter = require('karma-junit-reporter');
|
||||
|
||||
module.exports = function (config) {
|
||||
existingKarmaConfig(config);
|
||||
config.reporters.push('junit');
|
||||
|
||||
config.set({
|
||||
basePath: './..',
|
||||
});
|
||||
|
||||
config.junitReporter = {
|
||||
outputDir: 'temp/', // results will be saved as $outputDir/$browserName.xml
|
||||
outputFile: 'test-results.xml', // if included, results will be saved as $outputDir/$browserName/$outputFile
|
||||
suite: 'karma', // suite will become the package name attribute in xml testsuite element
|
||||
useBrowserName: true, // add browser name to report and classes names
|
||||
};
|
||||
var coberturaSubDir = 'cobertura';
|
||||
var coverageSubDir = 'lcov';
|
||||
var coberturaFileName = 'cobertura.xml';
|
||||
config.coverageReporter.reporters.push({type: 'cobertura', subdir: './' + coberturaSubDir, file: coberturaFileName});
|
||||
config.coverageReporter.reporters.push({
|
||||
type: 'lcov',
|
||||
subdir: './' + coverageSubDir + '/',
|
||||
file: 'lcov.info'
|
||||
});
|
||||
config.browserNoActivityTimeout = 60000;
|
||||
config.plugins.push(junitReporter);
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "react-manage-sitedesigns-client-side-solution",
|
||||
"id": "50025bb6-5fda-4a16-b45e-5f27b19aac72",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-manage-sitedesigns.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
// check if gulp dist was called
|
||||
if (process.argv.indexOf('dist') !== -1) {
|
||||
// add ship options to command call
|
||||
process.argv.push('--ship');
|
||||
}
|
||||
|
||||
const path = require('path');
|
||||
const gulp = require('gulp');
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
const gulpSequence = require('gulp-sequence');
|
||||
|
||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||
|
||||
// Create clean distrubution package
|
||||
gulp.task('dist', gulpSequence('clean', 'bundle', 'package-solution'));
|
||||
// Create clean development package
|
||||
gulp.task('dev', gulpSequence('clean', 'bundle', 'package-solution'));
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom Framework Specific gulp tasks
|
||||
*/
|
||||
|
||||
|
||||
build.initialize(gulp);
|
||||
|
||||
/**
|
||||
* Continuous Integration
|
||||
*/
|
||||
|
||||
const buildConfig = build.getConfig();
|
||||
|
||||
const karmaTaskCandidates = buildConfig.uniqueTasks.filter(task => task.name === 'karma');
|
||||
|
||||
if (karmaTaskCandidates && karmaTaskCandidates.length > 0) {
|
||||
const karmaTask = karmaTaskCandidates[0];
|
||||
karmaTask.taskConfig.configPath = './config/karma.config.js';
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": "react-manage-sitedesigns",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"preversion": "node ./tools/pre-version.js",
|
||||
"postversion": "gulp dist",
|
||||
"test": "./node_modules/.bin/jest --config ./config/jest.config.json",
|
||||
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-lodash-subset": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-property-pane": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-webpart-base": "1.8.0-plusbeta",
|
||||
"@pnp/pnpjs": "^1.3.0",
|
||||
"@pnp/spfx-controls-react": "1.12.0",
|
||||
"@pnp/spfx-property-controls": "1.14.1",
|
||||
"@types/es6-promise": "0.0.33",
|
||||
"@types/jquery": "^3.3.29",
|
||||
"@types/react": "16.7.22",
|
||||
"@types/react-dom": "16.0.5",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"jquery": "^3.3.1",
|
||||
"jsoneditor": "^5.31.1",
|
||||
"jsoneditor-react": "^1.0.0",
|
||||
"react": "16.7.0",
|
||||
"react-dom": "16.7.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "16.7.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/rush-stack-compiler-2.7": "0.4.0",
|
||||
"@microsoft/rush-stack-compiler-3.2": "0.2.11",
|
||||
"@microsoft/sp-build-web": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-module-interfaces": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-tslint-rules": "1.8.0-plusbeta",
|
||||
"@microsoft/sp-webpart-workbench": "1.8.0-plusbeta",
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/mocha": "2.2.38",
|
||||
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
||||
"ajv": "^5.5.2",
|
||||
"gulp": "~3.9.1",
|
||||
"gulp-sequence": "1.0.0",
|
||||
"jest": "^23.6.0",
|
||||
"karma-junit-reporter": "^1.2.0",
|
||||
"tslint": "5.14.0",
|
||||
"typescript": "^3.2.4"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
// João Mendes
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IAddPrincipalProps } from './IAddPrincipalProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IAddPrincipalState } from './IAddPrincipalState';
|
||||
import { SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignInfo, SiteDesignPrincipals } from '@pnp/sp';
|
||||
import {
|
||||
Panel,
|
||||
PanelType,
|
||||
TextField,
|
||||
Toggle,
|
||||
IPersonaProps,
|
||||
DialogFooter,
|
||||
PrimaryButton, DefaultButton,
|
||||
Spinner, SpinnerSize,
|
||||
MessageBar, MessageBarType
|
||||
} from 'office-ui-fabric-react';
|
||||
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
|
||||
|
||||
export default class AddPrincipal extends React.Component<IAddPrincipalProps, IAddPrincipalState> {
|
||||
private spService: spservice;
|
||||
private selectedUsers: IPersonaProps[] = [];
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.getPeoplePickerItems = this.getPeoplePickerItems.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: true,
|
||||
showPanel: false,
|
||||
siteDesignInfo: this.props.siteDesignInfo,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
saving: false,
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberofEditSiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
|
||||
const principals: string[] = [];
|
||||
|
||||
for (const user of this.selectedUsers){
|
||||
principals.push(user.secondaryText);
|
||||
}
|
||||
// read SiteScript
|
||||
try {
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.grantSiteDesignRights(this.props.siteDesignInfo.Id, principals);
|
||||
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private getPeoplePickerItems(items: any[]) {
|
||||
this.selectedUsers = items;
|
||||
this.setState({ showError:false, errorMessage:'', disableSaveButton: this.selectedUsers.length > 0 ? false : true });
|
||||
|
||||
}
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteDesignProps>}
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IAddPrincipalProps> {
|
||||
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.custom}
|
||||
customWidth={"480px"}
|
||||
headerText="Add Principals">
|
||||
<TextField
|
||||
label={strings.SiteDesignIdLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Id : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Title : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Description : ''}
|
||||
multiline
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<Toggle
|
||||
defaultChecked={this.props.siteDesignInfo.IsDefault}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
disabled
|
||||
/>
|
||||
<br />
|
||||
|
||||
<PeoplePicker
|
||||
context={this.props.context}
|
||||
titleText="Add Users"
|
||||
personSelectionLimit={3}
|
||||
groupName={""} // Leave this blank in case you want to filter from all users
|
||||
showtooltip={true}
|
||||
isRequired={true}
|
||||
selectedItems={this.getPeoplePickerItems}
|
||||
showHiddenInUI={false}
|
||||
principalTypes={[PrincipalType.User]}
|
||||
resolveDelay={1000} />
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.AddPrincipalPanelButtonSaveText} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.AddPrincipalPanelButtonCancelText} />
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteDesignPrincipals } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
export interface IAddPrincipalProps {
|
||||
|
||||
context: WebPartContext;
|
||||
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
siteDesignInfo: IListViewItems;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
|
||||
import { SiteDesignInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
export interface IAddPrincipalState {
|
||||
isLoading: boolean;
|
||||
siteDesignInfo?: IListViewItems;
|
||||
showPanel: boolean;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
saving: boolean;
|
||||
|
||||
}
|
|
@ -0,0 +1,392 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IAddSiteDesignProps } from './IAddSiteDesignProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IAddSiteDesignState } from './IAddSiteDesignState';
|
||||
import { SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignCreationInfo } from '@pnp/sp';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { IImageProps, Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
import { Dropdown, IDropdown, DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
|
||||
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
import { getGUID } from '@pnp/common';
|
||||
|
||||
export default class AddSiteDesign extends React.Component<IAddSiteDesignProps, IAddSiteDesignState> {
|
||||
private spService: spservice;
|
||||
private siteScripts: SiteScriptInfo[];
|
||||
|
||||
private AddScriptDialog = React.lazy(() => import('../../controls/AddSiteScript/AddSiteScript' /* webpackChunkName: "addscriptdialog" */));
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: false,
|
||||
showPanel: false,
|
||||
siteDesignCreationInfo: { Description: '', Title: '', IsDefault: false, PreviewImageAltText: '', PreviewImageUrl: '', SiteScriptIds: [], WebTemplate: '64' },
|
||||
panelMode: panelMode.New,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
sitescriptslist: [],
|
||||
selectedItems: [],
|
||||
showPanelAddScript: false,
|
||||
saving: false,
|
||||
selectedItemWebTemplate: 64
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onIsDefault = this.onIsDefault.bind(this);
|
||||
this.onGetErrorMessageDescription = this.onGetErrorMessageDescription.bind(this);
|
||||
this.onGetErrorMessageTitle = this.onGetErrorMessageTitle.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onGetErrorMessageImageUrl = this.onGetErrorMessageImageUrl.bind(this);
|
||||
this.onChangeMultiSelect = this.onChangeMultiSelect.bind(this);
|
||||
this.onAddScript = this.onAddScript.bind(this);
|
||||
this.onDismissAddScriptPanel = this.onDismissAddScriptPanel.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.onSelectedItemWebTemplate = this.onSelectedItemWebTemplate.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
|
||||
const _siteDesignCreationInfo: SiteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
// read SiteScripts
|
||||
for (const item of this.state.selectedItems) {
|
||||
_siteDesignCreationInfo.SiteScriptIds.push(item);
|
||||
}
|
||||
try {
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.createSiteDesign(_siteDesignCreationInfo);
|
||||
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add SiteScrit Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onAddScript(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.setState({ showPanelAddScript: true });
|
||||
}
|
||||
|
||||
private onDismissAddScriptPanel(refresh: boolean) {
|
||||
|
||||
this.setState({ showPanelAddScript: false });
|
||||
if (refresh) {
|
||||
this.loadSiteScripts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SiteScript
|
||||
* @private
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private async loadSiteScripts() {
|
||||
this.siteScripts = await this.spService.getSiteScripts();
|
||||
let siteScriptsList: { key: string, text: string }[] = [];
|
||||
if (this.siteScripts) {
|
||||
for (const sitescript of this.siteScripts) {
|
||||
siteScriptsList.push({
|
||||
key: sitescript.Id,
|
||||
text: sitescript.Title
|
||||
});
|
||||
}
|
||||
this.setState({ sitescriptslist: siteScriptsList.sort() });
|
||||
}
|
||||
}
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
await this.loadSiteScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public async onChangeMultiSelect(event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) {
|
||||
const updatedSelectedItem = this.state.selectedItems ? this.copyArray(this.state.selectedItems) : [];
|
||||
const hasTitlevalue = this.state.siteDesignCreationInfo.Title;
|
||||
if (item.selected) {
|
||||
// add the option if it's checked
|
||||
updatedSelectedItem.push(item.key);
|
||||
this.setState({ errorMessage: '', selectedItems: updatedSelectedItem, disableSaveButton: hasTitlevalue ? false : true });
|
||||
} else {
|
||||
// remove the option if it's unchecked
|
||||
const currIndex = updatedSelectedItem.indexOf(item.key);
|
||||
if (currIndex > -1) {
|
||||
updatedSelectedItem.splice(currIndex, 1);
|
||||
}
|
||||
this.setState({ errorMessage: '', selectedItems: updatedSelectedItem, disableSaveButton: updatedSelectedItem.length > 0 ? false : true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.FormEvent<HTMLDivElement>} event
|
||||
* @param {IDropdownOption} item
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onSelectedItemWebTemplate(event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) {
|
||||
const _siteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
_siteDesignCreationInfo.WebTemplate = item.key.toString();
|
||||
this.setState({ selectedItemWebTemplate: item.key, siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public copyArray(array: any[]): any[] {
|
||||
const newArray: any[] = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
newArray[i] = array[i];
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
||||
// Validate Value
|
||||
/**
|
||||
* Validate Title
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageTitle(value: string) {
|
||||
let returnvalue: string = '';
|
||||
const _siteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
const numberSiteScriptSelected = this.state.selectedItems.length;
|
||||
if (value.trim().length > 0) {
|
||||
_siteDesignCreationInfo.Title = value;
|
||||
this.setState({ disableSaveButton: numberSiteScriptSelected > 0 ? false : true, siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
} else {
|
||||
_siteDesignCreationInfo.Title = value;
|
||||
this.setState({ errorMessage: '', disableSaveButton: true, siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
returnvalue = strings.AddSiteDesignPanelTitleErrorMessage;
|
||||
}
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Description
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageDescription(value: string) {
|
||||
|
||||
let returnvalue: string = '';
|
||||
const _siteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
_siteDesignCreationInfo.Description = value;
|
||||
this.setState({ siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns {string} returnvale
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageImageUrl(value: string) {
|
||||
let returnvalue: string = '';
|
||||
const _siteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
if (value.length > 0) {
|
||||
try {
|
||||
const _URL = new URL(value);
|
||||
_siteDesignCreationInfo.PreviewImageUrl = value;
|
||||
} catch (error) {
|
||||
_siteDesignCreationInfo.PreviewImageUrl = value;
|
||||
returnvalue = error.message;
|
||||
}
|
||||
} else {
|
||||
_siteDesignCreationInfo.PreviewImageUrl = value;
|
||||
}
|
||||
|
||||
this.setState({ siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} ev
|
||||
* @param {boolean} checked
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onIsDefault(ev: React.MouseEvent<HTMLElement>, checked: boolean) {
|
||||
const _siteDesignCreationInfo = this.state.siteDesignCreationInfo;
|
||||
_siteDesignCreationInfo.IsDefault = checked;
|
||||
this.setState({ siteDesignCreationInfo: _siteDesignCreationInfo });
|
||||
}
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteDesignProps>}
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IAddSiteDesignProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.medium}
|
||||
headerText="Add Site Design">
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
required={true}
|
||||
value={this.state.siteDesignCreationInfo ? this.state.siteDesignCreationInfo.Title : ''}
|
||||
deferredValidationTime={1500}
|
||||
onGetErrorMessage={this.onGetErrorMessageTitle} />
|
||||
<Dropdown
|
||||
placeholder="SelectWebTemplate"
|
||||
label="WebTemplate"
|
||||
selectedKey={this.state.selectedItemWebTemplate}
|
||||
onChange={this.onSelectedItemWebTemplate}
|
||||
|
||||
options={[
|
||||
{ key: 64, text: 'Team Site' },
|
||||
{ key: 68, text: 'Comunication Site' }
|
||||
]}
|
||||
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignCreationInfo ? this.state.siteDesignCreationInfo.Description : ''}
|
||||
deferredValidationTime={1500}
|
||||
onGetErrorMessage={this.onGetErrorMessageDescription} />
|
||||
<TextField
|
||||
label={strings.AddSiteDesignImageUrlLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignCreationInfo ? this.state.siteDesignCreationInfo.PreviewImageUrl : ''}
|
||||
deferredValidationTime={1500}
|
||||
onGetErrorMessage={this.onGetErrorMessageImageUrl} />
|
||||
<br />
|
||||
{
|
||||
this.state.siteDesignCreationInfo.PreviewImageUrl &&
|
||||
<Image src={this.state.siteDesignCreationInfo ? this.state.siteDesignCreationInfo.PreviewImageUrl : ''}
|
||||
imageFit={ImageFit.cover}
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
}
|
||||
<Toggle
|
||||
defaultChecked={false}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
onChange={this.onIsDefault}
|
||||
/>
|
||||
|
||||
<div style={{ paddingTop: '10px', textAlign: 'right' }}>
|
||||
<ActionButton
|
||||
data-automation-id="test"
|
||||
iconProps={{ iconName: 'Add' }}
|
||||
allowDisabledFocus={true}
|
||||
title={"Add Site Script"}
|
||||
onClick={this.onAddScript}
|
||||
>
|
||||
{strings.AddSiteDesignPanelActionButtonText}
|
||||
</ActionButton>
|
||||
</div>
|
||||
<div>
|
||||
<p> {strings.AddSiteDesignPanelScriptOrderInfo} </p>
|
||||
<Dropdown
|
||||
placeholder={strings.AddSiteDesignPanelDropDownPlaceholderText}
|
||||
label={strings.AddSiteDesignPanelDropDownLabel}
|
||||
selectedKeys={this.state.selectedItems}
|
||||
onChange={this.onChangeMultiSelect}
|
||||
multiSelect
|
||||
options={this.state.sitescriptslist}
|
||||
|
||||
/>
|
||||
</div>
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.AddScriptDialog
|
||||
hideDialog={!this.state.showPanelAddScript}
|
||||
onDismiss={this.onDismissAddScriptPanel}
|
||||
context={this.props.context} />
|
||||
</React.Suspense>
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.AddSiteDesignPanelButtonSaveText} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.AddSiteDesignPanelButtonCancelText} />
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface IAddSiteDesignProps {
|
||||
|
||||
context: WebPartContext;
|
||||
mode: panelMode;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
}
|
||||
|
||||
interface ISiteDesignSelectedItem {
|
||||
key: string;
|
||||
Description: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
WebTemplate:string;
|
||||
SiteScriptIds: string;
|
||||
numberSiteScripts: number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText: string;
|
||||
PreviewImageUrl: string;
|
||||
Version: string;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { SiteDesignCreationInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
export interface IAddSiteDesignState {
|
||||
isLoading: boolean;
|
||||
siteDesignCreationInfo?: SiteDesignCreationInfo;
|
||||
showPanel: boolean;
|
||||
panelMode: panelMode;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
sitescriptslist: { key: string | number | undefined, text: string }[];
|
||||
selectedItems: string[];
|
||||
showPanelAddScript: boolean;
|
||||
saving: boolean;
|
||||
selectedItemWebTemplate: string | number;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IAddSiteScriptProps } from './IAddSiteScriptProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IAddSiteScriptState } from './IAddSiteScriptState';
|
||||
import { SiteDesignInfo, SiteScriptInfo, SiteScriptUpdateInfo } from '@pnp/sp';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
|
||||
export default class AddSiteScript extends React.Component<IAddSiteScriptProps, IAddSiteScriptState> {
|
||||
private spService: spservice;
|
||||
private siteScriptshowError: boolean = false;
|
||||
private siteTitleshowError: boolean = false;
|
||||
|
||||
private JsonEditorWrapper = React.lazy(() => import('../json-editor-wrapper' /* webpackChunkName: "jsoneditorwrapper" */));
|
||||
private currentSiteScript: ISiteScript = {
|
||||
|
||||
"$schema": "schema.json",
|
||||
"actions": [],
|
||||
"bindata": {},
|
||||
"version": 1
|
||||
};
|
||||
|
||||
/**
|
||||
*Creates an instance of AddSiteScript.
|
||||
* @param {*} props
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
saving: false,
|
||||
hideDialog: true,
|
||||
readOnly: false,
|
||||
title: '',
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
currentSiteScript: this.currentSiteScript,
|
||||
description: ''
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onGetErrorMessageDescription = this.onGetErrorMessageDescription.bind(this);
|
||||
this.onGetErrorMessageTitle = this.onGetErrorMessageTitle.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.setSiteScript = this.setSiteScript.bind(this);
|
||||
this.onValidateSiteScript = this.onValidateSiteScript.bind(this);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
try {
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.createSiteScript(this.state.title, this.state.description, this.state.currentSiteScript);
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {*} value
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
private setSiteScript(value: ISiteScript) {
|
||||
|
||||
this.setState({ currentSiteScript: value });
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} error (true/false)
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
private onValidateSiteScript(valid: boolean) {
|
||||
|
||||
if (valid) {
|
||||
this.siteScriptshowError = false;
|
||||
if (this.siteTitleshowError) {
|
||||
this.setState({ errorMessage: '', disableSaveButton: true, showError: false });
|
||||
} else {
|
||||
this.setState({ errorMessage: '', disableSaveButton: false, showError: false });
|
||||
}
|
||||
|
||||
} else {
|
||||
this.siteScriptshowError = true;
|
||||
this.setState({ showError: true, errorMessage: strings.JSONSchemaErrorMessage, disableSaveButton: true });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Validate Value
|
||||
/**
|
||||
*
|
||||
* Validate Title
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
private onGetErrorMessageTitle(value: string) {
|
||||
let returnvalue: string = '';
|
||||
let siteScriptTitle = this.state.title;
|
||||
const { showError } = this.state;
|
||||
if (value.trim().length > 0) {
|
||||
siteScriptTitle = value;
|
||||
this.siteTitleshowError = false;
|
||||
if (this.siteScriptshowError) {
|
||||
this.setState({ disableSaveButton: true, title: siteScriptTitle });
|
||||
} else {
|
||||
this.setState({ disableSaveButton: false, title: siteScriptTitle });
|
||||
}
|
||||
} else {
|
||||
siteScriptTitle = value;
|
||||
this.siteTitleshowError = true;
|
||||
this.setState({ disableSaveButton: true, title: siteScriptTitle });
|
||||
// returnvalue = 'Site Script title is required';
|
||||
}
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
private onGetErrorMessageDescription(value: string) {
|
||||
let returnvalue: string = '';
|
||||
this.setState({ description: value });
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteScriptProps>}
|
||||
* @memberof AddSiteScript
|
||||
*/
|
||||
public render(): React.ReactElement<IAddSiteScriptProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns} >
|
||||
|
||||
<Dialog
|
||||
hidden={this.props.hideDialog}
|
||||
onDismiss={this.onCancel}
|
||||
minWidth={"600px"}
|
||||
dialogContentProps={{
|
||||
type: DialogType.normal,
|
||||
title: strings.AddSiteScriptDialogTitle,
|
||||
subText: strings.AddSiteScriptDialogSubText
|
||||
}}
|
||||
modalProps={{
|
||||
isBlocking: true,
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.state.showError &&
|
||||
<MessageBar messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
}
|
||||
<TextField
|
||||
label={strings.AddSiteScriptTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
required={true}
|
||||
value={this.state.title ? this.state.title : ''}
|
||||
deferredValidationTime={300}
|
||||
onGetErrorMessage={this.onGetErrorMessageTitle} />
|
||||
<TextField
|
||||
label={strings.AddSiteScriptDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.title ? this.state.description : ''}
|
||||
deferredValidationTime={300}
|
||||
onGetErrorMessage={this.onGetErrorMessageDescription} />
|
||||
<br />
|
||||
{
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.JsonEditorWrapper
|
||||
currentSiteScript={this.state.currentSiteScript}
|
||||
setSiteScript={this.setSiteScript}
|
||||
onValidate={this.onValidateSiteScript}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.AddSiteScriptPanelButtonSave} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.AddSiteScriptPanelButtonCancelText} />
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface IAddSiteScriptProps {
|
||||
|
||||
context: WebPartContext;
|
||||
hideDialog: boolean;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { SiteDesignInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
export interface IAddSiteScriptState{
|
||||
title:string;
|
||||
description:string;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
currentSiteScript: ISiteScript;
|
||||
hideDialog:boolean;
|
||||
saving:boolean;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IAddSiteScriptToSiteDesignProps } from './IAddSiteScriptToSiteDesignProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IAddSiteScriptToSiteDesignState } from './IAddSiteScriptToSiteDesignState';
|
||||
import { SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignCreationInfo, SiteDesignUpdateInfo } from '@pnp/sp';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { IImageProps, Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
import { Dropdown, IDropdown, DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
|
||||
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
import { getGUID } from '@pnp/common';
|
||||
import { FieldTextRenderer } from "@pnp/spfx-controls-react/lib/FieldTextRenderer";
|
||||
|
||||
export default class AddSiteScriptToSiteDesign extends React.Component<IAddSiteScriptToSiteDesignProps, IAddSiteScriptToSiteDesignState> {
|
||||
private spService: spservice;
|
||||
private siteScripts: SiteScriptInfo[];
|
||||
private currentSiteScriptsIds: string[] = [];
|
||||
|
||||
private AddScriptDialog = React.lazy(() => import('../AddSiteScript/AddSiteScript' /* webpackChunkName: "addscriptdialog" */));
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: true,
|
||||
showPanel: false,
|
||||
panelMode: panelMode.New,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
siteScriptsList: [],
|
||||
selectedItems: [],
|
||||
showPanelAddScript: false,
|
||||
saving: false,
|
||||
|
||||
});
|
||||
|
||||
this.currentSiteScriptsIds = this.props.siteDesignInfo.SiteScriptIds.split(',');
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onChangeMultiSelect = this.onChangeMultiSelect.bind(this);
|
||||
this.onAddScript = this.onAddScript.bind(this);
|
||||
this.onDismissAddScriptPanel = this.onDismissAddScriptPanel.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
try {
|
||||
for (const item of this.state.selectedItems) {
|
||||
this.currentSiteScriptsIds.push(item);
|
||||
}
|
||||
const siteDesignUpdateInfo: SiteDesignUpdateInfo = {
|
||||
Id: this.props.siteDesignInfo.Id,
|
||||
SiteScriptIds: this.currentSiteScriptsIds
|
||||
};
|
||||
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.updateSiteDesign(siteDesignUpdateInfo);
|
||||
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add SiteScrit Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private onAddScript(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.setState({ showPanelAddScript: true });
|
||||
}
|
||||
|
||||
private onDismissAddScriptPanel(refresh: boolean) {
|
||||
|
||||
this.setState({ showPanelAddScript: false });
|
||||
if (refresh) {
|
||||
this.loadSiteScripts();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if SiteScript already exists in Site Design
|
||||
*
|
||||
* @private
|
||||
* @param {string} siteScriptId
|
||||
* @returns
|
||||
* @memberof AddSiteScriptToSiteDesign
|
||||
*/
|
||||
private async checkSiteScriptExists(siteScriptId: string) {
|
||||
let found: boolean = false;
|
||||
|
||||
for (const currentSitescriptId of this.currentSiteScriptsIds) {
|
||||
if (currentSitescriptId === siteScriptId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
/**
|
||||
* Load SiteScript
|
||||
* @private
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
private async loadSiteScripts() {
|
||||
|
||||
this.siteScripts = await this.spService.getSiteScripts();
|
||||
let siteScriptsList: IDropdownOption[] = [];
|
||||
if (this.siteScripts) {
|
||||
for (const siteScript of this.siteScripts) {
|
||||
const exists = await this.checkSiteScriptExists(siteScript.Id);
|
||||
if (!exists) {
|
||||
siteScriptsList.push({
|
||||
key: siteScript.Id,
|
||||
text: siteScript.Title
|
||||
});
|
||||
}
|
||||
}
|
||||
this.setState({ siteScriptsList: siteScriptsList.sort() });
|
||||
}
|
||||
}
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
await this.loadSiteScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public async onChangeMultiSelect(event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) {
|
||||
const updatedSelectedItem = this.state.selectedItems ? this.copyArray(this.state.selectedItems) : [];
|
||||
|
||||
if (item.selected) {
|
||||
// add the option if it's checked
|
||||
updatedSelectedItem.push(item.key);
|
||||
this.setState({ errorMessage: '', selectedItems: updatedSelectedItem, disableSaveButton: false });
|
||||
} else {
|
||||
// remove the option if it's unchecked
|
||||
const currIndex = updatedSelectedItem.indexOf(item.key);
|
||||
if (currIndex > -1) {
|
||||
updatedSelectedItem.splice(currIndex, 1);
|
||||
}
|
||||
this.setState({ errorMessage: '', selectedItems: updatedSelectedItem, disableSaveButton: updatedSelectedItem.length > 0 ? false : true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public copyArray(array: any[]): any[] {
|
||||
const newArray: any[] = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
newArray[i] = array[i];
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteDesignProps>}
|
||||
* @memberof AddSiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IAddSiteScriptToSiteDesignProps> {
|
||||
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.medium}
|
||||
headerText={strings.AddSiteScriptToSiteDesignPanelTitle}>
|
||||
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.Title}
|
||||
style={{backgroundColor: "#f8f8f8"}}
|
||||
/>
|
||||
<TextField
|
||||
label={"WebTemplate"}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.WebTemplate}
|
||||
style={{backgroundColor: "#f8f8f8"}}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.Description}
|
||||
style={{backgroundColor: "#f8f8f8"}}
|
||||
/>
|
||||
<br />
|
||||
{
|
||||
this.props.siteDesignInfo.PreviewImageUrl &&
|
||||
<Image src={this.props.siteDesignInfo ? this.props.siteDesignInfo.PreviewImageUrl : ''}
|
||||
imageFit={ImageFit.cover}
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
}
|
||||
<Toggle
|
||||
defaultChecked={this.props.siteDesignInfo.IsDefault}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
disabled
|
||||
/>
|
||||
<div style={{ paddingTop: '10px', textAlign: 'right' }}>
|
||||
<ActionButton
|
||||
data-automation-id="test"
|
||||
iconProps={{ iconName: 'Add' }}
|
||||
allowDisabledFocus={true}
|
||||
title={strings.actionButtonTitle}
|
||||
onClick={this.onAddScript}
|
||||
>
|
||||
Add SiteScript
|
||||
</ActionButton>
|
||||
</div>
|
||||
<div>
|
||||
<Dropdown
|
||||
placeholder={strings.DropDownSelectSiteScriptPlaceHolder}
|
||||
label={strings.DropDownSelectSiteScriptLabel}
|
||||
selectedKeys={this.state.selectedItems}
|
||||
onChange={this.onChangeMultiSelect}
|
||||
multiSelect
|
||||
options={this.state.siteScriptsList}
|
||||
|
||||
/>
|
||||
</div>
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.AddScriptDialog
|
||||
hideDialog={!this.state.showPanelAddScript}
|
||||
onDismiss={this.onDismissAddScriptPanel}
|
||||
context={this.props.context} />
|
||||
</React.Suspense>
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.AddSiteScriptToSiteDesignPanelButtonSaveText} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.AddSiteScriptToSiteDesignPanelButtonCancelText} />
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface IAddSiteScriptToSiteDesignProps {
|
||||
context: WebPartContext;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
siteDesignInfo: ISiteDesignSelectedItem;
|
||||
}
|
||||
|
||||
|
||||
interface ISiteDesignSelectedItem {
|
||||
key: string;
|
||||
Description: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
WebTemplate:string;
|
||||
SiteScriptIds: string;
|
||||
numberSiteScripts: number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText: string;
|
||||
PreviewImageUrl: string;
|
||||
Version: string;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { SiteDesignCreationInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
export interface IAddSiteScriptToSiteDesignState {
|
||||
isLoading: boolean;
|
||||
showPanel: boolean;
|
||||
panelMode: panelMode;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
siteScriptsList: { key: string | number | undefined, text: string }[];
|
||||
selectedItems: string[];
|
||||
showPanelAddScript: boolean;
|
||||
saving: boolean;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IApplySiteDesignProps } from './IApplySiteDesignProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IApplySiteDesignState } from './IApplySiteDesignState';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { IImageProps, Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
import { IViewSite } from '../SelectSite/IViewSite';
|
||||
import { IAddSiteDesignTaskToCurrentWebResult } from '../../services/IAddSiteDesignTaskToCurrentWebResult';
|
||||
|
||||
export default class ApplySiteDesign extends React.Component<IApplySiteDesignProps, IApplySiteDesignState> {
|
||||
|
||||
private spService: spservice;
|
||||
private siteDesignsApplyedInfo: {addSiteDesignTaskResult:IAddSiteDesignTaskToCurrentWebResult, siteUrl:string}[] = [];
|
||||
private selectedWebSites: IViewSite[] = [];
|
||||
private SelectSite = React.lazy(() => import('../SelectSite/SelectSite' /* webpackChunkName: "selectsite" */));
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: true,
|
||||
showPanel: false,
|
||||
panelMode: panelMode.New,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
selectedItems: [],
|
||||
saving: false,
|
||||
});
|
||||
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.ontSelectSite = this.ontSelectSite.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.setState({ saving: true, disableSaveButton: true, showError: false, errorMessage: '' });
|
||||
try {
|
||||
if (this.selectedWebSites.length > 0) {
|
||||
|
||||
let addSiteDesignTaskResult: IAddSiteDesignTaskToCurrentWebResult = null;
|
||||
for (const item of this.selectedWebSites) {
|
||||
addSiteDesignTaskResult = await this.spService.AddSiteDesignTask(item.url,this.props.siteDesignInfo.Id);
|
||||
this.siteDesignsApplyedInfo.push({addSiteDesignTaskResult: addSiteDesignTaskResult, siteUrl:item.url});
|
||||
}
|
||||
}
|
||||
this.props.onDismiss(this.siteDesignsApplyedInfo,true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {IViewSite[]} items
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
private ontSelectSite(items: IViewSite[]) {
|
||||
|
||||
if (items.length > 0) {
|
||||
this.selectedWebSites = items;
|
||||
this.setState({
|
||||
disableSaveButton: false
|
||||
});
|
||||
} else {
|
||||
this.selectedWebSites = [];
|
||||
this.setState({
|
||||
disableSaveButton: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SiteScript
|
||||
* @private
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
private async loadSiteScripts() {
|
||||
}
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
}
|
||||
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IApplySiteDesignProps>}
|
||||
* @memberof ApplySiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IApplySiteDesignProps> {
|
||||
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.medium}
|
||||
headerText={strings.ApplyPanelTitle}>
|
||||
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.Title}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<TextField
|
||||
label={"WebTemplate"}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.WebTemplate}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.props.siteDesignInfo.Description}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<br />
|
||||
{
|
||||
this.props.siteDesignInfo.PreviewImageUrl &&
|
||||
<Image src={this.props.siteDesignInfo ? this.props.siteDesignInfo.PreviewImageUrl : ''}
|
||||
imageFit={ImageFit.cover}
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
}
|
||||
<Toggle
|
||||
defaultChecked={this.props.siteDesignInfo.IsDefault}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
disabled
|
||||
/>
|
||||
<div>
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.SelectSite
|
||||
context={this.props.context}
|
||||
onSelectItem={this.ontSelectSite}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.ApplyPanelApplyButtonLabel} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.ApplyPanelButtonCancelLabel}/>
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IAddSiteDesignTaskToCurrentWebResult } from './../../services/IAddSiteDesignTaskToCurrentWebResult';
|
||||
|
||||
export interface IApplySiteDesignProps {
|
||||
context: WebPartContext;
|
||||
onDismiss(siteDesignsApplyedInfo?: { addSiteDesignTaskResult: IAddSiteDesignTaskToCurrentWebResult, siteUrl: string }[],refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
siteDesignInfo: ISiteDesignSelectedItem;
|
||||
}
|
||||
|
||||
|
||||
interface ISiteDesignSelectedItem {
|
||||
key: string;
|
||||
Description: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
WebTemplate:string;
|
||||
SiteScriptIds: string;
|
||||
numberSiteScripts: number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText: string;
|
||||
PreviewImageUrl: string;
|
||||
Version: string;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { SiteDesignCreationInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
import { IViewSite } from '../SelectSite/IViewSite';
|
||||
export interface IApplySiteDesignState {
|
||||
isLoading: boolean;
|
||||
showPanel: boolean;
|
||||
panelMode: panelMode;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
|
||||
selectedItems: IViewSite[];
|
||||
|
||||
saving: boolean;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
// João Mendes
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IDeleteSiteDesignProps } from './IDeleteSiteDesignProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IDeleteSiteDesignState } from './IDeleteSiteDesignState';
|
||||
import { SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignInfo, SiteDesignUpdateInfo } from '@pnp/sp';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { IImageProps, Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
|
||||
import { Dropdown, IDropdown, DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
|
||||
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
|
||||
export default class DeleteSiteDesign extends React.Component<IDeleteSiteDesignProps, IDeleteSiteDesignState> {
|
||||
private spService: spservice;
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onDelete = this.onDelete.bind(this);
|
||||
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: true,
|
||||
showPanel: false,
|
||||
siteDesignInfo: this.props.siteDesignInfo,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableDeleteButton: false,
|
||||
saving: false,
|
||||
selectedItemWebTemplate: parseInt(this.props.siteDesignInfo.WebTemplate)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberofEditSiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private async onDelete(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
|
||||
const siteDesignUpdateInfo: SiteDesignUpdateInfo= {
|
||||
Id: this.state.siteDesignInfo.Id,
|
||||
Description: this.state.siteDesignInfo.Description,
|
||||
IsDefault: this.state.siteDesignInfo.IsDefault,
|
||||
PreviewImageUrl: this.state.siteDesignInfo.PreviewImageUrl,
|
||||
Title: this.state.siteDesignInfo.Title,
|
||||
WebTemplate: this.state.siteDesignInfo.WebTemplate,
|
||||
};
|
||||
// read SiteScript
|
||||
try {
|
||||
this.setState({ saving: true, disableDeleteButton: true });
|
||||
await this.spService.deleteSiteDesign(siteDesignUpdateInfo);
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableDeleteButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
//
|
||||
}
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteDesignProps>}
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IDeleteSiteDesignProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.medium}
|
||||
headerText={strings.DeleteSiteDesignPanelTitle}>
|
||||
<TextField
|
||||
label={strings.SiteDesignIdLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Id : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
required={true}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Title : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<Dropdown
|
||||
placeholder="SelectWebTemplate"
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
label="WebTemplate"
|
||||
selectedKey={this.state.selectedItemWebTemplate}
|
||||
options={[
|
||||
{ key: 64, text: 'Team Site' },
|
||||
{ key: 68, text: 'Comunication Site' }
|
||||
]}
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Description : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
multiline
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignImageUrlLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.PreviewImageUrl : ''}
|
||||
style={{ backgroundColor: "#f8f8f8" }}
|
||||
/>
|
||||
<br />
|
||||
{
|
||||
this.state.siteDesignInfo.PreviewImageUrl &&
|
||||
<Image src={this.state.siteDesignInfo ? this.state.siteDesignInfo.PreviewImageUrl : ''}
|
||||
imageFit={ImageFit.cover}
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
}
|
||||
<Toggle
|
||||
defaultChecked={this.state.siteDesignInfo.IsDefault}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
disabled={true}
|
||||
/>
|
||||
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onDelete} text={strings.DeleteSiteDesignPanelButtonDeleteText} disabled={this.state.disableDeleteButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.DeleteSiteDesignPanelButtonCanceltext} />
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
export interface IDeleteSiteDesignProps {
|
||||
|
||||
context: WebPartContext;
|
||||
mode: panelMode;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
siteDesignInfo: IListViewItems;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
|
||||
import { SiteDesignInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
export interface IDeleteSiteDesignState {
|
||||
isLoading: boolean;
|
||||
siteDesignInfo?: IListViewItems;
|
||||
showPanel: boolean;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableDeleteButton: boolean;
|
||||
saving: boolean;
|
||||
selectedItemWebTemplate: string | number;
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
// João Mendes
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IEditSiteDesignProps } from './IEditSiteDesignProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IEditSiteDesignState } from './IEditSiteDesignState';
|
||||
import { SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignInfo, SiteDesignUpdateInfo } from '@pnp/sp';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { Toggle } from 'office-ui-fabric-react/lib/Toggle';
|
||||
import { IImageProps, Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
|
||||
import { Dropdown, IDropdown, DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
|
||||
import { ActionButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
|
||||
export default class EditSiteDesign extends React.Component<IEditSiteDesignProps, IEditSiteDesignState> {
|
||||
private spService: spservice;
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onIsDefault = this.onIsDefault.bind(this);
|
||||
this.onGetErrorMessageDescription = this.onGetErrorMessageDescription.bind(this);
|
||||
this.onGetErrorMessageTitle = this.onGetErrorMessageTitle.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onGetErrorMessageImageUrl = this.onGetErrorMessageImageUrl.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.onSelectedItemWebTemplate = this.onSelectedItemWebTemplate.bind(this);
|
||||
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
readOnly: false,
|
||||
showPanel: false,
|
||||
siteDesignInfo: this.props.siteDesignInfo,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
saving: false,
|
||||
selectedItemWebTemplate: parseInt(this.props.siteDesignInfo.WebTemplate)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberofEditSiteDesign
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save SiteDesign Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
|
||||
const siteDesignUpdateInfo: SiteDesignUpdateInfo= {
|
||||
Id: this.state.siteDesignInfo.Id,
|
||||
Description: this.state.siteDesignInfo.Description,
|
||||
IsDefault: this.state.siteDesignInfo.IsDefault,
|
||||
PreviewImageUrl: this.state.siteDesignInfo.PreviewImageUrl,
|
||||
Title: this.state.siteDesignInfo.Title,
|
||||
WebTemplate: this.state.siteDesignInfo.WebTemplate,
|
||||
|
||||
};
|
||||
// read SiteScript
|
||||
try {
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.updateSiteDesign(siteDesignUpdateInfo);
|
||||
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Select WebTemplate
|
||||
*
|
||||
* @private
|
||||
* @param {React.FormEvent<HTMLDivElement>} event
|
||||
* @param {IDropdownOption} item
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private onSelectedItemWebTemplate(event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) {
|
||||
const siteDesignInfo = this.state.siteDesignInfo;
|
||||
siteDesignInfo.WebTemplate = item.key.toString();
|
||||
this.setState({ selectedItemWebTemplate: item.key, siteDesignInfo: siteDesignInfo });
|
||||
}
|
||||
|
||||
// Validate Value
|
||||
/**
|
||||
* Validate Title
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageTitle(value: string) {
|
||||
let returnvalue: string = '';
|
||||
const siteDesignInfo = this.state.siteDesignInfo;
|
||||
|
||||
if (value.trim().length > 0) {
|
||||
siteDesignInfo.Title = value;
|
||||
this.setState({ disableSaveButton: false, siteDesignInfo: siteDesignInfo });
|
||||
} else {
|
||||
siteDesignInfo.Title = value;
|
||||
this.setState({ errorMessage: '', disableSaveButton: true, siteDesignInfo: siteDesignInfo });
|
||||
returnvalue = "SiteDesign tile is required";
|
||||
}
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Description
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageDescription(value: string) {
|
||||
|
||||
let returnvalue: string = '';
|
||||
const siteDesignInfo = this.state.siteDesignInfo;
|
||||
siteDesignInfo.Description = value;
|
||||
this.setState({ siteDesignInfo: siteDesignInfo });
|
||||
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns {string} returnvale
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private onGetErrorMessageImageUrl(value: string) {
|
||||
|
||||
let returnvalue: string = '';
|
||||
const siteDesignInfo = this.state.siteDesignInfo;
|
||||
if (value.length > 0) {
|
||||
try {
|
||||
const _URL = new URL(value);
|
||||
siteDesignInfo.PreviewImageUrl = value;
|
||||
} catch (error) {
|
||||
siteDesignInfo.PreviewImageUrl = value;
|
||||
returnvalue = error.message;
|
||||
}
|
||||
} else {
|
||||
siteDesignInfo.PreviewImageUrl = value;
|
||||
}
|
||||
|
||||
this.setState({ siteDesignInfo: siteDesignInfo });
|
||||
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} ev
|
||||
* @param {boolean} checked
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
private onIsDefault(ev: React.MouseEvent<HTMLElement>, checked: boolean) {
|
||||
const siteDesignInfo = this.state.siteDesignInfo;
|
||||
siteDesignInfo.IsDefault = checked;
|
||||
this.setState({ siteDesignInfo: siteDesignInfo });
|
||||
}
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<IAddSiteDesignProps>}
|
||||
* @memberof EditSiteDesign
|
||||
*/
|
||||
public render(): React.ReactElement<IEditSiteDesignProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<Panel isOpen={this.props.showPanel}
|
||||
onDismiss={this.onCancel}
|
||||
type={PanelType.medium}
|
||||
headerText="Edit Site Design">
|
||||
<TextField
|
||||
label={strings.AddSiteDesignTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
required={true}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Title : ''}
|
||||
deferredValidationTime={200}
|
||||
onGetErrorMessage={this.onGetErrorMessageTitle} />
|
||||
<Dropdown
|
||||
placeholder={strings.DropDownSelectSiteScriptPlaceHolder}
|
||||
label={strings.DropDownSelectSiteScriptLabel}
|
||||
selectedKey={this.state.selectedItemWebTemplate}
|
||||
onChange={this.onSelectedItemWebTemplate}
|
||||
options={[
|
||||
{ key: 64, text: strings.WebTemplateTeamSite },
|
||||
{ key: 68, text: strings.WebTemplateCommunicationSite }
|
||||
]}
|
||||
|
||||
/>
|
||||
<TextField
|
||||
label={strings.AddSiteDesignDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.Description : ''}
|
||||
deferredValidationTime={200}
|
||||
multiline
|
||||
onGetErrorMessage={this.onGetErrorMessageDescription} />
|
||||
<TextField
|
||||
label={strings.AddSiteDesignImageUrlLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.siteDesignInfo ? this.state.siteDesignInfo.PreviewImageUrl : ''}
|
||||
deferredValidationTime={200}
|
||||
|
||||
onGetErrorMessage={this.onGetErrorMessageImageUrl} />
|
||||
<br />
|
||||
{
|
||||
this.state.siteDesignInfo.PreviewImageUrl &&
|
||||
<Image src={this.state.siteDesignInfo ? this.state.siteDesignInfo.PreviewImageUrl : ''}
|
||||
imageFit={ImageFit.cover}
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
}
|
||||
<Toggle
|
||||
defaultChecked={this.state.siteDesignInfo.IsDefault}
|
||||
label={strings.AddSiteDesignIsDefaultLabel}
|
||||
onText="On"
|
||||
offText="Off"
|
||||
onChange={this.onIsDefault}
|
||||
/>
|
||||
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.EditSiteDesignPanelButtonSaveText} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.EditSiteDesignPanelButtonCancelText} />
|
||||
</DialogFooter>
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
export interface IEditSiteDesignProps {
|
||||
|
||||
context: WebPartContext;
|
||||
mode: panelMode;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
siteDesignInfo: IListViewItems;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IListViewItems } from '../../webparts/siteDesigns/components/IListViewItems';
|
||||
|
||||
|
||||
import { SiteDesignInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
export interface IEditSiteDesignState {
|
||||
isLoading: boolean;
|
||||
siteDesignInfo?: IListViewItems;
|
||||
showPanel: boolean;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
saving: boolean;
|
||||
selectedItemWebTemplate: string | number;
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { IEditSiteScriptProps } from './IEditSiteScriptProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { IEditSiteScriptState } from './IEditSiteScriptState';
|
||||
import { SiteDesignInfo, SiteScriptInfo, SiteScriptUpdateInfo } from '@pnp/sp';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
|
||||
export default class EditSiteScript extends React.Component<IEditSiteScriptProps, IEditSiteScriptState> {
|
||||
private spService: spservice;
|
||||
private siteScriptShowError: boolean = false;
|
||||
private siteTitleShowError: boolean = false;
|
||||
private siteScriptInfo: SiteScriptInfo;
|
||||
|
||||
private JsonEditorWrapper = React.lazy(() => import('../json-editor-wrapper' /* webpackChunkName: "testcomponent" */));
|
||||
private currentSiteScript: ISiteScript = {
|
||||
|
||||
"$schema": "schema.json",
|
||||
"actions": [],
|
||||
"bindata": {},
|
||||
"version": 1
|
||||
};
|
||||
|
||||
/**
|
||||
*Creates an instance of EditSiteScript.
|
||||
* @param {*} props
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
saving: false,
|
||||
hideDialog: true,
|
||||
readOnly: false,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
disableSaveButton: true,
|
||||
currentSiteScript: this.currentSiteScript,
|
||||
title: '',
|
||||
description: '',
|
||||
isLoading: false
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onGetErrorMessageDescription = this.onGetErrorMessageDescription.bind(this);
|
||||
this.onGetErrorMessageTitle = this.onGetErrorMessageTitle.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.setSiteScript = this.setSiteScript.bind(this);
|
||||
this.onValidateSiteScript = this.onValidateSiteScript.bind(this);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private async onSave(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
try {
|
||||
const siteScriptUpdateInfo: SiteScriptUpdateInfo = { Id: this.props.siteScriptId, Title: this.state.title, Description: this.state.description, Content: JSON.stringify(this.state.currentSiteScript) };
|
||||
this.setState({ saving: true, disableSaveButton: true });
|
||||
const result = await this.spService.updateSiteScript(siteScriptUpdateInfo);
|
||||
this.props.onDismiss(true);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
try {
|
||||
this.setState({ isLoading: true });
|
||||
this.siteScriptInfo = await this.spService.getSiteScriptMetadata(this.props.siteScriptId);
|
||||
const siteScript: ISiteScript = JSON.parse(this.siteScriptInfo.Content);
|
||||
this.setState({ isLoading: false, description: this.siteScriptInfo.Description, title: this.siteScriptInfo.Title, currentSiteScript: siteScript });
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ isLoading: false, saving: false, disableSaveButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {*} value
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private setSiteScript(value: ISiteScript) {
|
||||
this.setState({ currentSiteScript: value });
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} error (true/false)
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private onValidateSiteScript(valid: boolean) {
|
||||
|
||||
if (valid) {
|
||||
this.siteScriptShowError = false;
|
||||
if (this.siteTitleShowError) {
|
||||
this.setState({ errorMessage: '', disableSaveButton: true, showError: false });
|
||||
} else {
|
||||
this.setState({ errorMessage: '', disableSaveButton: false, showError: false });
|
||||
}
|
||||
} else {
|
||||
this.siteScriptShowError = true;
|
||||
this.setState({ showError: true, errorMessage: strings.JSONSchemaNotValidMessage, disableSaveButton: true });
|
||||
}
|
||||
}
|
||||
// Validate Value
|
||||
/**
|
||||
*
|
||||
* Validate Title
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private onGetErrorMessageTitle(value: string) {
|
||||
let returnvalue: string = '';
|
||||
let siteScriptTitle = this.state.title;
|
||||
|
||||
if (value.trim().length > 0) {
|
||||
siteScriptTitle = value;
|
||||
this.siteTitleShowError = false;
|
||||
if (this.siteScriptShowError) {
|
||||
this.setState({ disableSaveButton: true, title: siteScriptTitle });
|
||||
} else {
|
||||
this.setState({ disableSaveButton: false, title: siteScriptTitle });
|
||||
}
|
||||
} else {
|
||||
siteScriptTitle = value;
|
||||
this.siteTitleShowError = true;
|
||||
this.setState({ disableSaveButton: true, title: siteScriptTitle });
|
||||
// returnvalue = 'Site Script title is required';
|
||||
}
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
private onGetErrorMessageDescription(value: string) {
|
||||
let returnvalue: string = '';
|
||||
this.setState({ description: value });
|
||||
return returnvalue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @returns {React.ReactElement<IEditSiteScriptProps>}
|
||||
* @memberof EditSiteScript
|
||||
*/
|
||||
public render(): React.ReactElement<IEditSiteScriptProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns} >
|
||||
|
||||
<Dialog
|
||||
hidden={this.props.hideDialog}
|
||||
onDismiss={this.onCancel}
|
||||
minWidth={"600px"}
|
||||
dialogContentProps={{
|
||||
type: DialogType.normal,
|
||||
title: strings.EditSiteScriptDialogTitle,
|
||||
subText: strings.AddSiteScriptDialogSubText
|
||||
}}
|
||||
modalProps={{
|
||||
isBlocking: true,
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.state.isLoading &&
|
||||
<Spinner size={SpinnerSize.small} label={strings.LoadingLabel} ariaLive="assertive" />
|
||||
}
|
||||
{
|
||||
this.state.showError &&
|
||||
<MessageBar messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
}
|
||||
{
|
||||
!this.state.isLoading &&
|
||||
<TextField
|
||||
label={strings.SiteScriptIdLabel}
|
||||
readOnly={true}
|
||||
value={this.props.siteScriptId}
|
||||
style={{backgroundColor: "#f8f8f8"}}
|
||||
/>
|
||||
}
|
||||
{
|
||||
!this.state.isLoading &&
|
||||
<TextField
|
||||
label={strings.AddSiteScriptTitleLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
required={true}
|
||||
value={this.state.title ? this.state.title : ''}
|
||||
deferredValidationTime={300}
|
||||
onGetErrorMessage={this.onGetErrorMessageTitle} />
|
||||
}
|
||||
{
|
||||
!this.state.isLoading &&
|
||||
<TextField
|
||||
label={strings.AddSiteScriptDescriptionLabel}
|
||||
readOnly={this.state.readOnly}
|
||||
value={this.state.title ? this.state.description : ''}
|
||||
deferredValidationTime={300}
|
||||
onGetErrorMessage={this.onGetErrorMessageDescription} />
|
||||
}
|
||||
<br />
|
||||
{
|
||||
!this.state.isLoading &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.JsonEditorWrapper
|
||||
currentSiteScript={this.state.currentSiteScript}
|
||||
setSiteScript={this.setSiteScript}
|
||||
onValidate={this.onValidateSiteScript}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.saving &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<PrimaryButton onClick={this.onSave} text={strings.EditSiteScriptSaveButtonLabel} disabled={this.state.disableSaveButton} />
|
||||
<DefaultButton onClick={this.onCancel} text={strings.EditSiteScriptPanelButtonCancel} />
|
||||
</DialogFooter>
|
||||
|
||||
|
||||
</Dialog>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface IEditSiteScriptProps {
|
||||
|
||||
context: WebPartContext;
|
||||
hideDialog: boolean;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
siteScriptId:string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { SiteDesignInfo, SiteScriptInfo } from '@pnp/sp';
|
||||
import { ISiteScript } from '../../types/ISiteScript';
|
||||
export interface IEditSiteScriptState {
|
||||
title: string;
|
||||
description: string;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
readOnly: boolean;
|
||||
disableSaveButton: boolean;
|
||||
currentSiteScript: ISiteScript;
|
||||
hideDialog: boolean;
|
||||
saving: boolean;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import { IViewSite } from './IViewSite';
|
||||
|
||||
export interface ISelectSiteProps {
|
||||
context: WebPartContext;
|
||||
onSelectItem: (item:IViewSite[]) => void;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
import {IViewSite } from './IViewSite';
|
||||
|
||||
export interface ISelectSiteState {
|
||||
isLoading: boolean;
|
||||
showError: boolean;
|
||||
errorMessage: string;
|
||||
selectedItems: IViewSite[];
|
||||
items: IViewSite[];
|
||||
hasError:boolean;
|
||||
showList:boolean;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
export interface IViewSite {
|
||||
key: string;
|
||||
webtemplate: string;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||
.selectSite {
|
||||
margin-top: 25px
|
||||
|
||||
}
|
||||
.title {
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
}
|
||||
.label {
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
@include ms-font-l;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from './SelectSite.module.scss';
|
||||
import { ISelectSiteProps } from './ISelectSiteProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import spservice from '../../services/spservices';
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { ISelectSiteState } from './ISelectSiteState';
|
||||
import {
|
||||
ActionButton,
|
||||
Icon,
|
||||
Spinner,
|
||||
SpinnerSize,
|
||||
MessageBar,
|
||||
MessageBarType,
|
||||
SearchBox,
|
||||
Link
|
||||
} from 'office-ui-fabric-react';
|
||||
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
|
||||
import { IViewSite } from './IViewSite';
|
||||
import { SearchResults } from '@pnp/sp';
|
||||
|
||||
|
||||
// ListView Columns
|
||||
const viewFields: IViewField[] = [
|
||||
{
|
||||
name: 'icon',
|
||||
render: ((item: any) => {
|
||||
const image = <Icon iconName="FileASPX" />;
|
||||
return image;
|
||||
}),
|
||||
maxWidth: 40,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
displayName: strings.WebSiteTitleLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 200
|
||||
},
|
||||
{
|
||||
name: 'url',
|
||||
render: ((item: IViewSite) =>{
|
||||
const link = <Link href={item.url} target='blank'>{item.url}</Link>;
|
||||
return link;
|
||||
}),
|
||||
displayName:strings.WebSiteUrl ,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 200
|
||||
}
|
||||
];
|
||||
|
||||
export default class SelectSite extends React.Component<ISelectSiteProps, ISelectSiteState> {
|
||||
private spService: spservice;
|
||||
private items : IViewSite[];
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
isLoading: false,
|
||||
showError: false,
|
||||
errorMessage: '',
|
||||
selectedItems: [],
|
||||
items: [],
|
||||
hasError:false,
|
||||
showList: false
|
||||
});
|
||||
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
this.onClear = this.onClear.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SelectSite
|
||||
*/
|
||||
private async onClear(ev: React.MouseEvent<HTMLButtonElement>){
|
||||
ev.preventDefault();
|
||||
this.items=[];
|
||||
this.setState({showList:false, items: this.items, hasError: false, errorMessage:''});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SelectSite
|
||||
*/
|
||||
private async onSearch(newValue:string) {
|
||||
let results: SearchResults = null;
|
||||
this.items=[];
|
||||
this.setState({isLoading:true, errorMessage:''});
|
||||
try{
|
||||
results = await this.spService.getSites(newValue);
|
||||
if (results && results.PrimarySearchResults ){
|
||||
for ( const result of results.PrimarySearchResults){
|
||||
this.items.push({key: result.UniqueId, title: result.Title, url: result.Path, webtemplate: result.WebTemplate});
|
||||
}
|
||||
}
|
||||
this.setState({items: this.items, isLoading:false, errorMessage:'', showList:true});
|
||||
}catch(error){
|
||||
this.setState({hasError:true,isLoading:false, errorMessage: error.message, showList:false});
|
||||
}
|
||||
}
|
||||
// Component Did Mount
|
||||
/**
|
||||
*
|
||||
* @memberof SelectSite
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* On Render
|
||||
*
|
||||
* @returns {React.ReactElement<ISelectSiteProps>}
|
||||
* @memberof SelectSite
|
||||
*/
|
||||
public render(): React.ReactElement<ISelectSiteProps> {
|
||||
|
||||
return (
|
||||
<div className={styles.selectSite}>
|
||||
<SearchBox
|
||||
placeholder={strings.SearchBoxPlaceholderText}
|
||||
onClear={this.onClear}
|
||||
onSearch={this.onSearch}
|
||||
/>
|
||||
<br/>
|
||||
{
|
||||
this.state.isLoading ?
|
||||
<Spinner size={SpinnerSize.large} label={strings.LoadingLabel} ariaLive="assertive" />
|
||||
:
|
||||
this.state.hasError ?
|
||||
<MessageBar
|
||||
messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
:
|
||||
this.state.showList &&
|
||||
<ListView
|
||||
items={this.state.items}
|
||||
viewFields={viewFields}
|
||||
compact={false}
|
||||
selectionMode={SelectionMode.multiple}
|
||||
selection={this.props.onSelectItem}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface IListViewItems {
|
||||
'key': string;
|
||||
DisplayName: string;
|
||||
PrincipalName: string;
|
||||
Rights?: number;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { IListViewItems } from './IListViewItems';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface ISiteDesignRightsState{
|
||||
items: IListViewItems[];
|
||||
isLoading:boolean;
|
||||
disableCommandOption:boolean;
|
||||
showPanel:boolean;
|
||||
selectItem: IListViewItems[];
|
||||
panelMode: panelMode;
|
||||
hasError: boolean;
|
||||
errorMessage: string;
|
||||
showPanelAddScript: boolean;
|
||||
showDialogDelete:boolean;
|
||||
deleting:boolean;
|
||||
disableDeleteButton: boolean;
|
||||
showError: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface ISiteDesignRightsProps {
|
||||
SiteDesignSelectedItem: ISiteDesignSelectedItem;
|
||||
context: WebPartContext;
|
||||
mode: panelMode;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
}
|
||||
|
||||
interface ISiteDesignSelectedItem {
|
||||
key: string;
|
||||
Description: string;
|
||||
PreviewImageUrl: string;
|
||||
SiteScriptIds: string;
|
||||
Title: string;
|
||||
WebTemplate: string;
|
||||
Id: string;
|
||||
numberSiteScripts:number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText:string;
|
||||
Version: string;
|
||||
runStatus: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||
.title {
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
}
|
||||
.label {
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
@include ms-font-l;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
//import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { ISiteDesignRightsProps } from './ISiteRightsProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
|
||||
import { IListViewItems } from './IListViewItems';
|
||||
import spservice from '../../services/spservices';
|
||||
import {
|
||||
Icon,
|
||||
IconType,
|
||||
CommandBar,
|
||||
Panel,
|
||||
PanelType,
|
||||
MessageBar,
|
||||
MessageBarType,
|
||||
Label,
|
||||
Spinner,
|
||||
SpinnerSize,
|
||||
Dialog,
|
||||
DialogType,
|
||||
DialogFooter,
|
||||
PrimaryButton,
|
||||
DefaultButton,
|
||||
ImageFit,
|
||||
|
||||
} from 'office-ui-fabric-react';
|
||||
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { ISiteDesignRightsState } from './ISiteDesignRightsState';
|
||||
import { SiteDesignInfo, SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignUpdateInfo, SiteDesignPrincipals } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import styles from './SiteDesignRights.module.scss';
|
||||
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
|
||||
|
||||
// "https://outlook.office365.com/owa/service.svc/s/Ge…?email=anamendes@sitenanuvem.pt&UA=0&size=HR96x96"
|
||||
// ListView Columns
|
||||
const viewFields: IViewField[] = [
|
||||
{
|
||||
name: 'Icon',
|
||||
render: ((item: IListViewItems) => {
|
||||
// const image = <Icon iconName="UserFollowed" />;
|
||||
const email = item.PrincipalName.replace('i:0#.f|membership|', "");
|
||||
const image = <Icon iconType={IconType.image} imageProps={{ imageFit: ImageFit.cover, src: `/_layouts/15/userphoto.aspx?size=s&accountname=${email}`, className: styles.image }} />;
|
||||
return image;
|
||||
}),
|
||||
maxWidth: 70,
|
||||
},
|
||||
{
|
||||
name: 'DisplayName',
|
||||
displayName: strings.ListViewColumnIdPrincipalNameLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 300,
|
||||
minWidth: 300
|
||||
}
|
||||
];
|
||||
|
||||
export default class SiteDesignRights extends React.Component<ISiteDesignRightsProps, ISiteDesignRightsState> {
|
||||
|
||||
private spService: spservice;
|
||||
private items: IListViewItems[] = [];
|
||||
private refreshParent: boolean = false;
|
||||
private siteDesignPrincipals: SiteDesignPrincipals[];
|
||||
|
||||
private AddPrincipal = React.lazy(() => import('../AddPrincipal/AddPrincipal' /* webpackChunkName: "addprincipal" */));
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
items: [],
|
||||
isLoading: false,
|
||||
disableCommandOption: true,
|
||||
showPanel: false,
|
||||
selectItem: [],
|
||||
panelMode: panelMode.New,
|
||||
hasError: false,
|
||||
errorMessage: '',
|
||||
showPanelAddScript: false,
|
||||
showDialogDelete: false,
|
||||
deleting: false,
|
||||
disableDeleteButton: false,
|
||||
showError: false
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.getSelection = this.getSelection.bind(this);
|
||||
this.onNewItem = this.onNewItem.bind(this);
|
||||
this.onDeleteItem = this.onDeleteItem.bind(this);
|
||||
this.onDismissPanel = this.onDismissPanel.bind(this);
|
||||
this.onRefresh = this.onRefresh.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onDismissAddPrincipalPane = this.onDismissAddPrincipalPane.bind(this);
|
||||
this.onCloseDialog = this.onCloseDialog.bind(this);
|
||||
this.onDeleteConfirm = this.onDeleteConfirm.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} refresh
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private onDismissAddPrincipalPane(refresh: boolean) {
|
||||
|
||||
this.setState({ showPanel: false });
|
||||
if (refresh) {
|
||||
this.refreshParent = true;
|
||||
this.loadPrincipals();
|
||||
}
|
||||
}
|
||||
|
||||
// Get Selection Item from List
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {IListViewItems[]} items
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private getSelection(items: IListViewItems[]) {
|
||||
if (items.length > 0) {
|
||||
this.setState({
|
||||
disableCommandOption: false,
|
||||
selectItem: items
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
disableCommandOption: true,
|
||||
selectItem: [],
|
||||
showPanel: false,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* cancel event option SiteScrips
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
|
||||
this.props.onDismiss(this.refreshParent);
|
||||
}
|
||||
|
||||
private onCloseDialog(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.setState({
|
||||
showDialogDelete: false
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private async onDeleteConfirm(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
try {
|
||||
let updateSiteDesignPrincipals: IListViewItems[] = this.items;
|
||||
for (const item of this.state.selectItem) {
|
||||
const idx = updateSiteDesignPrincipals.indexOf(item);
|
||||
if (idx !== -1) {
|
||||
updateSiteDesignPrincipals.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ deleting: true, disableDeleteButton: true });
|
||||
const principals: string[] = [];
|
||||
for (const item of this.state.selectItem) {
|
||||
principals.push(item.PrincipalName.replace('i:0#.f|membership|', ""));
|
||||
}
|
||||
|
||||
await this.spService.revokeSiteDesignRights(this.props.SiteDesignSelectedItem.Id, principals);
|
||||
this.refreshParent = true;
|
||||
this.setState({ deleting: false, disableDeleteButton: false, showDialogDelete: false, showError: false });
|
||||
this.loadPrincipals();
|
||||
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ deleting: false, disableDeleteButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Panel Dismiss CallBack
|
||||
*
|
||||
* @param {boolean} [refresh]
|
||||
* @returns
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
public async onDismissPanel(refresh?: boolean) {
|
||||
this.setState({
|
||||
showPanel: false
|
||||
});
|
||||
if (refresh) {
|
||||
await this.loadPrincipals();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// On New Item
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private onNewItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.New,
|
||||
showPanel: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On Delete
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private onDeleteItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.Delete,
|
||||
showDialogDelete: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SiteDesignRights
|
||||
*
|
||||
* @private
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
private async loadPrincipals() {
|
||||
this.items = [];
|
||||
this.setState({ isLoading: true });
|
||||
try {
|
||||
// check if user is Teanant Global Admin
|
||||
const isGlobalAdmin = await this.spService.checkUserIsGlobalAdmin();
|
||||
if (isGlobalAdmin) {
|
||||
// get SiteDesignRights for SiteDesign
|
||||
this.siteDesignPrincipals = await this.spService.getSiteDesignRights(this.props.SiteDesignSelectedItem.Id);
|
||||
|
||||
if (this.siteDesignPrincipals.length > 0) {
|
||||
for (const siteDesignPrincipal of this.siteDesignPrincipals) {
|
||||
|
||||
this.items.push(
|
||||
{
|
||||
key: siteDesignPrincipal.PrincipalName,
|
||||
DisplayName: siteDesignPrincipal.DisplayName,
|
||||
PrincipalName: siteDesignPrincipal.PrincipalName
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
this.setState({ items: this.items, isLoading: false, disableCommandOption: true });
|
||||
} else {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: strings.ErrorMessageUserNotAdmin,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: error.message,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
/** Refresh
|
||||
*
|
||||
* @param {React.MouseEvent<HTMLElement>} ev
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
public onRefresh(ev: React.MouseEvent<HTMLElement>) {
|
||||
ev.preventDefault();
|
||||
// loadPrincipals
|
||||
this.loadPrincipals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component Did Mount
|
||||
*
|
||||
* @memberof SiteDesignRights
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// loadPrincipals
|
||||
await this.loadPrincipals();
|
||||
}
|
||||
// On Render
|
||||
public render(): React.ReactElement<ISiteDesignRightsProps> {
|
||||
return (
|
||||
<div>
|
||||
<Panel isOpen={this.props.showPanel} onDismiss={this.onCancel} type={PanelType.medium} headerText={strings.SiteDesignRightsPanelTitle}>
|
||||
<div>
|
||||
<span className={styles.label}>{strings.SiteDesignIdLabel}</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.Id}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className={styles.label}>{strings.SiteDesignRightsPanelTitle}</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.Title}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className={styles.label}>{strings.WebTemplateLabel}</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.WebTemplate === '64' ? strings.WebTemplateTeamSite : strings.WebTemplateCommunicationSite}</span>
|
||||
</div>
|
||||
<br />
|
||||
{
|
||||
this.state.isLoading ?
|
||||
<Spinner size={SpinnerSize.large} label={strings.LoadingLabel} ariaLive="assertive" />
|
||||
:
|
||||
this.state.hasError ?
|
||||
<MessageBar
|
||||
messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
:
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<CommandBar
|
||||
items={[
|
||||
{
|
||||
key: 'newItem',
|
||||
name: strings.CommandbarNewLabel,
|
||||
iconProps: {
|
||||
iconName: 'Add'
|
||||
},
|
||||
onClick: this.onNewItem,
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
name: strings.CommandbarDeleteLabel,
|
||||
iconProps: {
|
||||
iconName: 'Delete'
|
||||
},
|
||||
onClick: this.onDeleteItem,
|
||||
disabled: this.state.disableCommandOption,
|
||||
}
|
||||
]}
|
||||
farItems={[
|
||||
{
|
||||
key: 'refresh',
|
||||
name: strings.CommandbarRefreshLabel,
|
||||
iconProps: {
|
||||
iconName: 'Refresh'
|
||||
},
|
||||
onClick: this.onRefresh,
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
!this.state.hasError && !this.state.isLoading &&
|
||||
<ListView
|
||||
items={this.state.items}
|
||||
viewFields={viewFields}
|
||||
compact={false}
|
||||
selectionMode={SelectionMode.multiple}
|
||||
selection={this.getSelection}
|
||||
showFilter={true}
|
||||
filterPlaceHolder={strings.SearchPlaceholder}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.New &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.AddPrincipal
|
||||
showPanel={this.state.showPanel}
|
||||
onDismiss={this.onDismissAddPrincipalPane}
|
||||
context={this.props.context}
|
||||
siteDesignInfo={this.props.SiteDesignSelectedItem}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
|
||||
<Dialog
|
||||
hidden={!this.state.showDialogDelete}
|
||||
onDismiss={this.onCloseDialog}
|
||||
|
||||
dialogContentProps={{
|
||||
type: DialogType.normal,
|
||||
title: strings.DialogConfirmDeleteTitle,
|
||||
}}
|
||||
modalProps={{
|
||||
isBlocking: true,
|
||||
|
||||
}}
|
||||
>
|
||||
<p>{strings.DialogConfirmDeleteText}</p>
|
||||
<br />
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.deleting &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<DefaultButton onClick={this.onDeleteConfirm} text={strings.ButtonDeleteLabel} disabled={this.state.disableDeleteButton} />
|
||||
<PrimaryButton onClick={this.onCloseDialog} text={strings.ButtonCancelLabel} />
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</Panel>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import * as React from 'react';
|
||||
import JSONEditor from "jsoneditor";
|
||||
var schema = require("./../json-editor-wrapper/site-design-script-actions.schema.json");
|
||||
|
||||
|
||||
import "jsoneditor/dist/jsoneditor.css";
|
||||
|
||||
export interface JsonEditorProps {
|
||||
onChange: (json: any) => void;
|
||||
onDirty: () => void;
|
||||
value: object;
|
||||
options: any;
|
||||
width: string;
|
||||
height: string;
|
||||
className?: string;
|
||||
config?: object;
|
||||
onValidate?: (error:boolean) => void;
|
||||
}
|
||||
|
||||
export default class JsonEditorReact extends React.PureComponent<JsonEditorProps,
|
||||
any> {
|
||||
private timeout: any = undefined;
|
||||
private editor: JSONEditor;
|
||||
private div: any;
|
||||
public static defaultProps: Partial<JsonEditorProps> = {
|
||||
config: {},
|
||||
onDirty: () => { }
|
||||
};
|
||||
constructor(props: JsonEditorProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
currentValue: props.value,
|
||||
dirty: false
|
||||
};
|
||||
this.onValidate = this.onValidate.bind(this);
|
||||
}
|
||||
|
||||
private handleChange = () => {
|
||||
|
||||
this.setState({
|
||||
currentValue: this
|
||||
.editor
|
||||
.get(),
|
||||
dirty: true
|
||||
});
|
||||
}
|
||||
|
||||
private onValidate(json) {
|
||||
const vl = this.props.options.ajv.compile(schema);
|
||||
|
||||
if (vl(json) && json.actions && json.actions.length > 0 && json['$schema'] && json.bindata && json.version){
|
||||
this.props.onValidate(true);
|
||||
}else{
|
||||
this.props.onValidate(false);
|
||||
}
|
||||
}
|
||||
|
||||
private handleFocus = () => {
|
||||
this.setState({ controllingFocus: true });
|
||||
}
|
||||
|
||||
private handleBlur = () => {
|
||||
this.setState({ controllingFocus: false });
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const { value, options } = this.props;
|
||||
|
||||
const mergedOptions = {
|
||||
...options,
|
||||
onChange: this.handleChange,
|
||||
onValidate: this.onValidate,
|
||||
|
||||
};
|
||||
|
||||
this.editor = new JSONEditor(this.div, mergedOptions);
|
||||
this
|
||||
.editor
|
||||
.set(value);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: JsonEditorProps, prevState: JsonEditorProps) {
|
||||
const { onChange, onDirty } = this.props;
|
||||
|
||||
if (this.state.dirty === true && this.state.controllingFocus) {
|
||||
onDirty();
|
||||
}
|
||||
|
||||
//if (this.state.dirty === true && !this.state.controllingFocus) {
|
||||
if (this.state.dirty === true) {
|
||||
this.timeout = setTimeout(() => {
|
||||
onChange(this.state.currentValue);
|
||||
this.setState({ dirty: false });
|
||||
}, 200);
|
||||
}
|
||||
|
||||
//if (this.state.controllingFocus) {
|
||||
// clearTimeout(this.timeout);
|
||||
//}
|
||||
|
||||
if (prevProps.value !== this.props.value && !this.state.controllingFocus) {
|
||||
|
||||
this
|
||||
.editor
|
||||
.set(this.props.value);
|
||||
this.setState({ currentValue: this.props.value, dirty: false });
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this
|
||||
.editor
|
||||
.destroy();
|
||||
delete this.editor;
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { className } = this.props;
|
||||
|
||||
return (<div
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleBlur}
|
||||
className={className}
|
||||
style={{ height: this.props.height , width: this.props.width}}
|
||||
ref={div => {
|
||||
this.div = div;
|
||||
}} />);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
div.jsoneditor-menu {
|
||||
color: white;
|
||||
background-color: #414141;
|
||||
border-bottom: 1px solid #aeaeae;
|
||||
}
|
||||
div.jsoneditor-menu .jsoneditor-poweredBy{
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import * as React from "react";
|
||||
|
||||
import JsonEditorReact from "../../controls/json-editor-react";
|
||||
import { ISiteScript } from "../../types/ISiteScript";
|
||||
var schema = require("./site-design-script-actions.schema.json");
|
||||
import "./index.css";
|
||||
import * as Ajv from 'ajv';
|
||||
|
||||
interface IJsonEditorWrapperProps {
|
||||
currentSiteScript: ISiteScript | null | undefined;
|
||||
setSiteScript: (siteScript: ISiteScript) => void;
|
||||
onValidate: (error:boolean) => void;
|
||||
}
|
||||
|
||||
const JsonEditorWrapper: React.SFC<IJsonEditorWrapperProps> = props => {
|
||||
// Editor configuration. See jsoneditor's API.
|
||||
var ajv = new Ajv();
|
||||
|
||||
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
|
||||
ajv.addSchema(schema, 'JSON Schema for SiteScript Extensions');
|
||||
|
||||
|
||||
const options = {
|
||||
mode: "code",
|
||||
schema,
|
||||
ajv,
|
||||
|
||||
};
|
||||
return (
|
||||
<JsonEditorReact
|
||||
value={props.currentSiteScript ? props.currentSiteScript : {}}
|
||||
onChange={props.setSiteScript}
|
||||
onDirty={() => {}}
|
||||
options={options}
|
||||
height={"300px"}
|
||||
width={"100%"}
|
||||
onValidate={props.onValidate}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export default JsonEditorWrapper;
|
|
@ -0,0 +1,907 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title": "JSON Schema for SiteScript Extensions",
|
||||
"definitions": {
|
||||
"baseAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": { "type": "string" }
|
||||
},
|
||||
"required": [ "verb" ]
|
||||
},
|
||||
"activateSPFeature": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^activateSPFeature$"
|
||||
},
|
||||
"featureId": {
|
||||
"type": "string",
|
||||
"description": "The Guid of the feature to activate."
|
||||
}
|
||||
},
|
||||
"required": [ "featureId", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"associateExtension": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^associateExtension$"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Title of the extension."
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"pattern": "^ClientSideExtension\\..*$",
|
||||
"description": "If this extension creates commands, where the commands are display. Otherwise, this should be set to ClientSideExtension.ApplicationCustomizer."
|
||||
},
|
||||
"clientSideComponentId": {
|
||||
"type": "string",
|
||||
"description": "GUID of the extension."
|
||||
},
|
||||
"clientSideComponentProperties": {
|
||||
"type": "string",
|
||||
"description": "This is an optional parameter, which can be used to provide properties for the instance."
|
||||
},
|
||||
"registrationId": {
|
||||
"type": "string",
|
||||
"description": "This is an optional parameter, which indicates the type of the list to which extension is associated, if the extension is associated with lists."
|
||||
},
|
||||
"registrationType": {
|
||||
"type": "string",
|
||||
"pattern": "^$|^List$",
|
||||
"description": "This is an optional parameter, which should be specified if the extension is associated with a list."
|
||||
},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"pattern": "^(Web|Site)$",
|
||||
"description": "Indicates whether the extension is associated with a Web or a Site."
|
||||
}
|
||||
},
|
||||
"required": [ "clientSideComponentId", "title", "location", "verb", "scope" ]
|
||||
},
|
||||
"createSPList": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^createSPList$"
|
||||
},
|
||||
"listName": {
|
||||
"type": "string",
|
||||
"description": "An identifying name for the list."
|
||||
},
|
||||
"templateType": {
|
||||
"type": "number",
|
||||
"description": "Specifies the type of a list definition or a list template."
|
||||
},
|
||||
"subactions": {
|
||||
"description": "Sub-actions to run on the list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/SPListSubactions/setTitle" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/setDescription" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addSPField" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/deleteSPField" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addSPFieldXml" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addSPLookupFieldXml" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addSiteColumn" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addSPView" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/removeSPView" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/addContentType" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/removeContentType" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/setSPFieldCustomFormatter" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/associateFieldCustomizer" },
|
||||
{ "$ref": "#/definitions/SPListSubactions/associateListViewCommandSet" }
|
||||
]
|
||||
},
|
||||
"additionalItems": false
|
||||
}
|
||||
},
|
||||
"required": [ "listName", "templateType", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"SPListSubactions": {
|
||||
"addContentType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addContentType$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the ContentType to add."
|
||||
}
|
||||
},
|
||||
"required": [ "name", "verb" ]
|
||||
},
|
||||
"removeContentType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^removeContentType$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the ContentType to remove."
|
||||
}
|
||||
},
|
||||
"required": [ "name", "verb" ]
|
||||
},
|
||||
"setSPFieldCustomFormatter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setSPFieldCustomFormatter$"
|
||||
},
|
||||
"fieldDisplayName": {
|
||||
"type": "string",
|
||||
"description": "The DisplayName of the SPField to operate on."
|
||||
},
|
||||
"formatterJSON": {
|
||||
"type": "object",
|
||||
"description": "A JSON object to use as the field CustomFormatter."
|
||||
}
|
||||
},
|
||||
"required": [ "fieldDisplayName", "verb", "formatterJSON" ]
|
||||
},
|
||||
"setTitle": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setTitle$"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The new title of the list."
|
||||
}
|
||||
},
|
||||
"required": [ "title", "verb" ]
|
||||
},
|
||||
"setDescription": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setDescription$"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "The new description of the list."
|
||||
}
|
||||
},
|
||||
"required": [ "description", "verb" ]
|
||||
},
|
||||
"addSiteColumn": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSiteColumn$"
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "The internal name of the site column to add."
|
||||
},
|
||||
"addToDefaultView": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, the newly added field will also be added to the default view."
|
||||
}
|
||||
},
|
||||
"required": [ "internalName", "verb" ]
|
||||
},
|
||||
"addSPField": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSPField$"
|
||||
},
|
||||
"fieldType": {
|
||||
"type": "string",
|
||||
"pattern": "^(Text|Note|Number|Boolean|User|DateTime)$",
|
||||
"description": "The type of field to add."
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"description": "The display name of the field."
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "Optional attribute. If provided, specifies the internal name of the field. If not provided, the internal name will be based on the display name"
|
||||
},
|
||||
"isRequired": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this field is required to contain information."
|
||||
},
|
||||
"addToDefaultView": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, the newly added field will also be added to the default view."
|
||||
},
|
||||
"enforceUnique": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, then all values for this field must be unique."
|
||||
}
|
||||
},
|
||||
"required": [ "displayName", "fieldType", "isRequired", "verb" ]
|
||||
},
|
||||
"deleteSPField": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^deleteSPField$"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"description": "The display name of the field to delete."
|
||||
}
|
||||
},
|
||||
"required": [ "displayName" ]
|
||||
},
|
||||
"addSPFieldXml": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSPFieldXml$"
|
||||
},
|
||||
"schemaXml": {
|
||||
"type": "string",
|
||||
"description": "The schemaXml specifying the field. See https://msdn.microsoft.com/en-us/library/office/aa979575.aspx"
|
||||
},
|
||||
"addToDefaultView": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, the newly added field will also be added to the default view."
|
||||
}
|
||||
},
|
||||
"required": [ "schemaXml", "verb" ]
|
||||
},
|
||||
"addSPLookupFieldXml": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSPLookupFieldXml$"
|
||||
},
|
||||
"schemaXml": {
|
||||
"type": "string",
|
||||
"description": "The schemaXml specifying the field. See https://msdn.microsoft.com/en-us/library/office/aa979575.aspx"
|
||||
},
|
||||
"targetListName": {
|
||||
"type": "string",
|
||||
"description": "The name that identifies the list this lookup field is targeted against. Provide either this or targetListUrl."
|
||||
},
|
||||
"targetListUrl": {
|
||||
"type": "string",
|
||||
"description": "A web-relative url that identifies the list this lookup field is targeted against. Provide either this or targetListName."
|
||||
},
|
||||
"addToDefaultView": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, the newly added field will also be added to the default view."
|
||||
}
|
||||
},
|
||||
"required": [ "schemaXml", "verb" ]
|
||||
},
|
||||
"associateFieldCustomizer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^associateFieldCustomizer$"
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "The internalName of the field to customize."
|
||||
},
|
||||
"clientSideComponentId": {
|
||||
"type": "string",
|
||||
"description": "GUID of the extension to use to customize the field."
|
||||
},
|
||||
"clientSideComponentProperties": {
|
||||
"type": "string",
|
||||
"description": "This is an optional parameter, which can be used to provide properties for the Field Customizer instance."
|
||||
}
|
||||
},
|
||||
"required": [ "clientSideComponentId", "internalName", "verb" ]
|
||||
},
|
||||
"associateListViewCommandSet": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^associateListViewCommandSet$"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Title of the extension."
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"pattern": "^(ClientSideExtension\\.ListViewCommandSet\\.ContextMenu|ClientSideExtension\\.ListViewCommandSet\\.CommandBar|ClientSideExtension\\.ListViewCommandSet)$",
|
||||
"description": "Where the commands are displayed."
|
||||
},
|
||||
"clientSideComponentId": {
|
||||
"type": "string",
|
||||
"description": "GUID of the extension to use to customize the field."
|
||||
},
|
||||
"clientSideComponentProperties": {
|
||||
"type": "string",
|
||||
"description": "This is an optional parameter, which can be used to provide properties for the Field Customizer instance."
|
||||
}
|
||||
},
|
||||
"required": [ "clientSideComponentId", "title", "location", "verb" ]
|
||||
},
|
||||
"addSPView": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSPView$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the view."
|
||||
},
|
||||
"viewFields": {
|
||||
"description": "An array of the internal names of the fields of the view.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"query": {
|
||||
"type": "string",
|
||||
"description": "A CAML query string that contains the where clause for the view's query. See https://msdn.microsoft.com/en-us/library/ms462365"
|
||||
},
|
||||
"rowLimit": {
|
||||
"type": "integer",
|
||||
"description": "The row limit of the view."
|
||||
},
|
||||
"isPaged": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the view is paged."
|
||||
},
|
||||
"makeDefault": {
|
||||
"type": "boolean",
|
||||
"description": "If true, the view will be made the default view of the list."
|
||||
},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"pattern": "^(Default|Recursive|RecursiveAll|FilesOnly)$",
|
||||
"description": "Optional. The scope of the view. See https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx"
|
||||
},
|
||||
"formatterJSON": {
|
||||
"type": "object",
|
||||
"description": "A JSON object to use as the view CustomFormatter."
|
||||
}
|
||||
},
|
||||
"required": [ "name", "viewFields", "query", "rowLimit", "isPaged", "makeDefault" ]
|
||||
},
|
||||
"removeSPView": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^removeSPView$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the view to remove."
|
||||
}
|
||||
},
|
||||
"required": [ "name" ]
|
||||
}
|
||||
},
|
||||
"createPage": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^createPage$"
|
||||
},
|
||||
"fileName": {
|
||||
"type": "string",
|
||||
"pattern": "^.+\\.aspx&",
|
||||
"description": "The file name of the page."
|
||||
},
|
||||
"pageData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Title": {
|
||||
"type": "string",
|
||||
"description": "The title of the page."
|
||||
},
|
||||
"BannerImageUrl": {
|
||||
"type": "string",
|
||||
"description": "The URL of the image to be displayed in the banner."
|
||||
},
|
||||
"CanvasContent1": {
|
||||
"type": "string",
|
||||
"description": "The content to be displayed in the canvas, as a string of XML."
|
||||
},
|
||||
"LayoutWebpartsContent": {
|
||||
"type": "string",
|
||||
"description": "Information about the page layout, as a string of JSON."
|
||||
}
|
||||
},
|
||||
"required": [ "Title", "BannerImageUrl", "CanvasContent1", "LayoutWebpartsContent" ]
|
||||
},
|
||||
"setAsHomePage": {
|
||||
"type": "boolean",
|
||||
"description": "Whether or not to set this page as the homepage. The default is false."
|
||||
}
|
||||
},
|
||||
"required": [ "fileName", "pageData", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"addPrincipalToSPGroup": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addPrincipalToSPGroup$"
|
||||
},
|
||||
"principal": {
|
||||
"type": "string",
|
||||
"description": "The name of principal to add to the SPGroup."
|
||||
},
|
||||
"group": {
|
||||
"type": "string",
|
||||
"description": "The SPGroup to add the principal to.",
|
||||
"pattern": "^(Members|Owners|Visitors)$"
|
||||
}
|
||||
},
|
||||
"required": [ "principal", "group", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"applyTheme": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^applyTheme$"
|
||||
},
|
||||
"themeName": {
|
||||
"type": "string",
|
||||
"description": "The name of the theme to apply."
|
||||
}
|
||||
},
|
||||
"required": [ "themeName", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"setSiteLogo": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setSiteLogo$"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "The URL of the new SiteLogo."
|
||||
}
|
||||
},
|
||||
"required": [ "url", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"triggerFlow": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^triggerFlow$"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "The trigger URL of the Flow."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the Flow."
|
||||
},
|
||||
"waitForReply": {
|
||||
"type": "boolean",
|
||||
"description": "If true, the script will expect that the Flow will call Microsoft.SharePoint.Utilities.SiteScriptUtility.SetSiteScriptStageOutcome() when it has finished executing. Note that this will not cause the script to block. The script will keep executing, but for record-keeping purposes, the run will be considered incomplete until the reply is made."
|
||||
},
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"description": "An option set of parameters to pass into the Flow."
|
||||
}
|
||||
},
|
||||
"required": [ "name", "url", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"installSolution": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^installSolution$"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the Solution."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the Solution."
|
||||
}
|
||||
},
|
||||
"required": [ "id", "verb", "name" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"addNavLink": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addNavLink$"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "The url of the link to add."
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"description": "The display name of the link"
|
||||
},
|
||||
"isWebRelative": {
|
||||
"type": "boolean",
|
||||
"description": "Optionally indicates whether the link is web-relative. The default is false."
|
||||
},
|
||||
"parentDisplayName": {
|
||||
"type": "string",
|
||||
"description": "Optional parameter. If provided, makes this nav link a child of the nav link with this displayName. If both this and parentUrl are provided, it searches for a link that matches both to be the parent."
|
||||
},
|
||||
"parentUrl": {
|
||||
"type": "string",
|
||||
"description": "Optional parameter. If provided, makes this nav link a child of the nav link with this url. If both this and parentDisplayName are provided, it searches for a link that matches both to be the parent."
|
||||
},
|
||||
"isParentUrlWebRelative": {
|
||||
"type": "boolean",
|
||||
"description": "Optional parameter. Indicates whether parentUrl is web-relative. The default is false."
|
||||
}
|
||||
},
|
||||
"required": [ "displayName", "url", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"removeNavLink": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^removeNavLink$"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Optionally indicates the url of the link to remove. if this parameter is not provided, the link to be removed will be found based on the displayName only."
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"description": "The display name of the link to remove."
|
||||
},
|
||||
"isWebRelative": {
|
||||
"type": "boolean",
|
||||
"description": "Optionally indicates whether the link is web-relative. The default is false."
|
||||
}
|
||||
},
|
||||
"required": [ "displayName", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"joinHubSite": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^joinHubSite$"
|
||||
},
|
||||
"hubSiteId": {
|
||||
"type": "string",
|
||||
"description": "A Guid specifying the hub site."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "An optional string specifying the name of the hub site."
|
||||
}
|
||||
},
|
||||
"required": [ "hubSiteId", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"createContentType": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^createContentType$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the content type."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Optional description of the content type."
|
||||
},
|
||||
"parentName": {
|
||||
"type": "string",
|
||||
"description": "Name of the parent content type. Provide either this, parentId, or id."
|
||||
},
|
||||
"parentId": {
|
||||
"type": "string",
|
||||
"description": "Id of the parent content type. Provide either this, parentName, or id."
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id of the content type. Provide either this, parentName, or parentId."
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the content type is hidden."
|
||||
},
|
||||
"subactions": {
|
||||
"description": "Sub-actions to run on the content type.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/SPContentTypeSubactions/addSiteColumn" },
|
||||
{ "$ref": "#/definitions/SPContentTypeSubactions/removeSiteColumn" }
|
||||
]
|
||||
},
|
||||
"additionalItems": false
|
||||
}
|
||||
},
|
||||
"required": [ "verb", "name", "hidden" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"SPContentTypeSubactions": {
|
||||
"addSiteColumn": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^addSiteColumn$"
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "The internal name of the site column to add."
|
||||
}
|
||||
},
|
||||
"required": [ "internalName", "verb" ]
|
||||
},
|
||||
"removeSiteColumn": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^removeSiteColumn$"
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "The internal name of the site column to remove."
|
||||
}
|
||||
},
|
||||
"required": [ "internalName", "verb" ]
|
||||
}
|
||||
},
|
||||
"createSiteColumn": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^createSiteColumn$"
|
||||
},
|
||||
"fieldType": {
|
||||
"type": "string",
|
||||
"pattern": "^(Text|Note|Number|Boolean|User|DateTime)$",
|
||||
"description": "The type of column to add."
|
||||
},
|
||||
"internalName": {
|
||||
"type": "string",
|
||||
"description": "Internal name of the column"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"description": "Optional display name of the column."
|
||||
},
|
||||
"isRequired": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this column is required to contain information."
|
||||
},
|
||||
"group": {
|
||||
"type": "string",
|
||||
"description": "Optional attribute. If provided, sets the column group to which this column belongs."
|
||||
},
|
||||
"enforceUnique": {
|
||||
"type": "boolean",
|
||||
"description": "Optional attribute that defaults to false. If true, then all values for this column must be unique."
|
||||
}
|
||||
},
|
||||
"required": [ "fieldType", "verb", "internalName", "isRequired" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"createSiteColumnXml": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^createSiteColumnXml$"
|
||||
},
|
||||
"schemaXml": {
|
||||
"type": "string",
|
||||
"description": "The schemaXml specifying the field. See https://msdn.microsoft.com/en-us/library/office/aa979575.aspx"
|
||||
},
|
||||
"pushChanges": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates whether this change should be pushed to lists that already reference this field. Defaults to true."
|
||||
}
|
||||
},
|
||||
"required": [ "verb", "schemaXml" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"setSiteExternalSharingCapability": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setSiteExternalSharingCapability$"
|
||||
},
|
||||
"capability": {
|
||||
"type": "string",
|
||||
"pattern": "^(Disabled|ExistingExternalUserSharingOnly|ExternalUserSharingOnly|ExternalUserAndGuestSharing)$",
|
||||
"description": "A string specifying the sharing capability for the site."
|
||||
}
|
||||
},
|
||||
"required": [ "capability", "verb" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"setRegionalSettings": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/baseAction" },
|
||||
{
|
||||
"properties": {
|
||||
"verb": {
|
||||
"type": "string",
|
||||
"pattern": "^setRegionalSettings$"
|
||||
},
|
||||
"timeZone": {
|
||||
"type": "integer",
|
||||
"description": "A number specifying the time zone. See https://msdn.microsoft.com/library/microsoft.sharepoint.spregionalsettings.timezones.aspx"
|
||||
},
|
||||
"locale": {
|
||||
"type": "integer",
|
||||
"description": "A number specifying the culture by lcid. See https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx"
|
||||
},
|
||||
"sortOrder": {
|
||||
"type": "integer",
|
||||
"description": "A number specifying the sort order. See https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spregionalsettings.collation.aspx"
|
||||
},
|
||||
"hourFormat": {
|
||||
"type": "string",
|
||||
"pattern": "^(12|24)$",
|
||||
"description": "Specifies whether the site should use 12-hour or 24-hour time."
|
||||
}
|
||||
},
|
||||
"required": [ "sortOrder", "verb" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"actions": {
|
||||
"title": "array of supported actions",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/activateSPFeature" },
|
||||
{ "$ref": "#/definitions/associateExtension" },
|
||||
{ "$ref": "#/definitions/addPrincipalToSPGroup" },
|
||||
{ "$ref": "#/definitions/addNavLink" },
|
||||
{ "$ref": "#/definitions/applyTheme" },
|
||||
{ "$ref": "#/definitions/createContentType" },
|
||||
{ "$ref": "#/definitions/createPage" },
|
||||
{ "$ref": "#/definitions/createSiteColumn" },
|
||||
{ "$ref": "#/definitions/createSiteColumnXml" },
|
||||
{ "$ref": "#/definitions/createSPList" },
|
||||
{ "$ref": "#/definitions/installSolution" },
|
||||
{ "$ref": "#/definitions/joinHubSite" },
|
||||
{ "$ref": "#/definitions/removeNavLink" },
|
||||
{ "$ref": "#/definitions/setRegionalSettings" },
|
||||
{ "$ref": "#/definitions/setSiteLogo" },
|
||||
{ "$ref": "#/definitions/setSiteExternalSharingCapability" },
|
||||
{ "$ref": "#/definitions/triggerFlow" }
|
||||
]
|
||||
},
|
||||
"additionalItems": false
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"bindata": {
|
||||
"type": "object",
|
||||
"title": "Binary Data",
|
||||
"description": "guid<->base64encodedstrings key-value pairs",
|
||||
"patternProperties": {
|
||||
"^[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": { "type": "number" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export interface IListViewItems {
|
||||
'key': string;
|
||||
Description: string;
|
||||
Title: string;
|
||||
Id: string;
|
||||
Version?: string;
|
||||
SiteScriptsId?: string[];
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SiteScriptInfo, SiteDesignInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface ISiteScriptsProps {
|
||||
SiteDesignSelectedItem: ISiteDesignSelectedItem;
|
||||
context: WebPartContext;
|
||||
mode: panelMode;
|
||||
onDismiss(refresh?: boolean): void;
|
||||
showPanel: boolean;
|
||||
}
|
||||
|
||||
interface ISiteDesignSelectedItem {
|
||||
key: string;
|
||||
Description: string;
|
||||
Id: string;
|
||||
Title: string;
|
||||
WebTemplate:string;
|
||||
SiteScriptIds: string;
|
||||
numberSiteScripts: number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText: string;
|
||||
PreviewImageUrl: string;
|
||||
Version: string;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { IListViewItems } from './IListViewItems';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
|
||||
export interface ISiteScriptsState{
|
||||
items: IListViewItems[];
|
||||
isLoading:boolean;
|
||||
disableCommandOption:boolean;
|
||||
showPanel:boolean;
|
||||
selectItem: IListViewItems[];
|
||||
panelMode: panelMode;
|
||||
hasError: boolean;
|
||||
errorMessage: string;
|
||||
showPanelAddScript: boolean;
|
||||
showDialogDelete:boolean;
|
||||
deleting:boolean;
|
||||
disableDeleteButton: boolean;
|
||||
showError: boolean;
|
||||
showCommmandEdit: string;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,486 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
//import styles from '../../webparts/siteDesigns/components/SiteDesigns.module.scss';
|
||||
import { ISiteScriptsProps } from './ISiteScriptsProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
|
||||
import { IListViewItems } from './IListViewItems';
|
||||
import spservice from '../../services/spservices';
|
||||
import {
|
||||
Icon,
|
||||
IconType,
|
||||
CommandBar,
|
||||
Panel,
|
||||
PanelType,
|
||||
MessageBar,
|
||||
MessageBarType,
|
||||
Label,
|
||||
Spinner,
|
||||
SpinnerSize,
|
||||
Dialog,
|
||||
DialogType,
|
||||
DialogFooter,
|
||||
PrimaryButton,
|
||||
DefaultButton,
|
||||
|
||||
} from 'office-ui-fabric-react';
|
||||
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { ISiteScriptsState } from './ISiteScriptsState';
|
||||
import { SiteDesignInfo, SiteScriptInfo, SiteScriptUpdateInfo, SiteDesignUpdateInfo } from '@pnp/sp';
|
||||
import { panelMode } from '../../webparts/siteDesigns/components/IEnumPanel';
|
||||
import styles from './siteScript.module.scss';
|
||||
|
||||
// ListView Columns
|
||||
const viewFields: IViewField[] = [
|
||||
{
|
||||
name: 'Image',
|
||||
render: ((item: IListViewItems) => {
|
||||
const image = <Icon iconName="FileCode" />;
|
||||
return image;
|
||||
}),
|
||||
maxWidth: 70,
|
||||
},
|
||||
{
|
||||
name: 'Id',
|
||||
displayName: strings.ListViewColumnIdLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 200
|
||||
},
|
||||
{
|
||||
name: 'Title',
|
||||
displayName: strings.TitleFieldLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
name: 'Description',
|
||||
displayName: strings.ListViewColumnDescriptionLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
name: 'Version',
|
||||
displayName: "Version",
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 65
|
||||
}
|
||||
];
|
||||
|
||||
export default class SiteScripts extends React.Component<ISiteScriptsProps, ISiteScriptsState> {
|
||||
private spService: spservice;
|
||||
private items: IListViewItems[] = [];
|
||||
private refreshParent: boolean = false;
|
||||
private siteScripts: string[];
|
||||
|
||||
private AddSiteScriptToSiteDesignDialog = React.lazy(() => import('../AddSiteScriptToSiteDesign/AddSiteScriptToSiteDesign' /* webpackChunkName: "addscriptdialog" */));
|
||||
private EditScriptDialog = React.lazy(() => import('../../controls/EditSiteScript/EditSiteScript' /* webpackChunkName: "editscriptdialog" */));
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
items: [],
|
||||
isLoading: false,
|
||||
disableCommandOption: true,
|
||||
showPanel: false,
|
||||
selectItem: [],
|
||||
panelMode: panelMode.New,
|
||||
hasError: false,
|
||||
errorMessage: '',
|
||||
showPanelAddScript: false,
|
||||
showDialogDelete: false,
|
||||
deleting: false,
|
||||
disableDeleteButton: false,
|
||||
showError: false,
|
||||
showCommmandEdit: ''
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this.getSelection = this.getSelection.bind(this);
|
||||
this.onNewItem = this.onNewItem.bind(this);
|
||||
this.onEditItem = this.onEditItem.bind(this);
|
||||
this.onDeleteItem = this.onDeleteItem.bind(this);
|
||||
this.onDismissPanel = this.onDismissPanel.bind(this);
|
||||
this.onRefresh = this.onRefresh.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onDismissAddScriptPanel = this.onDismissAddScriptPanel.bind(this);
|
||||
this.onCloseDialog = this.onCloseDialog.bind(this);
|
||||
this.onDeleteConfirm = this.onDeleteConfirm.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} refresh
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private onDismissAddScriptPanel(refresh: boolean) {
|
||||
|
||||
this.setState({ showPanel: false });
|
||||
if (refresh) {
|
||||
this.refreshParent = true;
|
||||
this.loadSiteScripts();
|
||||
}
|
||||
}
|
||||
|
||||
// Get Selection Item from List
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {IListViewItems[]} items
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private getSelection(items: IListViewItems[]) {
|
||||
if (items.length > 0) {
|
||||
|
||||
this.setState({
|
||||
disableCommandOption: false,
|
||||
selectItem: items,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
disableCommandOption: true,
|
||||
selectItem: [],
|
||||
showPanel: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* cancel event option SiteScrips
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private onCancel(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
|
||||
this.props.onDismiss(this.refreshParent);
|
||||
}
|
||||
|
||||
private onCloseDialog(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
this.setState({
|
||||
showDialogDelete: false
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} ev
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private async onDeleteConfirm(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
ev.preventDefault();
|
||||
try {
|
||||
let updateSiteScripts: string[] = this.siteScripts;
|
||||
for (const item of this.state.selectItem) {
|
||||
const idx = updateSiteScripts.indexOf(item.Id);
|
||||
if (idx !== -1) {
|
||||
updateSiteScripts.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
this.setState({ deleting: true, disableDeleteButton: true });
|
||||
const siteDesignUpdateInfo: SiteDesignUpdateInfo = { Id: this.props.SiteDesignSelectedItem.Id, SiteScriptIds: updateSiteScripts };
|
||||
const result = await this.spService.updateSiteDesign(siteDesignUpdateInfo);
|
||||
this.refreshParent = true;
|
||||
this.setState({ deleting: false, disableDeleteButton: false, showDialogDelete: false, showError: false });
|
||||
this.loadSiteScripts();
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
this.setState({ deleting: false, disableDeleteButton: true, showError: true, errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Panel Dismiss CallBack
|
||||
*
|
||||
* @param {boolean} [refresh]
|
||||
* @returns
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
public async onDismissPanel(refresh?: boolean) {
|
||||
this.setState({
|
||||
showPanel: false
|
||||
});
|
||||
if (refresh) {
|
||||
await this.loadSiteScripts();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// On New Item
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private onNewItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.New,
|
||||
showPanel: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On Delete
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private onDeleteItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.Delete,
|
||||
showDialogDelete: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On Edit item
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private onEditItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.edit,
|
||||
showPanel: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SiteScripts
|
||||
*
|
||||
* @private
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
private async loadSiteScripts() {
|
||||
this.items = [];
|
||||
this.setState({ isLoading: true });
|
||||
try {
|
||||
// check if user is Teanant Global Admin
|
||||
const isGlobalAdmin = await this.spService.checkUserIsGlobalAdmin();
|
||||
if (isGlobalAdmin) {
|
||||
// get SiteScripts for SiteDesign
|
||||
const siteDesignInfo: SiteDesignInfo = await this.spService.getSiteDesignMetadata(this.props.SiteDesignSelectedItem.Id);
|
||||
this.siteScripts = siteDesignInfo.SiteScriptIds;
|
||||
|
||||
if (this.siteScripts.length > 0) {
|
||||
for (const siteScriptId of this.siteScripts) {
|
||||
if (siteScriptId === "") continue;
|
||||
const siteScript: SiteScriptInfo = await this.spService.getSiteScriptMetadata(siteScriptId);
|
||||
this.items.push(
|
||||
{
|
||||
key: siteScript.Id,
|
||||
Description: siteScript.Description,
|
||||
Id: siteScript.Id,
|
||||
Title: siteScript.Title,
|
||||
Version: siteScript.Version
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
this.setState({ items: this.items, isLoading: false, disableCommandOption: true });
|
||||
} else {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: strings.ErrorMessageUserNotAdmin,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: error.message,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
/** Refresh
|
||||
*
|
||||
* @param {React.MouseEvent<HTMLElement>} ev
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
public onRefresh(ev: React.MouseEvent<HTMLElement>) {
|
||||
ev.preventDefault();
|
||||
// loadSiteScripts
|
||||
this.loadSiteScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component Did Mount
|
||||
*
|
||||
* @memberof SiteScripts
|
||||
*/
|
||||
public async componentDidMount() {
|
||||
// loadSiteScripts
|
||||
await this.loadSiteScripts();
|
||||
}
|
||||
// On Render
|
||||
public render(): React.ReactElement<ISiteScriptsProps> {
|
||||
return (
|
||||
<div>
|
||||
<Panel isOpen={this.props.showPanel} onDismiss={this.onCancel} type={PanelType.large} headerText="Site Scripts">
|
||||
<div>
|
||||
<span className={styles.label}>SiteDesign Id:</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.Id}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className={styles.label}>Title:</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.Title}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className={styles.label}>WebTemplate:</span>
|
||||
<span className={styles.title}>{this.props.SiteDesignSelectedItem.WebTemplate === '64' ? "Team Site" : "Communication Site"}</span>
|
||||
</div>
|
||||
<br />
|
||||
{
|
||||
this.state.isLoading ?
|
||||
<Spinner size={SpinnerSize.large} label={strings.LoadingLabel} ariaLive="assertive" />
|
||||
:
|
||||
this.state.hasError ?
|
||||
<MessageBar
|
||||
messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
:
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<CommandBar
|
||||
items={[
|
||||
{
|
||||
key: 'newItem',
|
||||
name: strings.CommandbarNewLabel,
|
||||
iconProps: {
|
||||
iconName: 'Add'
|
||||
},
|
||||
onClick: this.onNewItem,
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
name: strings.CommandbarEditLabel,
|
||||
iconProps: {
|
||||
iconName: 'Edit'
|
||||
},
|
||||
onClick: this.onEditItem,
|
||||
disabled: this.state.selectItem.length ===0 ? true : this.state.selectItem.length > 1 ? true : false,
|
||||
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
name: strings.CommandbarDeleteLabel,
|
||||
iconProps: {
|
||||
iconName: 'Delete'
|
||||
},
|
||||
onClick: this.onDeleteItem,
|
||||
disabled: this.state.disableCommandOption,
|
||||
}
|
||||
]}
|
||||
farItems={[
|
||||
{
|
||||
key: 'refresh',
|
||||
name: strings.CommandbarRefreshLabel,
|
||||
iconProps: {
|
||||
iconName: 'Refresh'
|
||||
},
|
||||
onClick: this.onRefresh,
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
!this.state.hasError && !this.state.isLoading &&
|
||||
<ListView
|
||||
items={this.state.items}
|
||||
viewFields={viewFields}
|
||||
compact={false}
|
||||
selectionMode={SelectionMode.multiple}
|
||||
selection={this.getSelection}
|
||||
showFilter={true}
|
||||
filterPlaceHolder={strings.SearchPlaceholder}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.New &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.AddSiteScriptToSiteDesignDialog
|
||||
showPanel={this.state.showPanel}
|
||||
onDismiss={this.onDismissAddScriptPanel}
|
||||
context={this.props.context}
|
||||
siteDesignInfo={this.props.SiteDesignSelectedItem}
|
||||
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.edit &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.EditScriptDialog
|
||||
hideDialog={!this.state.showPanel}
|
||||
onDismiss={this.onDismissAddScriptPanel}
|
||||
context={this.props.context}
|
||||
siteScriptId={this.state.selectItem[0].Id}
|
||||
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
<Dialog
|
||||
hidden={!this.state.showDialogDelete}
|
||||
onDismiss={this.onCloseDialog}
|
||||
|
||||
dialogContentProps={{
|
||||
type: DialogType.normal,
|
||||
title: strings.DeleteSiteScriptDialogConfirmTitle,
|
||||
}}
|
||||
modalProps={{
|
||||
isBlocking: true,
|
||||
|
||||
}}
|
||||
>
|
||||
<p>{strings.DeleteSiteScriptDialogConfirmText}</p>
|
||||
<br />
|
||||
{
|
||||
this.state.showError &&
|
||||
<div style={{ marginTop: '15px' }}>
|
||||
<MessageBar messageBarType={MessageBarType.error} >
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar>
|
||||
</div>
|
||||
}
|
||||
<br />
|
||||
<DialogFooter>
|
||||
{
|
||||
this.state.deleting &&
|
||||
<div style={{ display: "inline-block", marginRight: '10px', verticalAlign: 'middle' }}>
|
||||
<Spinner size={SpinnerSize.small} ariaLive="assertive" />
|
||||
</div>
|
||||
}
|
||||
<DefaultButton onClick={this.onDeleteConfirm} text={strings.ButtonDeleteLabel} disabled={this.state.disableDeleteButton} />
|
||||
<PrimaryButton onClick={this.onCloseDialog} text={strings.ButtonCancelLabel} />
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
</Panel>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||
.title {
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
}
|
||||
.label {
|
||||
vertical-align: top;
|
||||
margin-right: 15px;
|
||||
display: inline-block;
|
||||
@include ms-font-m;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
@include ms-font-l;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,7 @@
|
|||
export interface IAddSiteDesignTaskToCurrentWebResult {
|
||||
ID: string;
|
||||
LogonName: string;
|
||||
SiteDesignID: string;
|
||||
SiteID: string;
|
||||
WebID:string;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface ISiteDesignTaskResult {
|
||||
"@odata.null"?: boolean;
|
||||
ID: string;
|
||||
LogonName: string;
|
||||
SiteDesignID: string;
|
||||
}
|
|
@ -0,0 +1,386 @@
|
|||
// João Mendes
|
||||
// March 2019
|
||||
|
||||
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||
import { sp, Web, SiteDesignInfo, SiteScriptInfo, SiteScripts, SiteDesignCreationInfo, SiteDesignUpdateInfo, SiteDesignPrincipals, SiteScriptUpdateInfo, SearchResults, } from '@pnp/sp';
|
||||
import { graph, } from "@pnp/graph";
|
||||
import { SPHttpClient, SPHttpClientResponse, ISPHttpClientOptions, HttpClient } from '@microsoft/sp-http';
|
||||
import { ISiteScript } from '../types/ISiteScript';
|
||||
import SiteDesignRights from "../controls/SiteDesignRights/SiteDesignRights";
|
||||
import { IAddSiteDesignTaskToCurrentWebResult } from './IAddSiteDesignTaskToCurrentWebResult';
|
||||
import { ISiteDesignTaskResult } from './ISiteDesignTaskResult';
|
||||
import * as $ from 'jquery';
|
||||
|
||||
const ADMIN_ROLETEMPLATE_ID = "62e90394-69f5-4237-9190-012177145e10"; // Global Admin TemplateRoleId
|
||||
// Class Services
|
||||
export default class spservices {
|
||||
private appCatalogUrl: string = '';
|
||||
constructor(private context: WebPartContext) {
|
||||
// Setuo Context to PnPjs and MSGraph
|
||||
sp.setup({
|
||||
spfxContext: this.context
|
||||
});
|
||||
|
||||
graph.setup({
|
||||
spfxContext: this.context
|
||||
});
|
||||
|
||||
this.onInit();
|
||||
}
|
||||
// OnInit Function
|
||||
private async onInit() {
|
||||
this.appCatalogUrl = await this.getAppCatalogUrl();
|
||||
}
|
||||
|
||||
// Get App Catalog
|
||||
private async getAppCatalogUrl() {
|
||||
try {
|
||||
const webAbsoluteUrl = this.context.pageContext.web.absoluteUrl;
|
||||
const apiUrl = `${webAbsoluteUrl}/_api/SP_TenantSettings_Current`;
|
||||
|
||||
const data: SPHttpClientResponse = await this.context.spHttpClient.get(apiUrl, SPHttpClient.configurations.v1);
|
||||
if (data.ok) {
|
||||
const results = await data.json();
|
||||
if (results) {
|
||||
return results.CorporateCatalogUrl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.dir(error);
|
||||
return Promise.reject(error.message);
|
||||
}
|
||||
}
|
||||
// Check if user is Global Admin
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public async checkUserIsGlobalAdmin() {
|
||||
const myDirRolesAndGroups: any[] = await graph.me.memberOf.get();
|
||||
for (const myDirRolesAndGroup of myDirRolesAndGroups) {
|
||||
if (myDirRolesAndGroup.roleTemplateId && myDirRolesAndGroup.roleTemplateId === ADMIN_ROLETEMPLATE_ID) { // roleTemplateId for glabal Admin
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Get List of Site Designs
|
||||
*
|
||||
* @returns results[]
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteDesigns() {
|
||||
let result: SiteDesignInfo[] = [];
|
||||
try {
|
||||
result = await sp.siteDesigns.getSiteDesigns();
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Return Site Scripts
|
||||
*
|
||||
* @returns array os siteScripts
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteScripts() {
|
||||
let results: SiteScriptInfo[] = [];
|
||||
try {
|
||||
results = await sp.siteScripts.getSiteScripts();
|
||||
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Site Script by Id
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns {SiteScriptInfo}
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteScriptMetadata(id: string) {
|
||||
let results: SiteScriptInfo = null;
|
||||
try {
|
||||
results = await sp.siteScripts.getSiteScriptMetadata(id);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GetSiteDesignMetaData
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteDesignMetadata(id: string) {
|
||||
let results: SiteDesignInfo = null;
|
||||
try {
|
||||
results = await sp.siteDesigns.getSiteDesignMetadata(id);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a SiteScript
|
||||
*
|
||||
* @param {string} title
|
||||
* @param {*} description
|
||||
* @param {string} sitescript
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async createSiteScript(title: string, description, siteScript: ISiteScript) {
|
||||
let results: SiteScriptInfo = null;
|
||||
try {
|
||||
results = await sp.siteScripts.createSiteScript(title, description, siteScript);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {SiteDesignInfo} siteDesignInfo
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async createSiteDesign(siteDesignInfo: SiteDesignCreationInfo) {
|
||||
let results: SiteDesignCreationInfo = null;
|
||||
try {
|
||||
results = await sp.siteDesigns.createSiteDesign(siteDesignInfo);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {SiteDesignUpdateInfo} siteDesignInfo
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async updateSiteDesign(siteDesignInfo: SiteDesignUpdateInfo) {
|
||||
let results: SiteDesignInfo = null;
|
||||
try {
|
||||
results = await sp.siteDesigns.updateSiteDesign(siteDesignInfo);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {SiteDesignUpdateInfo} siteDesignInfo
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async deleteSiteDesign(siteDesignInfo: SiteDesignUpdateInfo) {
|
||||
try {
|
||||
await sp.siteDesigns.deleteSiteDesign(siteDesignInfo.Id);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @param {string} siteDesignId
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteDesignRights(siteDesignId: string) {
|
||||
let results: SiteDesignPrincipals[] = null;
|
||||
try {
|
||||
results = await sp.siteDesigns.getSiteDesignRights(siteDesignId);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public async updateSiteScript(siteScriptInfo: SiteScriptUpdateInfo) {
|
||||
let results: SiteScriptInfo = null;
|
||||
try {
|
||||
results = await sp.siteScripts.updateSiteScript(siteScriptInfo);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {string} siteDesignId
|
||||
* @param {string[]} principals
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async grantSiteDesignRights(siteDesignId: string, principals: string[]) {
|
||||
|
||||
try {
|
||||
await sp.siteDesigns.grantSiteDesignRights(siteDesignId, principals);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {string} siteDesignId
|
||||
* @param {string[]} principals
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async revokeSiteDesignRights(siteDesignId: string, principals: string[]) {
|
||||
try {
|
||||
await sp.siteDesigns.revokeSiteDesignRights(siteDesignId, principals);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {string} value
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSites(value: string) {
|
||||
let results: SearchResults = null;
|
||||
try {
|
||||
|
||||
results = await sp.search(`${value} AND contentclass:STS_Site`);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {string} webUrl
|
||||
* @param {string} siteDesignId
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async AddSiteDesignTask(webUrl: string, siteDesignId: string) {
|
||||
const webAbsoluteUrl = this.context.pageContext.web.absoluteUrl;
|
||||
|
||||
try {
|
||||
const spOpts: ISPHttpClientOptions = {
|
||||
body: `{"siteDesignId":"${siteDesignId}","webUrl":${webUrl}}`
|
||||
};
|
||||
|
||||
const formDigest = await this.getRequestDigest();
|
||||
const apiUrl = `${webAbsoluteUrl}/_api/microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.AddSiteDesignTask`;
|
||||
|
||||
const results = await $.ajax({
|
||||
url: apiUrl,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: `{"siteDesignId":"${siteDesignId}","webUrl":"${webUrl}"}`,
|
||||
headers: {
|
||||
'content-type': 'application/json;charset=utf-8',
|
||||
'accept': 'application/json;odata=nometadata',
|
||||
'X-RequestDigest': formDigest
|
||||
}
|
||||
});
|
||||
// const data: SPHttpClientResponse = await this.context.spHttpClient.post(apiUrl, SPHttpClient.configurations.v1,spOpts);
|
||||
|
||||
if (results && results) {
|
||||
return results;
|
||||
}
|
||||
} catch (error) {
|
||||
console.dir(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} webUrl
|
||||
* @param {string} taskId
|
||||
* @returns
|
||||
* @memberof spservices
|
||||
*/
|
||||
public async getSiteDesignTask(webUrl: string, runTaskId: string): Promise<ISiteDesignTaskResult> {
|
||||
try {
|
||||
|
||||
const spOpts: ISPHttpClientOptions = {
|
||||
body: `{ "taskId": "${runTaskId}"}`
|
||||
};
|
||||
|
||||
const apiUrl = `${webUrl}/_api/microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignTask`;
|
||||
|
||||
const data: SPHttpClientResponse = await this.context.spHttpClient.post(apiUrl, SPHttpClient.configurations.v1, spOpts);
|
||||
if (data.ok) { // Testar sucesso diferente 200 e lançar erro
|
||||
const results: ISiteDesignTaskResult = await data.json();
|
||||
if (results) {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.dir(error);
|
||||
return Promise.reject(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async getRequestDigest(){
|
||||
try {
|
||||
|
||||
const webAbsoluteUrl = this.context.pageContext.web.absoluteUrl;
|
||||
const spOpts: ISPHttpClientOptions = {
|
||||
};
|
||||
const apiUrl = `${webAbsoluteUrl}/_api/contextinfo`;
|
||||
|
||||
const data: SPHttpClientResponse = await this.context.spHttpClient.post(apiUrl, SPHttpClient.configurations.v1, null);
|
||||
if (data.ok) {
|
||||
const results = await data.json();
|
||||
if (results) {
|
||||
return results.FormDigestValue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.dir(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
export interface ISiteScript {
|
||||
$schema: string;
|
||||
actions: IAction[];
|
||||
bindata: object;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface IAction {
|
||||
verb: string;
|
||||
[key: string]: any;
|
||||
subactions?: ISubaction[];
|
||||
}
|
||||
export interface ISubaction {
|
||||
verb: string;
|
||||
[key: string]: any;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
declare module '@dr-kobros/react-jsoneditor' {
|
||||
import * as react from 'react';
|
||||
export default class JsonEditor extends React.PureComponent<JsonEditorProps, any> {
|
||||
}
|
||||
export interface JsonEditorProps {
|
||||
onChange:(json:any)=>void;
|
||||
onDirty:(json:any)=>void;
|
||||
value:object;
|
||||
options:any;
|
||||
width:string;
|
||||
height:string;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
declare module 'jsoneditor' {
|
||||
import * as react from 'react';
|
||||
export default class JSONEditor {
|
||||
constructor(container: HTMLElement, options:JsonEditorOptions)
|
||||
get():any;
|
||||
set(value:object):any;
|
||||
destroy():any;
|
||||
}
|
||||
export interface JsonEditorOptions {
|
||||
onChange:()=>void;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "08bc7d85-ef3a-492d-89c5-a7f0048fc2ec",
|
||||
"alias": "SiteDesignsWebPart",
|
||||
"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": "Site Designs" },
|
||||
"description": { "default": "Manage Site Designs" },
|
||||
"officeFabricIconFontName": "Design",
|
||||
"properties": {
|
||||
"title": "Manage Site Designs"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
import {
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneTextField
|
||||
} from '@microsoft/sp-property-pane';
|
||||
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import SiteDesigns from './components/SiteDesigns';
|
||||
import { ISiteDesignsProps } from './components/ISiteDesignsProps';
|
||||
|
||||
export interface ISiteDesignsWebPartProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
export default class SiteDesignsWebPart extends BaseClientSideWebPart<ISiteDesignsWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<ISiteDesignsProps> = React.createElement(
|
||||
SiteDesigns,
|
||||
{
|
||||
title: this.properties.title,
|
||||
context: this.context,
|
||||
displayMode: this.displayMode,
|
||||
updateProperty: (value: string) => {
|
||||
this.properties.title = value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected onDispose(): void {
|
||||
ReactDom.unmountComponentAtNode(this.domElement);
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('title', {
|
||||
label: 'Title'
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export enum panelMode {
|
||||
"New",
|
||||
"edit",
|
||||
"Delete",
|
||||
"Apply",
|
||||
"Rights",
|
||||
"SiteScripts"
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
export interface IListViewItems {
|
||||
key: string;
|
||||
Description: string;
|
||||
PreviewImageUrl: string;
|
||||
SiteScriptIds: string;
|
||||
Title: string;
|
||||
WebTemplate: string;
|
||||
Id: string;
|
||||
numberSiteScripts:number;
|
||||
IsDefault: boolean;
|
||||
PreviewImageAltText:string;
|
||||
Version: string;
|
||||
runStatus: boolean;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import { IListViewItems } from '../components/IListViewItems';
|
||||
import { panelMode } from './IEnumPanel';
|
||||
import { SiteDesignInfo } from '@pnp/sp';
|
||||
export interface ISiteDesignState{
|
||||
items: IListViewItems[];
|
||||
isLoading:boolean;
|
||||
disableCommandOption:boolean;
|
||||
showPanel:boolean;
|
||||
selectItem: IListViewItems;
|
||||
panelMode: panelMode;
|
||||
hasError: boolean;
|
||||
errorMessage: string;
|
||||
siteDesignRunning:boolean;
|
||||
siteDesignRunningMessage: string[];
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
export interface ISiteDesignsProps {
|
||||
title: string;
|
||||
context: WebPartContext;
|
||||
displayMode:DisplayMode;
|
||||
updateProperty(value:string):void;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||
|
||||
.siteDesigns {
|
||||
margin: 0 auto;
|
||||
width: calc(100% - 50px) !important;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
.webPartTitle{
|
||||
margin-top: 25px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.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-size: 20px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.siteDesignRunningMessage {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.siteDesignRunningMessageLink {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.commandBar {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,561 @@
|
|||
|
||||
// João Mendes
|
||||
// Mar 2019
|
||||
//
|
||||
import * as React from 'react';
|
||||
import styles from './SiteDesigns.module.scss';
|
||||
import { ISiteDesignsProps } from './ISiteDesignsProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
|
||||
import { IListViewItems } from '../components/IListViewItems';
|
||||
import spservice from '../../../services/spservices';
|
||||
import { Icon, IconType } from 'office-ui-fabric-react/lib/Icon';
|
||||
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
||||
import { panelMode } from './IEnumPanel';
|
||||
import {
|
||||
MessageBar,
|
||||
MessageBarType,
|
||||
Spinner,
|
||||
SpinnerSize,
|
||||
Dialog,
|
||||
DialogType,
|
||||
DialogFooter,
|
||||
ImageFit,
|
||||
PrimaryButton,
|
||||
Link
|
||||
} from 'office-ui-fabric-react';
|
||||
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
||||
import * as strings from 'SiteDesignsWebPartStrings';
|
||||
import { ISiteDesignState } from './ISiteDesignState';
|
||||
import { SiteDesignInfo, Item } from '@pnp/sp';
|
||||
import { IAddSiteDesignTaskToCurrentWebResult } from '../../../services/IAddSiteDesignTaskToCurrentWebResult';
|
||||
|
||||
//import { SiteScripts } from './../../../controls/sitescripts/SiteScripts';
|
||||
|
||||
|
||||
// ListView Columns
|
||||
const viewFields: IViewField[] = [
|
||||
{
|
||||
name: 'Image',
|
||||
render: ((item: IListViewItems) => {
|
||||
let image;
|
||||
item.PreviewImageUrl ?
|
||||
image = <Icon iconType={IconType.image} imageProps={{ src: item.PreviewImageUrl, imageFit: ImageFit.cover }} /> :
|
||||
image = <Icon iconName="FileImage" />;
|
||||
return image;
|
||||
}),
|
||||
maxWidth: 70,
|
||||
},
|
||||
{
|
||||
name: 'Id',
|
||||
displayName: strings.ListViewColumnIdLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 200
|
||||
},
|
||||
{
|
||||
name: 'Title',
|
||||
displayName: strings.TitleFieldLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
name: 'Description',
|
||||
displayName: strings.ListViewColumnDescriptionLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
name: 'WebTemplate',
|
||||
displayName: strings.ListViewColumnWebTemplateLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 65
|
||||
},
|
||||
{
|
||||
name: 'numberSiteScripts',
|
||||
displayName: strings.ListViewColumnNumberSiteScriptsLabel,
|
||||
sorting: true,
|
||||
isResizable: true,
|
||||
maxWidth: 60
|
||||
}
|
||||
];
|
||||
export default class SiteDesigns extends React.Component<ISiteDesignsProps, ISiteDesignState> {
|
||||
private spService: spservice;
|
||||
private items: IListViewItems[];
|
||||
private siteDesignsRunStatus: { addSiteDesignTaskResult: IAddSiteDesignTaskToCurrentWebResult, siteUrl: string }[] = [];
|
||||
|
||||
private SiteScriptsList = React.lazy(() => import('../../../controls/siteScripts/SiteScripts' /* webpackChunkName: "sitescriptslist" */));
|
||||
private AddSiteDesign = React.lazy(() => import('./../../../controls/AddSiteDesign/AddSiteDesign' /* webpackChunkName: "addsitedesign" */));
|
||||
private EditSiteDesign = React.lazy(() => import('./../../../controls/EditSiteDesign/EditSiteDesign' /* webpackChunkName: "editsitedesign" */));
|
||||
private DeleteSiteDesign = React.lazy(() => import('./../../../controls/DeleteSiteDesign/DeleteSiteDesign' /* webpackChunkName: "deletesitedesign" */));
|
||||
private SiteDesignRights = React.lazy(() => import('./../../../controls/SiteDesignRights/SiteDesignRights' /* webpackChunkName: "sitedesignrights" */));
|
||||
private ApplySiteDesign = React.lazy(() => import('./../../../controls/ApplySiteDesign/ApplySiteDesign' /* webpackChunkName: "applysitedesign" */));
|
||||
|
||||
public constructor(props) {
|
||||
super(props);
|
||||
// Initialize state
|
||||
this.state = ({
|
||||
items: [],
|
||||
isLoading: false,
|
||||
disableCommandOption: true,
|
||||
showPanel: false,
|
||||
selectItem: null,
|
||||
panelMode: panelMode.New,
|
||||
hasError: false,
|
||||
errorMessage: '',
|
||||
siteDesignRunning: false,
|
||||
siteDesignRunningMessage: []
|
||||
});
|
||||
// Init class services
|
||||
this.spService = new spservice(this.props.context);
|
||||
// Register event handlers
|
||||
this._getSelection = this._getSelection.bind(this);
|
||||
this.onNewItem = this.onNewItem.bind(this);
|
||||
this.onEditItem = this.onEditItem.bind(this);
|
||||
this.onDeleteItem = this.onDeleteItem.bind(this);
|
||||
this.onApplyItem = this.onApplyItem.bind(this);
|
||||
this.onRights = this.onRights.bind(this);
|
||||
this.onSiteScripts = this.onSiteScripts.bind(this);
|
||||
this.onDismissPanel = this.onDismissPanel.bind(this);
|
||||
this.onRefresh = this.onRefresh.bind(this);
|
||||
this.onDismissApplyPanel = this.onDismissApplyPanel.bind(this);
|
||||
}
|
||||
// Get Selection Item from List
|
||||
private _getSelection(items: IListViewItems[]) {
|
||||
if (items.length > 0) {
|
||||
this.setState({
|
||||
disableCommandOption: false,
|
||||
selectItem: items[0]
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
disableCommandOption: true,
|
||||
selectItem: null,
|
||||
showPanel: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {IAddSiteDesignTaskToCurrentWebResult[]} siteDesignsRunning
|
||||
* @param {boolean} [refresh]
|
||||
* @returns
|
||||
* @memberof SiteDesigns
|
||||
*/
|
||||
public async onDismissApplyPanel(siteDesignsRunning: { addSiteDesignTaskResult: IAddSiteDesignTaskToCurrentWebResult, siteUrl: string }[], refresh?: boolean) {
|
||||
let isRunning: boolean = false;
|
||||
let totalRunningSiteDesigns: number = 0;
|
||||
let siteDesignRunningMessage: string[] = [`The Site Design ${siteDesignsRunning[0].addSiteDesignTaskResult.SiteDesignID} is beeing applyed ...`];
|
||||
if (siteDesignsRunning && siteDesignsRunning.length > 0) {
|
||||
|
||||
totalRunningSiteDesigns = siteDesignsRunning.length;
|
||||
this.siteDesignsRunStatus = siteDesignsRunning;
|
||||
this.setState({
|
||||
siteDesignRunning: true,
|
||||
siteDesignRunningMessage: siteDesignRunningMessage
|
||||
});
|
||||
const runTimer = setInterval(async () => {
|
||||
|
||||
siteDesignRunningMessage = [];
|
||||
siteDesignRunningMessage = [`The Site Design :${siteDesignsRunning[0].addSiteDesignTaskResult.SiteDesignID} was applyed.`];
|
||||
for (const siteDesignApplyed of siteDesignsRunning) {
|
||||
isRunning = true;
|
||||
|
||||
const result = await this.spService.getSiteDesignTask(siteDesignApplyed.siteUrl, siteDesignApplyed.addSiteDesignTaskResult.ID);
|
||||
isRunning = !result['@odata.null'] ? true : false;
|
||||
|
||||
if (!isRunning) {
|
||||
|
||||
totalRunningSiteDesigns = totalRunningSiteDesigns - 1;
|
||||
siteDesignRunningMessage.push(` site: ${siteDesignApplyed.siteUrl} : Applyed`);
|
||||
|
||||
} else {
|
||||
|
||||
siteDesignRunningMessage.push(`site: ${siteDesignApplyed.siteUrl} : Applying...`);
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
if (totalRunningSiteDesigns <= 0) {
|
||||
clearInterval(runTimer);
|
||||
this.setState({
|
||||
siteDesignRunning: true,
|
||||
siteDesignRunningMessage: siteDesignRunningMessage
|
||||
});
|
||||
}
|
||||
}
|
||||
, 5000);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
showPanel: false
|
||||
});
|
||||
if (refresh) {
|
||||
await this.loadSiteDesignsProperties();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Panel Dismiss CallBack
|
||||
// @param refresh refresh list?
|
||||
public async onDismissPanel(refresh?: boolean) {
|
||||
this.setState({
|
||||
showPanel: false
|
||||
});
|
||||
if (refresh) {
|
||||
await this.loadSiteDesignsProperties();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// On New Item
|
||||
private onNewItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.New,
|
||||
showPanel: true,
|
||||
});
|
||||
}
|
||||
// On Delete
|
||||
private onDeleteItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.Delete,
|
||||
showPanel: true,
|
||||
});
|
||||
}
|
||||
// On Edit item
|
||||
private onEditItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.edit,
|
||||
showPanel: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On Appply item
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteDesigns
|
||||
*/
|
||||
private onApplyItem(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.Apply,
|
||||
showPanel: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On Rights Event
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteDesigns
|
||||
*/
|
||||
private onRights(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.Rights,
|
||||
showPanel: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On SiteScripts
|
||||
*
|
||||
* @private
|
||||
* @param {React.MouseEvent<HTMLElement>} e
|
||||
* @memberof SiteDesigns
|
||||
*/
|
||||
private onSiteScripts(e: React.MouseEvent<HTMLElement>) {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
panelMode: panelMode.SiteScripts,
|
||||
showPanel: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private checkSiteDesignRunTask(siteDesignApplyedInfo: IAddSiteDesignTaskToCurrentWebResult) {
|
||||
try {
|
||||
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @private
|
||||
* @memberof SiteDesigns
|
||||
*/
|
||||
private async loadSiteDesignsProperties() {
|
||||
this.items = [];
|
||||
this.setState({ isLoading: true });
|
||||
try {
|
||||
// check if user is Teanant Global Admin
|
||||
const isGlobalAdmin = await this.spService.checkUserIsGlobalAdmin();
|
||||
if (isGlobalAdmin) {
|
||||
// Get Tenant Properties
|
||||
const siteDesigns: SiteDesignInfo[] = await this.spService.getSiteDesigns();
|
||||
for (const siteDesign of siteDesigns) {
|
||||
this.items.push(
|
||||
{
|
||||
key: siteDesign.Id,
|
||||
Description: siteDesign.Description,
|
||||
Id: siteDesign.Id,
|
||||
Title: siteDesign.Title,
|
||||
WebTemplate: siteDesign.WebTemplate,
|
||||
SiteScriptIds: siteDesign.SiteScriptIds.toString(),
|
||||
numberSiteScripts: siteDesign.SiteScriptIds.length,
|
||||
IsDefault: siteDesign.IsDefault,
|
||||
PreviewImageAltText: siteDesign.PreviewImageAltText,
|
||||
PreviewImageUrl: siteDesign.PreviewImageUrl,
|
||||
Version: siteDesign.Version,
|
||||
runStatus: false
|
||||
}
|
||||
);
|
||||
}
|
||||
this.setState({ items: this.items, isLoading: false, disableCommandOption: true });
|
||||
} else {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: strings.ErrorMessageUserNotAdmin,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
this.setState({
|
||||
items: this.items,
|
||||
hasError: true,
|
||||
errorMessage: error.message,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
// Refresh
|
||||
public onRefresh(ev: React.MouseEvent<HTMLElement>) {
|
||||
ev.preventDefault();
|
||||
// LoadTenantProperties
|
||||
this.loadSiteDesignsProperties();
|
||||
}
|
||||
// Component Did Mount
|
||||
public async componentDidMount() {
|
||||
// LoadTenantProperties
|
||||
await this.loadSiteDesignsProperties();
|
||||
}
|
||||
// On Render
|
||||
public render(): React.ReactElement<ISiteDesignsProps> {
|
||||
return (
|
||||
<div className={styles.siteDesigns}>
|
||||
<WebPartTitle displayMode={this.props.displayMode}
|
||||
title={this.props.title}
|
||||
className={styles.webPartTitle}
|
||||
updateProperty={this.props.updateProperty} />
|
||||
{
|
||||
this.state.isLoading ?
|
||||
<Spinner size={SpinnerSize.large} label={strings.LoadingLabel} ariaLive="assertive" />
|
||||
:
|
||||
this.state.hasError ?
|
||||
<MessageBar
|
||||
messageBarType={MessageBarType.error}>
|
||||
<span>{this.state.errorMessage}</span>
|
||||
</MessageBar >
|
||||
:
|
||||
this.state.siteDesignRunning ?
|
||||
<MessageBar
|
||||
truncated={true}
|
||||
isMultiline={false}
|
||||
onDismiss={ (ev) => {this.setState({siteDesignRunning: false});}}
|
||||
messageBarType={MessageBarType.info}
|
||||
styles={{
|
||||
root: {
|
||||
background: 'rgba(113, 175, 229, 0.2)',
|
||||
color: '#00188f'
|
||||
},
|
||||
icon: {
|
||||
color: '#00188f'
|
||||
}
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.state.siteDesignRunningMessage.map((message) =>{
|
||||
return (
|
||||
<span>{message}<br/></span>
|
||||
);
|
||||
})
|
||||
|
||||
}
|
||||
</MessageBar>
|
||||
:
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!this.state.hasError && !this.state.isLoading &&
|
||||
< div className={styles.commandBar}>
|
||||
<CommandBar
|
||||
items={[
|
||||
{
|
||||
key: 'newItem',
|
||||
name: strings.CommandbarNewLabel,
|
||||
iconProps: {
|
||||
iconName: 'Add'
|
||||
},
|
||||
onClick: this.onNewItem,
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
name: strings.CommandbarEditLabel,
|
||||
iconProps: {
|
||||
iconName: 'Edit'
|
||||
},
|
||||
onClick: this.onEditItem,
|
||||
disabled: this.state.disableCommandOption,
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
name: strings.CommandbarDeleteLabel,
|
||||
iconProps: {
|
||||
iconName: 'Delete'
|
||||
},
|
||||
onClick: this.onDeleteItem,
|
||||
disabled: this.state.disableCommandOption,
|
||||
},
|
||||
{
|
||||
key: 'apply',
|
||||
name: strings.CommandbarApplyLabel,
|
||||
iconProps: {
|
||||
iconName: 'Play'
|
||||
},
|
||||
onClick: this.onApplyItem,
|
||||
disabled: this.state.disableCommandOption,
|
||||
},
|
||||
{
|
||||
key: 'rights',
|
||||
name: strings.CommandbarRightsLabel,
|
||||
iconProps: {
|
||||
iconName: 'Permissions'
|
||||
},
|
||||
onClick: this.onRights,
|
||||
disabled: this.state.disableCommandOption,
|
||||
},
|
||||
{
|
||||
key: 'sitescripts',
|
||||
name: strings.CommandbarSiteScriptsLabel,
|
||||
iconProps: {
|
||||
iconName: 'FileCode'
|
||||
},
|
||||
onClick: this.onSiteScripts,
|
||||
disabled: this.state.disableCommandOption,
|
||||
}
|
||||
]}
|
||||
farItems={[
|
||||
{
|
||||
key: 'refresh',
|
||||
name: strings.CommandbarRefreshLabel,
|
||||
iconProps: {
|
||||
iconName: 'Refresh'
|
||||
},
|
||||
onClick: this.onRefresh,
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
!this.state.hasError && !this.state.isLoading &&
|
||||
<ListView
|
||||
items={this.state.items}
|
||||
viewFields={viewFields}
|
||||
compact={false}
|
||||
selectionMode={SelectionMode.single}
|
||||
selection={this._getSelection}
|
||||
showFilter={true}
|
||||
filterPlaceHolder={strings.SearchPlaceholder}
|
||||
/>
|
||||
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.SiteScripts &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.SiteScriptsList
|
||||
mode={this.state.panelMode}
|
||||
SiteDesignSelectedItem={this.state.selectItem}
|
||||
onDismiss={this.onDismissPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.New &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.AddSiteDesign
|
||||
mode={this.state.panelMode}
|
||||
onDismiss={this.onDismissPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.edit &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.EditSiteDesign
|
||||
mode={this.state.panelMode}
|
||||
onDismiss={this.onDismissPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
siteDesignInfo={this.state.selectItem}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.Delete &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.DeleteSiteDesign
|
||||
mode={this.state.panelMode}
|
||||
onDismiss={this.onDismissPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
siteDesignInfo={this.state.selectItem}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.Rights &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.SiteDesignRights
|
||||
mode={this.state.panelMode}
|
||||
onDismiss={this.onDismissPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
SiteDesignSelectedItem={this.state.selectItem}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
{
|
||||
this.state.showPanel && this.state.panelMode == panelMode.Apply &&
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<this.ApplySiteDesign
|
||||
onDismiss={this.onDismissApplyPanel}
|
||||
showPanel={this.state.showPanel}
|
||||
context={this.props.context}
|
||||
siteDesignInfo={this.state.selectItem}
|
||||
/>
|
||||
</React.Suspense>
|
||||
}
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
define([], function() {
|
||||
return {
|
||||
DeleteSiteScriptDialogConfirmText: "Please confirm delete of Site Scripts",
|
||||
DeleteSiteScriptDialogConfirmTitle: "Delete Site Scripts?",
|
||||
JSONSchemaNotValidMessage: "JSON Schema has errors or not valid",
|
||||
EditSiteDesignPanelButtonCancelText: "Cancel",
|
||||
EditSiteDesignPanelButtonSaveText: "Save",
|
||||
DeleteSiteDesignPanelTitle: "Delete Site Design",
|
||||
DeleteSiteDesignPanelButtonCanceltext: "Cancel",
|
||||
DeleteSiteDesignPanelButtonDeleteText: "Delete",
|
||||
AddSiteScriptToSiteDesignPanelButtonCancelText: "Cancel",
|
||||
AddSiteScriptToSiteDesignPanelButtonSaveText: "Save",
|
||||
AddSiteScriptPanelButtonCancelText: "Cancel",
|
||||
AddSiteScriptPanelButtonSave: "Save",
|
||||
AddPrincipalPanelButtonCancelText: "Cancel",
|
||||
AddPrincipalPanelButtonSaveText: "Save",
|
||||
AddSiteDesignPanelDropDownLabel: "Site Scripts",
|
||||
AddSiteDesignPanelDropDownPlaceholderText: "Select Site Script",
|
||||
AddSiteDesignPanelButtonCancelText: "Cancel",
|
||||
AddSiteDesignPanelButtonSaveText: "Save",
|
||||
AddSiteDesignPanelScriptOrderInfo: "SiteScripts will run in the order they are selected",
|
||||
AddSiteDesignPanelActionButtonText: " Add SiteScript",
|
||||
AddSiteDesignPanelTitleErrorMessage: "Site Design title is required",
|
||||
SearchBoxPlaceholderText: "Please search for sites to apply",
|
||||
EditSiteScriptPanelButtonCancel: "Cancel",
|
||||
EditSiteScriptSaveButtonLabel: "Save",
|
||||
ApplyPanelTitle: "Apply Site Design",
|
||||
ApplyPanelButtonCancelLabel: "Cancel",
|
||||
ApplyPanelApplyButtonLabel: "Apply",
|
||||
siteDesignRunningMessage: "There are Site Designs been applyed...",
|
||||
WebSiteUrl: "Web Url",
|
||||
WebSiteTitleLabel: "Web Title",
|
||||
actionButtonTitle: "Add Site Script",
|
||||
ButtonCancelLabel: "Cancel",
|
||||
ButtonDeleteLabel: "Delete",
|
||||
DropDownSelectSiteScriptLabel: "Site Scripts",
|
||||
DropDownSelectSiteScriptPlaceHolder: "Select Site Script",
|
||||
AddSiteScriptToSiteDesignPanelTitle: "Add SiteScript to SiteDesign",
|
||||
AddSiteScriptDialogSubText: "Please specify JSON Definitions",
|
||||
JSONSchemaErrorMessage: "JSON Schema has errors or not valid",
|
||||
DialogConfirmDeleteText: "Please confirm revoke of Site Design Rights ",
|
||||
DialogConfirmDeleteTitle: "Revoke Site Design Rights",
|
||||
WebTemplateCommunicationSite: "Communication Sit",
|
||||
WebTemplateTeamSite: "Team Site",
|
||||
SiteDesignRightsPanelTitle: "Site Design Rights",
|
||||
SiteScriptIdLabel: "Site Script Id",
|
||||
EditSiteScriptDialogTitle: "Edit Site Script",
|
||||
AddSiteScriptDialogTitle: "Create a Site Script",
|
||||
AddSiteScriptDescriptionLabel: "Description",
|
||||
AddSiteScriptTitleLabel: "Title",
|
||||
"PropertyPaneDescription": "Properties",
|
||||
"BasicGroupName": "Group Name",
|
||||
"TitleFieldLabel": "Title",
|
||||
"ListViewColumnIdLabel": "Id",
|
||||
"ListViewColumnWebTemplateLabel": "WebTemplate",
|
||||
"ListViewColumnDescriptionLabel": "Description",
|
||||
"ListViewColumnNumberSiteScriptsLabel": "Nr Site Scripts",
|
||||
"ErrorMessageUserNotAdmin": "User is not Tenant Admin to managed Tenant Properties",
|
||||
"LoadingLabel":"Loading...",
|
||||
"CommandbarNewLabel":"New",
|
||||
"CommandbarEditLabel": "Edit",
|
||||
"CommandbarDeleteLabel": "Delete",
|
||||
"CommandbarRefreshLabel": "Refresh",
|
||||
"CommandbarRightsLabel": "Rights",
|
||||
"CommandbarApplyLabel": "Apply",
|
||||
"SearchPlaceholder": "Search...",
|
||||
"PrimaryButtonLabelSave":"Save",
|
||||
"PrimaryButtonLabelDelete":"Delete",
|
||||
"DefaultButtonLabel":"Cancel",
|
||||
"PanelHeaderTextEdit":"Add / Edit Site Design",
|
||||
"PanelHeaderTextDelete":"Delete Site Design",
|
||||
"messageTenantExist": "A Site Design with this key already exists",
|
||||
"CommandbarSiteScriptsLabel": "Site Scripts",
|
||||
"AddSiteDesignTitleLabel" : "Site Design Title",
|
||||
"AddSiteDesignDescriptionLabel": "Site Design Description",
|
||||
"AddSiteDesignImageUrlLabel": "Preview Image Url",
|
||||
"AddSiteDesignIsDefaultLabel" : "Is Default ?",
|
||||
"SiteDesignIdLabel": "Site Design Id",
|
||||
"ListViewColumnIdPrincipalNameLabel" : "PrincipalName",
|
||||
SiteDesignTitleLabel: "Site Design Title:",
|
||||
WebTemplateLabel: "Web Template"
|
||||
}
|
||||
});
|
87
samples/react-manage-sitedesigns/src/webparts/siteDesigns/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
declare interface ISiteDesignsWebPartStrings {
|
||||
DeleteSiteScriptDialogConfirmText: string;
|
||||
DeleteSiteScriptDialogConfirmTitle: string;
|
||||
JSONSchemaNotValidMessage: string;
|
||||
EditSiteDesignPanelButtonCancelText: string;
|
||||
EditSiteDesignPanelButtonSaveText: string;
|
||||
DeleteSiteDesignPanelTitle: string;
|
||||
DeleteSiteDesignPanelButtonCanceltext: string;
|
||||
DeleteSiteDesignPanelButtonDeleteText: string;
|
||||
AddSiteScriptToSiteDesignPanelButtonCancelText: string;
|
||||
AddSiteScriptToSiteDesignPanelButtonSaveText: string;
|
||||
AddSiteScriptPanelButtonCancelText: string;
|
||||
AddSiteScriptPanelButtonSave: string;
|
||||
AddPrincipalPanelButtonCancelText: string;
|
||||
AddPrincipalPanelButtonSaveText: string;
|
||||
AddSiteDesignPanelDropDownLabel: string;
|
||||
AddSiteDesignPanelDropDownPlaceholderText: string;
|
||||
AddSiteDesignPanelButtonCancelText: string;
|
||||
AddSiteDesignPanelButtonSaveText: string;
|
||||
AddSiteDesignPanelScriptOrderInfo: string;
|
||||
AddSiteDesignPanelActionButtonText: string;
|
||||
AddSiteDesignPanelTitleErrorMessage: string;
|
||||
SearchBoxPlaceholderText: string;
|
||||
EditSiteScriptPanelButtonCancel: string;
|
||||
EditSiteScriptSaveButtonLabel: string;
|
||||
ApplyPanelTitle: string;
|
||||
ApplyPanelButtonCancelLabel: string;
|
||||
ApplyPanelApplyButtonLabel: string;
|
||||
siteDesignRunningMessage: string;
|
||||
WebSiteUrl: string;
|
||||
WebSiteTitleLabel: string;
|
||||
actionButtonTitle: string;
|
||||
ButtonCancelLabel: string;
|
||||
ButtonDeleteLabel: string;
|
||||
DropDownSelectSiteScriptLabel: string;
|
||||
DropDownSelectSiteScriptPlaceHolder: string;
|
||||
AddSiteScriptToSiteDesignPanelTitle: string;
|
||||
AddSiteScriptDialogSubText: string;
|
||||
JSONSchemaErrorMessage: string;
|
||||
DialogConfirmDeleteText: string;
|
||||
DialogConfirmDeleteTitle: string;
|
||||
WebTemplateCommunicationSite: string;
|
||||
WebTemplateTeamSite: string;
|
||||
SiteDesignRightsPanelTitle: string;
|
||||
SiteScriptIdLabel: string;
|
||||
EditSiteScriptDialogTitle: string;
|
||||
AddSiteScriptDialogTitle: string;
|
||||
AddSiteScriptDescriptionLabel: string;
|
||||
AddSiteScriptTitleLabel: string;
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
TitleFieldLabel: string;
|
||||
ListViewColumnIdLabel:string;
|
||||
ListViewColumnWebTemplateLabel:string;
|
||||
ListViewColumnDescriptionLabel:string;
|
||||
ListViewColumnNumberSiteScriptsLabel:string;
|
||||
ErrorMessageUserNotAdmin:string;
|
||||
LoadingLabel:string;
|
||||
CommandbarNewLabel:string;
|
||||
CommandbarEditLabel:string;
|
||||
CommandbarDeleteLabel:string;
|
||||
CommandbarRefreshLabel:string;
|
||||
CommandbarRightsLabel:string;
|
||||
CommandbarSiteScriptsLabel:string;
|
||||
CommandbarApplyLabel:string;
|
||||
SearchPlaceholder:string;
|
||||
PrimaryButtonLabelSave:string;
|
||||
PrimaryButtonLabelDelete:string;
|
||||
DefaultButtonLabel:string;
|
||||
PanelHeaderTextEdit:string;
|
||||
PanelHeaderTextDelete:string;
|
||||
messageTenantExist:string;
|
||||
AddSiteDesignTitleLabel:string,
|
||||
AddSiteDesignDescriptionLabel:string;
|
||||
AddSiteDesignImageUrlLabel:string;
|
||||
AddSiteDesignIsDefaultLabel:string;
|
||||
SiteDesignIdLabel:string;
|
||||
ListViewColumnIdPrincipalNameLabel:string;
|
||||
SiteDesignTitleLabel:string;
|
||||
WebTemplateLabel:string;
|
||||
}
|
||||
|
||||
|
||||
declare module 'SiteDesignsWebPartStrings' {
|
||||
const strings: ISiteDesignsWebPartStrings;
|
||||
export = strings;
|
||||
}
|
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* This script updates the package-solution version analogue to the
|
||||
* the package.json file.
|
||||
*/
|
||||
|
||||
if (process.env.npm_package_version === undefined) {
|
||||
|
||||
throw 'Package version cannot be evaluated';
|
||||
|
||||
}
|
||||
|
||||
// define path to package-solution file
|
||||
const solution = './config/package-solution.json',
|
||||
teams = './teams/manifest.json';
|
||||
|
||||
// require filesystem instanc
|
||||
const fs = require('fs');
|
||||
|
||||
// get next automated package version from process variable
|
||||
const nextPkgVersion = process.env.npm_package_version;
|
||||
|
||||
// make sure next build version match
|
||||
const nextVersion = nextPkgVersion.indexOf('-') === -1 ?
|
||||
nextPkgVersion : nextPkgVersion.split('-')[0];
|
||||
|
||||
// Update version in SPFx package-solution if exists
|
||||
if (fs.existsSync(solution)) {
|
||||
|
||||
// read package-solution file
|
||||
const solutionFileContent = fs.readFileSync(solution, 'UTF-8');
|
||||
// parse file as json
|
||||
const solutionContents = JSON.parse(solutionFileContent);
|
||||
|
||||
// set property of version to next version
|
||||
solutionContents.solution.version = nextVersion + '.0';
|
||||
|
||||
// save file
|
||||
fs.writeFileSync(
|
||||
solution,
|
||||
// convert file back to proper json
|
||||
JSON.stringify(solutionContents, null, 2),
|
||||
'UTF-8');
|
||||
|
||||
}
|
||||
|
||||
// Update version in teams manifest if exists
|
||||
if (fs.existsSync(teams)) {
|
||||
|
||||
// read package-solution file
|
||||
const teamsManifestContent = fs.readFileSync(teams, 'UTF-8');
|
||||
// parse file as json
|
||||
const teamsContent = JSON.parse(teamsManifestContent);
|
||||
|
||||
// set property of version to next version
|
||||
teamsContent.version = nextVersion;
|
||||
|
||||
// save file
|
||||
fs.writeFileSync(
|
||||
teams,
|
||||
// convert file back to proper json
|
||||
JSON.stringify(teamsContent, null, 2),
|
||||
'UTF-8');
|
||||
|
||||
}
|