Skip to content

Commit d43c5db

Browse files
Updating development environment
- Add application customizer and form customizer to the SPFx project - Update MPA documentation
1 parent 4497d0c commit d43c5db

21 files changed

+438
-18
lines changed

.yo-rc.json

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
{
22
"@microsoft/generator-sharepoint": {
3-
"version": "1.15.2",
3+
"version": "1.16.0",
44
"libraryName": "sp-dev-fx-controls-react",
55
"libraryId": "92b1e52c-a5fa-490a-bcf4-76080f39442c",
66
"environment": "spo",
77
"isDomainIsolated": false,
8-
"isCreatingSolution": true,
8+
"isCreatingSolution": false,
99
"packageManager": "npm",
10-
"componentType": "webpart"
10+
"plusBeta": false,
11+
"nodeVersion": "16.15.0",
12+
"sdksVersions": {
13+
"@microsoft/microsoft-graph-client": "3.0.2",
14+
"@microsoft/teams-js": "2.4.1"
15+
},
16+
"componentType": "extension",
17+
"extensionType": "ApplicationCustomizer"
1118
}
1219
}

config/config.json

+25-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
"version": "2.0",
44
"bundles": {
55
"controls-test-web-part": {
6-
"components": [{
7-
"entrypoint": "./lib/webparts/controlsTest/ControlsTestWebPart.js",
8-
"manifest": "./src/webparts/controlsTest/ControlsTestWebPart.manifest.json"
9-
}]
6+
"components": [
7+
{
8+
"entrypoint": "./lib/webparts/controlsTest/ControlsTestWebPart.js",
9+
"manifest": "./src/webparts/controlsTest/ControlsTestWebPart.manifest.json"
10+
}
11+
]
1012
},
1113
"ootb-fields-field-customizer": {
1214
"components": [
@@ -15,11 +17,29 @@
1517
"manifest": "./src/extensions/ootbFields/OotbFieldsFieldCustomizer.manifest.json"
1618
}
1719
]
20+
},
21+
"controls-test-form-customizer": {
22+
"components": [
23+
{
24+
"entrypoint": "./lib/extensions/testForm/TestFormCustomizer.js",
25+
"manifest": "./src/extensions/testForm/TestFormCustomizer.manifest.json"
26+
}
27+
]
28+
},
29+
"app-controls-test-application-customizer": {
30+
"components": [
31+
{
32+
"entrypoint": "./lib/extensions/testApp/TestApplicationCustomizer.js",
33+
"manifest": "./src/extensions/testApp/TestApplicationCustomizer.manifest.json"
34+
}
35+
]
1836
}
1937
},
2038
"externals": {},
2139
"localizedResources": {
2240
"ControlStrings": "lib/loc/{locale}.js",
23-
"ControlsTestWebPartStrings": "lib/webparts/controlsTest/loc/{locale}.js"
41+
"ControlsTestWebPartStrings": "lib/webparts/controlsTest/loc/{locale}.js",
42+
"ControlsTestFormCustomizerStrings": "lib/extensions/testForm/loc/{locale}.js",
43+
"TestApplicationCustomizerStrings": "lib/extensions/testApp/loc/{locale}.js"
2444
}
2545
}

config/package-solution.json

+15-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,21 @@
1313
"termsOfUseUrl": "",
1414
"websiteUrl": "",
1515
"mpnId": "Undefined-1.13.0"
16-
}
16+
},
17+
"features": [
18+
{
19+
"title": "sp-dev-fx-controls-react Feature",
20+
"description": "The feature that activates elements of the sp-dev-fx-controls-react solution.",
21+
"id": "d7493d69-72ce-4892-a4ae-643166acae22",
22+
"version": "1.0.0.0",
23+
"assets": {
24+
"elementManifests": [
25+
"elements.xml",
26+
"ClientSideInstance.xml"
27+
]
28+
}
29+
}
30+
]
1731
},
1832
"paths": {
1933
"zippedPackage": "solution/sp-dev-fx-controls-react.sppkg"

config/serve.json

+60-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,64 @@
22
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
33
"port": 4321,
44
"initialPage": "https://enter-your-SharePoint-site/_layouts/workbench.aspx",
5-
"https": true
5+
"https": true,
6+
"serveConfigurations": {
7+
"default": {
8+
"pageUrl": "https://enter-your-SharePoint-site.sharepoint.com/sites/mySite/_layouts/15/SPListForm.aspx",
9+
"formCustomizer": {
10+
"componentId": "f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8",
11+
"PageType": 8,
12+
"RootFolder": "/sites/mySite/Lists/MyList",
13+
"properties": {
14+
"sampleText": "Value"
15+
}
16+
}
17+
},
18+
"testForm_NewForm": {
19+
"pageUrl": "https://enter-your-SharePoint-site.sharepoint.com/sites/mySite/_layouts/15/SPListForm.aspx",
20+
"formCustomizer": {
21+
"componentId": "f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8",
22+
"PageType": 8,
23+
"RootFolder": "/sites/mySite/Lists/MyList",
24+
"properties": {
25+
"sampleText": "Value"
26+
}
27+
}
28+
},
29+
"testForm_EditForm": {
30+
"pageUrl": "https://enter-your-SharePoint-site.sharepoint.com/sites/mySite/_layouts/15/SPListForm.aspx",
31+
"formCustomizer": {
32+
"componentId": "f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8",
33+
"PageType": 6,
34+
"RootFolder": "/sites/mySite/Lists/MyList",
35+
"ID": 1,
36+
"properties": {
37+
"sampleText": "Value"
38+
}
39+
}
40+
},
41+
"testForm_ViewForm": {
42+
"pageUrl": "https://enter-your-SharePoint-site.sharepoint.com/sites/mySite/_layouts/15/SPListForm.aspx",
43+
"formCustomizer": {
44+
"componentId": "f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8",
45+
"PageType": 4,
46+
"RootFolder": "/sites/mySite/Lists/MyList",
47+
"ID": 1,
48+
"properties": {
49+
"sampleText": "Value"
50+
}
51+
}
52+
},
53+
"testApp": {
54+
"pageUrl": "https://enter-your-SharePoint-site.sharepoint.com/sites/mySite/SitePages/myPage.aspx",
55+
"customActions": {
56+
"ca9eac70-7343-4972-88d6-672d50e9cf38": {
57+
"location": "ClientSideExtension.ApplicationCustomizer",
58+
"properties": {
59+
"testMessage": "Test message"
60+
}
61+
}
62+
}
63+
}
64+
}
665
}

docs/documentation/docs/guides/mpa.md

+42-5
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,51 @@ The shortest way to prepare your local copy of the project for development and t
66

77
Before you start contributing to this project, you will need Node.js. This project has been tested with the 10.x version of Node.js and the version of NPM that comes with it. You can use [Node Version Manager](https://github.com/nvm-sh/nvm) to switch between different versions of Node.js.
88

9-
## Get the local version of the CLI
9+
## Get the local version of the project
1010

1111
- fork this repository
1212
- clone your fork
13-
- in the command line:
14-
- run `npm install` to restore dependencies
15-
- run `gulp serve` to serve your project
16-
- Start making your changes
13+
- in the command line, run the following commands:
14+
- `npm install` to restore dependencies
15+
- `npm install -g gulp-cli` in order to run `gulp` commands (run `npm list -g gulp-cli` to check if already installed on your machine or not)
16+
- `gulp serve` to serve your project (or `npm run serve` if you want to use [`spfx-fast-serve`](https://github.com/s-KaiNet/spfx-fast-serve))
17+
- Start making your changes
18+
19+
### Run the project locally
20+
21+
As this project embeds a SPFx solution, you have the ability to test all the controls on your machine.
22+
23+
!!! warning
24+
As long as you have access to a SharePoint Online environment (for v2 and after), you can test the components from your machine. But to test the web part as a Teams Tab, you have to first deploy the SPFx solution (and sync it to Teams). You also have to deploy the [SharePoint Framework library for Microsoft Graph Toolkit](https://learn.microsoft.com/en-us/graph/toolkit/get-started/mgt-spfx) v2.9.0. So be sure to be at least **SharePoint Administrator**.
25+
26+
#### SPFx web part
27+
28+
The web part is called *ControlsTest* and is available for both SharePoint Online and Teams. To test it on SharePoint, go to the workbench page (<https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/workbench.aspx>) and add the web part.
29+
30+
To test it on Teams, once the project deployed on the tenant accordingly, add the web part as a Tab (from a team for example).
31+
32+
To update the host component, open the *ControlsTest* React component located in the following project's relative path: *src\webparts\controlsTest\components\ControlsTest.tsx*.
33+
34+
#### SPFx application customizer
35+
36+
This extension is called *TestApplicationCustomizer*. To test it, go to the following URL (after updating the parameters):
37+
38+
<https://[SHAREPOINT_SITE].sharepoint.com?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={"ca9eac70-7343-4972-88d6-672d50e9cf38":{"location":"ClientSideExtension.ApplicationCustomizer"}}>
39+
40+
To update the host component, open the *TestApp* React component located in the following project's relative path: *src\extensions\testApp\TestApp.tsx*.
41+
42+
#### SPFx form customizer
43+
44+
This extension is called *TestForm*. To test it, you have to configure it first:
45+
46+
1. Open the *serve.json* file (located in the *config* folder)
47+
2. Replace the `rootFolder` property (under `serveConfigurations` ==> `default` ==> `formCustomizer`), which contains a server relative URL, to target the list on which you want to test the extension
48+
49+
Then go to the following URL (after updating the parameters):
50+
51+
<https://[SHAREPOINT_SITE].sharepoint.com/_layouts/15/SPListForm.aspx?debugManifestsFile=https://localhost:4321/temp/manifests.js&loadSPFX=true&componentId=f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8&PageType=8&RootFolder=[OPTIONAL_SERVER_RELATIVE_URL]/Lists/[LIST_NAME]>
52+
53+
To update the host component, open the *TestForm* React component located in the following project's relative path: *src\extensions\testForm\components\TestForm.tsx*.
1754

1855
### Documentation
1956

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@
6060
"react-mentions": "^4.3.0",
6161
"react-quill": "1.3.5",
6262
"regexify-string": "^1.0.16",
63-
"spfx-uifabric-themes": "^0.9.0"
63+
"spfx-uifabric-themes": "^0.9.0",
64+
"@microsoft/decorators": "1.16.0",
65+
"@microsoft/sp-dialog": "1.16.0",
66+
"@microsoft/sp-application-base": "1.16.0"
6467
},
6568
"devDependencies": {
6669
"@microsoft/eslint-config-spfx": "1.16.0",
@@ -101,7 +104,7 @@
101104
"react-addons-test-utils": "15.6.0",
102105
"request-promise": "4.2.5",
103106
"sonarqube-scanner": "2.8.2",
104-
"spfx-fast-serve-helpers": "~1.15.3",
107+
"spfx-fast-serve-helpers": "~1.16.0",
105108
"ts-jest": "^25.5.1",
106109
"tslib": "2.3.1",
107110
"tslint-microsoft-contrib": "6.2.0",
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
3+
<ClientSideComponentInstance
4+
Title="testApp"
5+
Location="ClientSideExtension.ApplicationCustomizer"
6+
ComponentId="ca9eac70-7343-4972-88d6-672d50e9cf38"
7+
Properties="{&quot;testMessage&quot;:&quot;Test message&quot;}">
8+
</ClientSideComponentInstance>
9+
</Elements>

sharepoint/assets/elements.xml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
3+
<CustomAction
4+
Title="testApp"
5+
Location="ClientSideExtension.ApplicationCustomizer"
6+
ClientSideComponentId="ca9eac70-7343-4972-88d6-672d50e9cf38"
7+
ClientSideComponentProperties="{&quot;testMessage&quot;:&quot;Test message&quot;}">
8+
</CustomAction>
9+
</Elements>

src/extensions/testApp/TestApp.module.scss

Whitespace-only changes.

src/extensions/testApp/TestApp.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ApplicationCustomizerContext } from '@microsoft/sp-application-base';
2+
import { DefaultButton } from 'office-ui-fabric-react';
3+
import * as React from 'react';
4+
5+
// import styles from './TestApp.module.scss';
6+
7+
export interface ITestAppProps {
8+
context: ApplicationCustomizerContext
9+
}
10+
11+
interface ITestAppState { }
12+
13+
export default class TestApp extends React.Component<ITestAppProps, ITestAppState> {
14+
15+
constructor(props: ITestAppProps) {
16+
super(props);
17+
18+
this.state = {
19+
20+
};
21+
}
22+
23+
public render(): React.ReactElement<ITestAppProps> {
24+
return (
25+
<DefaultButton text="test" />
26+
);
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-extension-manifest.schema.json",
3+
4+
"id": "ca9eac70-7343-4972-88d6-672d50e9cf38",
5+
"alias": "TestApplicationCustomizer",
6+
"componentType": "Extension",
7+
"extensionType": "ApplicationCustomizer",
8+
9+
// The "*" signifies that the version should be taken from the package.json
10+
"version": "*",
11+
"manifestVersion": 2,
12+
13+
// If true, the component can only be installed on sites where Custom Script is allowed.
14+
// Components that allow authors to embed arbitrary script code should set this to true.
15+
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
16+
"requiresCustomScript": false
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as React from 'react';
2+
import * as ReactDom from 'react-dom';
3+
import { Log } from '@microsoft/sp-core-library';
4+
import {
5+
BaseApplicationCustomizer, PlaceholderContent, PlaceholderName
6+
} from '@microsoft/sp-application-base';
7+
8+
import * as strings from 'TestApplicationCustomizerStrings';
9+
import TestApp, { ITestAppProps as ITestAppProps } from './TestApp';
10+
11+
const LOG_SOURCE: string = 'TestApplicationCustomizer';
12+
13+
/**
14+
* If your command set uses the ClientSideComponentProperties JSON input,
15+
* it will be deserialized into the BaseExtension.properties object.
16+
* You can define an interface to describe it.
17+
*/
18+
export interface ITestApplicationCustomizerProperties {
19+
// This is an example; replace with your own property
20+
testMessage: string;
21+
}
22+
23+
/** A Custom Action which can be run during execution of a Client Side Application */
24+
export default class TestApplicationCustomizer
25+
extends BaseApplicationCustomizer<ITestApplicationCustomizerProperties> {
26+
27+
private _topPlaceHolder: PlaceholderContent | undefined;
28+
29+
public onInit(): Promise<void> {
30+
Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
31+
32+
this.context.placeholderProvider.changedEvent.add(this, this._renderPlaceHolders);
33+
34+
return Promise.resolve();
35+
}
36+
37+
private async _renderPlaceHolders(): Promise<void> {
38+
if (!this._topPlaceHolder) {
39+
this._topPlaceHolder = this.context.placeholderProvider.tryCreateContent(
40+
PlaceholderName.Top,
41+
{ onDispose: this._onDispose }
42+
);
43+
}
44+
45+
const element: React.ReactElement<ITestAppProps> = React.createElement(TestApp, {
46+
context: this.context
47+
});
48+
49+
ReactDom.render(element, this._topPlaceHolder.domElement);
50+
}
51+
52+
private _onDispose(PlaceholderContent: PlaceholderContent): void {
53+
ReactDom.unmountComponentAtNode(PlaceholderContent.domElement);
54+
}
55+
}

src/extensions/testApp/loc/en-us.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
define([], function() {
2+
return {
3+
"Title": "TestApplicationCustomizer"
4+
}
5+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare interface ITestApplicationCustomizerStrings {
2+
Title: string;
3+
}
4+
5+
declare module 'TestApplicationCustomizerStrings' {
6+
const strings: ITestApplicationCustomizerStrings;
7+
export = strings;
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-extension-manifest.schema.json",
3+
4+
"id": "f9c6b930-8d5d-4550-bfd9-ed5f6ca443a8",
5+
"alias": "TestFormCustomizer",
6+
"componentType": "Extension",
7+
"extensionType": "FormCustomizer",
8+
9+
// The "*" signifies that the version should be taken from the package.json
10+
"version": "*",
11+
"manifestVersion": 2,
12+
13+
// If true, the component can only be installed on sites where Custom Script is allowed.
14+
// Components that allow authors to embed arbitrary script code should set this to true.
15+
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
16+
"requiresCustomScript": false
17+
}

0 commit comments

Comments
 (0)