Merge branch 'master' into UpdateBigCalendar
|
@ -0,0 +1,25 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
|
||||||
|
# change these settings to your own preference
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# we recommend you to keep these unchanged
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[{package,bower}.json]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.11.0",
|
||||||
|
"libraryName": "react-avatar",
|
||||||
|
"libraryId": "b96dfed7-ec48-4082-ba50-f6c7b09143c7",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
This is a sample web part that helps user create their avatar and save as profile picture. User can even download their avatar as PNG file. This web part can be useful in Intranet to help user create their avatar and save it as profile picture.
|
This is a sample web part that helps user create their avatar and save as profile picture. User can even download their avatar as PNG file. This web part can be useful in Intranet to help user create their avatar and save it as profile picture.
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
![directory](/samples/react-avatar/assets/reactAvatarOutcome.gif)
|
![directory](/samples/react-avatar/assets/reactAvatarOutcome.gif)
|
||||||
|
|
||||||
|
@ -16,7 +15,8 @@ This is a sample web part that helps user create their avatar and save as profil
|
||||||
|
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
![drop](https://img.shields.io/badge/version-1.10.0-green.svg)
|
|
||||||
|
![SPFx 1.11](https://img.shields.io/badge/version-1.11.0-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ Web Part Title | Text| no|
|
||||||
|
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
The web part Use avataaars library for creating avatars and MS Graph with User.ReadWrite and User.ReadWriteAll for saving avatar as current users Profile Picture.FileSaver for downloading avatar image as png file.
|
The web part Use avataaars library for creating avatars and MS Graph with User.ReadWrite and User.ReadWriteAll for saving avatar as current users Profile Picture.FileSaver for downloading avatar image as png file.
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
|
@ -66,9 +67,11 @@ react Avatar|Kunj Sangani
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0.0|August 1, 2020|Initial release
|
1.0.0|August 1, 2020|Initial release
|
||||||
|
1.0.1|October 20, 2020|Update to SPFx 1.11.0
|
||||||
|
|
||||||
|
|
||||||
## Disclaimer
|
## 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.**
|
**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.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -81,9 +84,6 @@ Version|Date|Comments
|
||||||
- `gulp build`
|
- `gulp build`
|
||||||
- `gulp bundle --ship`
|
- `gulp bundle --ship`
|
||||||
- `gulp package-solution --ship`
|
- `gulp package-solution --ship`
|
||||||
- `Add to AppCatalog and deploy`
|
- Add to AppCatalog and deploy
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-avatar" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-avatar" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-avatars-client-side-solution",
|
"name": "react-avatars-client-side-solution",
|
||||||
"id": "b96dfed7-ec48-4082-ba50-f6c7b09143c7",
|
"id": "b96dfed7-ec48-4082-ba50-f6c7b09143c7",
|
||||||
"version": "1.0.0.0",
|
"version": "1.0.1.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
"webApiPermissionRequests": [
|
"webApiPermissionRequests": [
|
||||||
|
@ -11,7 +11,14 @@
|
||||||
"resource": "Microsoft Graph",
|
"resource": "Microsoft Graph",
|
||||||
"scope": "User.ReadWrite"
|
"scope": "User.ReadWrite"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-avatars.sppkg"
|
"zippedPackage": "solution/react-avatars.sppkg"
|
||||||
|
|
|
@ -13,18 +13,14 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.0",
|
"@material-ui/core": "^4.11.0",
|
||||||
"@microsoft/sp-core-library": "1.10.0",
|
"@microsoft/sp-core-library": "1.11.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.10.0",
|
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
||||||
"@microsoft/sp-property-pane": "1.10.0",
|
"@microsoft/sp-property-pane": "1.11.0",
|
||||||
"@microsoft/sp-webpart-base": "1.10.0",
|
"@microsoft/sp-webpart-base": "1.11.0",
|
||||||
"@types/es6-promise": "0.0.33",
|
|
||||||
"@types/react": "16.8.8",
|
|
||||||
"@types/react-dom": "16.8.3",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"avataaars": "^1.2.1",
|
"avataaars": "^1.2.1",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"office-ui-fabric-react": "6.189.2",
|
"office-ui-fabric-react": "6.214.0",
|
||||||
"react": "16.8.5",
|
"react": "16.8.5",
|
||||||
"react-dom": "16.8.5"
|
"react-dom": "16.8.5"
|
||||||
},
|
},
|
||||||
|
@ -32,14 +28,14 @@
|
||||||
"@types/react": "16.8.8"
|
"@types/react": "16.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "1.10.0",
|
|
||||||
"@microsoft/sp-tslint-rules": "1.10.0",
|
|
||||||
"@microsoft/sp-module-interfaces": "1.10.0",
|
|
||||||
"@microsoft/sp-webpart-workbench": "1.10.0",
|
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||||
"gulp": "~3.9.1",
|
"@microsoft/sp-build-web": "1.11.0",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||||
"@types/chai": "3.4.34",
|
"@types/chai": "3.4.34",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/mocha": "2.2.38",
|
||||||
"ajv": "~5.2.2"
|
"ajv": "~5.2.2",
|
||||||
|
"gulp": "~3.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -104,13 +104,15 @@ Start Date | Date | yes | Event Date
|
||||||
End Date| Date| yes | Event Date
|
End Date| Date| yes | Event Date
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
The Web Part Use PnPjs library, Office-ui-fabric-react components. react Big-Calendar Compoment
|
|
||||||
|
The Web Part Use PnPjs library, Office-ui-fabric-react components. react Big-Calendar Component
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
Calendar Web Part|João Mendes
|
Calendar Web Part|João Mendes
|
||||||
Calendar Web Part|Mohamed Derhalli
|
Calendar Web Part|Mohamed Derhalli
|
||||||
Calendar Web Part (Upgrade)|Hugo Bernier ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/))
|
Calendar Web Part (Upgrade)|Hugo Bernier ([@bernier](https://twitter.com/bernierh), [Tahoe Ninjas](https://tahoeninjas.blog/))
|
||||||
|
Calendar Web Part|Nanddeep Nachan ([@NanddeepNachan](https://twitter.com/NanddeepNachan))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
@ -120,6 +122,7 @@ Version|Date|Comments
|
||||||
1.0.1|June 10, 2019|update add recurrence events
|
1.0.1|June 10, 2019|update add recurrence events
|
||||||
1.0.2|April 25, 2020|Update styles according to the applied theme
|
1.0.2|April 25, 2020|Update styles according to the applied theme
|
||||||
1.0.3|June 06, 2020|Upgrade to SPFx 1.10.0
|
1.0.3|June 06, 2020|Upgrade to SPFx 1.10.0
|
||||||
|
1.0.4|October 18, 2020|Added support for all-day events
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-calendar-client-side-solution",
|
"name": "react-calendar-client-side-solution",
|
||||||
"id": "3a13208b-3874-4036-9262-4edd22e88187",
|
"id": "3a13208b-3874-4036-9262-4edd22e88187",
|
||||||
"version": "1.0.0.1",
|
"version": "1.0.4.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "react-calendar",
|
"name": "react-calendar",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
|
|
|
@ -24,6 +24,7 @@ export interface IEventState {
|
||||||
displayDialog: boolean;
|
displayDialog: boolean;
|
||||||
userPermissions?: IUserPermissions;
|
userPermissions?: IUserPermissions;
|
||||||
isloading: boolean;
|
isloading: boolean;
|
||||||
|
isAllDayEvent: boolean;
|
||||||
siteRegionalSettings: any;
|
siteRegionalSettings: any;
|
||||||
recurrenceSeriesEdited?: boolean;
|
recurrenceSeriesEdited?: boolean;
|
||||||
showRecurrenceSeriesInfo: boolean;
|
showRecurrenceSeriesInfo: boolean;
|
||||||
|
|
|
@ -79,7 +79,6 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
navigator.geolocation.getCurrentPosition((position) => {
|
navigator.geolocation.getCurrentPosition((position) => {
|
||||||
this.latitude = position.coords.latitude;
|
this.latitude = position.coords.latitude;
|
||||||
this.longitude = position.coords.longitude;
|
this.longitude = position.coords.longitude;
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
/* geolocation IS NOT available */
|
/* geolocation IS NOT available */
|
||||||
|
@ -104,6 +103,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
displayDialog: false,
|
displayDialog: false,
|
||||||
isloading: false,
|
isloading: false,
|
||||||
|
isAllDayEvent: this.props.event && this.props.event.fAllDayEvent,
|
||||||
siteRegionalSettings: undefined,
|
siteRegionalSettings: undefined,
|
||||||
recurrenceSeriesEdited: false,
|
recurrenceSeriesEdited: false,
|
||||||
showRecurrenceSeriesInfo: false,
|
showRecurrenceSeriesInfo: false,
|
||||||
|
@ -148,13 +148,15 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
* @memberof Event
|
* @memberof Event
|
||||||
*/
|
*/
|
||||||
private async onSave() {
|
private async onSave() {
|
||||||
|
|
||||||
let eventData: IEventData = this.state.eventData;
|
let eventData: IEventData = this.state.eventData;
|
||||||
let panelMode = this.props.panelMode;
|
let panelMode = this.props.panelMode;
|
||||||
|
|
||||||
let startDate: string = null;
|
let startDate: string = null;
|
||||||
let endDate: string = null;
|
let endDate: string = null;
|
||||||
eventData.fRecurrence = false;
|
eventData.fRecurrence = false;
|
||||||
|
|
||||||
|
// set All day event
|
||||||
|
eventData.fAllDayEvent = this.state.isAllDayEvent;
|
||||||
|
|
||||||
// if there are new Event recurrence or Edited recurrence series
|
// if there are new Event recurrence or Edited recurrence series
|
||||||
if (this.state.recurrenceSeriesEdited || this.state.newRecurrenceEvent) {
|
if (this.state.recurrenceSeriesEdited || this.state.newRecurrenceEvent) {
|
||||||
eventData.RecurrenceData = this.returnedRecurrenceInfo.recurrenceData;
|
eventData.RecurrenceData = this.returnedRecurrenceInfo.recurrenceData;
|
||||||
|
@ -166,12 +168,13 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
eventData.fRecurrence = true;
|
eventData.fRecurrence = true;
|
||||||
eventData.UID = getGUID();
|
eventData.UID = getGUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventData.EventType == "1" && this.state.recurrenceSeriesEdited) {
|
if (eventData.EventType == "1" && this.state.recurrenceSeriesEdited) {
|
||||||
eventData.fRecurrence = true;
|
eventData.fRecurrence = true;
|
||||||
eventData.UID = getGUID();
|
eventData.UID = getGUID();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
if (this.state.eventData.EventType == '1') { // recurrence exception
|
if (this.state.eventData.EventType == '1') { // recurrence exception
|
||||||
eventData.RecurrenceID = eventData.EventDate.toString();
|
eventData.RecurrenceID = eventData.EventDate.toString();
|
||||||
eventData.MasterSeriesItemID = eventData.ID.toString();
|
eventData.MasterSeriesItemID = eventData.ID.toString();
|
||||||
|
@ -185,20 +188,19 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
endDate = `${moment(this.state.endDate).format('YYYY/MM/DD')}`;
|
endDate = `${moment(this.state.endDate).format('YYYY/MM/DD')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start Date
|
||||||
const startTime = `${this.state.startSelectedHour.key}:${this.state.startSelectedMin.key}`;
|
const startTime = `${this.state.startSelectedHour.key}:${this.state.startSelectedMin.key}`;
|
||||||
const startDateTime = `${startDate} ${startTime}`;
|
const startDateTime = `${startDate} ${startTime}`;
|
||||||
const start = moment(startDateTime, 'YYYY/MM/DD HH:mm').toLocaleString();
|
const start = moment(startDateTime, 'YYYY/MM/DD HH:mm').toLocaleString();
|
||||||
eventData.EventDate = new Date(start);
|
eventData.EventDate = new Date(start);
|
||||||
|
|
||||||
// End Date
|
// End Date
|
||||||
const endTime = `${this.state.endSelectedHour.key}:${this.state.endSelectedMin.key}`;
|
const endTime = `${this.state.endSelectedHour.key}:${this.state.endSelectedMin.key}`;
|
||||||
const endDateTime = `${endDate} ${endTime}`;
|
const endDateTime = `${endDate} ${endTime}`;
|
||||||
const end = moment(endDateTime, 'YYYY/MM/DD HH:mm').toLocaleString();
|
const end = moment(endDateTime, 'YYYY/MM/DD HH:mm').toLocaleString();
|
||||||
eventData.EndDate = new Date(end);
|
eventData.EndDate = new Date(end);
|
||||||
|
|
||||||
|
|
||||||
// get Geolocation
|
// get Geolocation
|
||||||
|
|
||||||
eventData.geolocation = { Latitude: this.latitude, Longitude: this.longitude };
|
eventData.geolocation = { Latitude: this.latitude, Longitude: this.longitude };
|
||||||
const locationInfo = await this.spService.getGeoLactionName(this.latitude, this.longitude);
|
const locationInfo = await this.spService.getGeoLactionName(this.latitude, this.longitude);
|
||||||
eventData.location = locationInfo ? locationInfo.display_name : 'N/A';
|
eventData.location = locationInfo ? locationInfo.display_name : 'N/A';
|
||||||
|
@ -213,7 +215,6 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const user of this.attendees) {
|
for (const user of this.attendees) {
|
||||||
|
|
||||||
const userInfo: any = await this.spService.getUserByLoginName(user.id, this.props.siteUrl);
|
const userInfo: any = await this.spService.getUserByLoginName(user.id, this.props.siteUrl);
|
||||||
eventData.attendes.push(Number(userInfo.Id));
|
eventData.attendes.push(Number(userInfo.Id));
|
||||||
}
|
}
|
||||||
|
@ -814,8 +815,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
});
|
});
|
||||||
|
|
||||||
const recurrenceInfo: any = await promise;
|
const recurrenceInfo: any = await promise;
|
||||||
if(recurrenceInfo != null)
|
if (recurrenceInfo != null) {
|
||||||
{
|
|
||||||
let keys = Object.keys(recurrenceInfo.recurrence.rule[0].repeat[0]);
|
let keys = Object.keys(recurrenceInfo.recurrence.rule[0].repeat[0]);
|
||||||
const recurrenceTypes = ["daily", "weekly", "monthly", "monthlyByDay", "yearly", "yearlyByDay"];
|
const recurrenceTypes = ["daily", "weekly", "monthly", "monthlyByDay", "yearly", "yearlyByDay"];
|
||||||
for (var key of keys) {
|
for (var key of keys) {
|
||||||
|
@ -948,6 +948,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
hidden={this.state.showRecurrenceSeriesInfo}
|
hidden={this.state.showRecurrenceSeriesInfo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{!this.state.isAllDayEvent &&
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
selectedKey={this.state.startSelectedHour.key}
|
selectedKey={this.state.startSelectedHour.key}
|
||||||
|
@ -982,6 +983,8 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
{!this.state.isAllDayEvent &&
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', }}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label={strings.StartMinLabel}
|
label={strings.StartMinLabel}
|
||||||
|
@ -1004,6 +1007,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
<br />
|
<br />
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
|
@ -1020,6 +1024,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
hidden={this.state.showRecurrenceSeriesInfo}
|
hidden={this.state.showRecurrenceSeriesInfo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{!this.state.isAllDayEvent &&
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', paddingRight: 10 }}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
selectedKey={this.state.endSelectedHour.key}
|
selectedKey={this.state.endSelectedHour.key}
|
||||||
|
@ -1054,6 +1059,8 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
{!this.state.isAllDayEvent &&
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', }}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label={strings.EndMinLabel}
|
label={strings.EndMinLabel}
|
||||||
|
@ -1077,10 +1084,26 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
<Label>{this.state.siteRegionalSettings ? this.state.siteRegionalSettings.Description : ''}</Label>
|
<Label>{this.state.siteRegionalSettings ? this.state.siteRegionalSettings.Description : ''}</Label>
|
||||||
<br />
|
<br />
|
||||||
{
|
|
||||||
|
|
||||||
|
<div style={{ display: 'inline-block', verticalAlign: 'top', width: '200px' }}>
|
||||||
|
<Toggle
|
||||||
|
defaultChecked={this.state.eventData && this.state.eventData.fAllDayEvent}
|
||||||
|
inlineLabel={true}
|
||||||
|
label={strings.allDayEventLabel}
|
||||||
|
onText={strings.onLabel}
|
||||||
|
offText={strings.offLabel}
|
||||||
|
onChange={(ev, checked: boolean) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.setState({ isAllDayEvent: checked });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{
|
||||||
this.state.eventData && (this.state.eventData.EventType == "0") ?
|
this.state.eventData && (this.state.eventData.EventType == "0") ?
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top', width: '200px' }}>
|
<div style={{ display: 'inline-block', verticalAlign: 'top', width: '200px' }}>
|
||||||
<Toggle
|
<Toggle
|
||||||
|
@ -1109,7 +1132,6 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
siteUrl={this.props.siteUrl}
|
siteUrl={this.props.siteUrl}
|
||||||
returnRecurrenceData={this.returnRecurrenceInfo}
|
returnRecurrenceData={this.returnRecurrenceInfo}
|
||||||
>
|
>
|
||||||
|
|
||||||
</EventRecurrenceInfo>
|
</EventRecurrenceInfo>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1147,6 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<PeoplePicker
|
<PeoplePicker
|
||||||
|
|
||||||
webAbsoluteUrl={this.props.siteUrl}
|
webAbsoluteUrl={this.props.siteUrl}
|
||||||
context={this.props.context}
|
context={this.props.context}
|
||||||
titleText={strings.AttendeesLabel}
|
titleText={strings.AttendeesLabel}
|
||||||
|
|
|
@ -76,7 +76,6 @@ export default class spservices {
|
||||||
let results = null;
|
let results = null;
|
||||||
try {
|
try {
|
||||||
const web = new Web(siteUrl);
|
const web = new Web(siteUrl);
|
||||||
|
|
||||||
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
||||||
|
|
||||||
results = await web.lists.getById(listId).items.add({
|
results = await web.lists.getById(listId).items.add({
|
||||||
|
@ -87,7 +86,7 @@ export default class spservices {
|
||||||
EventDate: new Date(moment(newEvent.EventDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
EventDate: new Date(moment(newEvent.EventDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
||||||
EndDate: new Date(moment(newEvent.EndDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
EndDate: new Date(moment(newEvent.EndDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
||||||
Location: newEvent.location,
|
Location: newEvent.location,
|
||||||
fAllDayEvent: false,
|
fAllDayEvent: newEvent.fAllDayEvent,
|
||||||
fRecurrence: newEvent.fRecurrence,
|
fRecurrence: newEvent.fRecurrence,
|
||||||
Category: newEvent.Category,
|
Category: newEvent.Category,
|
||||||
EventType: newEvent.EventType,
|
EventType: newEvent.EventType,
|
||||||
|
@ -96,7 +95,8 @@ export default class spservices {
|
||||||
MasterSeriesItemID: newEvent.MasterSeriesItemID,
|
MasterSeriesItemID: newEvent.MasterSeriesItemID,
|
||||||
RecurrenceID: newEvent.RecurrenceID ? moment(newEvent.RecurrenceID).add(siteTimeZoneHours, 'hours').toISOString() : undefined,
|
RecurrenceID: newEvent.RecurrenceID ? moment(newEvent.RecurrenceID).add(siteTimeZoneHours, 'hours').toISOString() : undefined,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
@ -117,13 +117,13 @@ export default class spservices {
|
||||||
try {
|
try {
|
||||||
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
||||||
const web = new Web(siteUrl);
|
const web = new Web(siteUrl);
|
||||||
|
|
||||||
//"Title","fRecurrence", "fAllDayEvent","EventDate", "EndDate", "Description","ID", "Location","Geolocation","ParticipantsPickerId"
|
//"Title","fRecurrence", "fAllDayEvent","EventDate", "EndDate", "Description","ID", "Location","Geolocation","ParticipantsPickerId"
|
||||||
const event = await web.lists.getById(listId).items.usingCaching().getById(eventId)
|
const event = await web.lists.getById(listId).items.usingCaching().getById(eventId)
|
||||||
.select("RecurrenceID", "MasterSeriesItemID", "Id", "ID", "ParticipantsPickerId", "EventType", "Title", "Description", "EventDate", "EndDate", "Location", "Author/SipAddress", "Author/Title", "Geolocation", "fAllDayEvent", "fRecurrence", "RecurrenceData", "RecurrenceData", "Duration", "Category", "UID")
|
.select("RecurrenceID", "MasterSeriesItemID", "Id", "ID", "ParticipantsPickerId", "EventType", "Title", "Description", "EventDate", "EndDate", "Location", "Author/SipAddress", "Author/Title", "Geolocation", "fAllDayEvent", "fRecurrence", "RecurrenceData", "RecurrenceData", "Duration", "Category", "UID")
|
||||||
.expand("Author")
|
.expand("Author")
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
|
|
||||||
returnEvent = {
|
returnEvent = {
|
||||||
Id: event.ID,
|
Id: event.ID,
|
||||||
ID: event.ID,
|
ID: event.ID,
|
||||||
|
@ -139,7 +139,7 @@ export default class spservices {
|
||||||
color: '',
|
color: '',
|
||||||
ownerName: event.Author.Title,
|
ownerName: event.Author.Title,
|
||||||
attendes: event.ParticipantsPickerId,
|
attendes: event.ParticipantsPickerId,
|
||||||
fAllDayEvent: false,
|
fAllDayEvent: event.fAllDayEvent,
|
||||||
geolocation: { Longitude: event.Geolocation ? event.Geolocation.Longitude : 0, Latitude: event.Geolocation ? event.Geolocation.Latitude : 0 },
|
geolocation: { Longitude: event.Geolocation ? event.Geolocation.Longitude : 0, Latitude: event.Geolocation ? event.Geolocation.Latitude : 0 },
|
||||||
Category: event.Category,
|
Category: event.Category,
|
||||||
Duration: event.Duration,
|
Duration: event.Duration,
|
||||||
|
@ -149,13 +149,13 @@ export default class spservices {
|
||||||
RecurrenceID: event.RecurrenceID,
|
RecurrenceID: event.RecurrenceID,
|
||||||
MasterSeriesItemID: event.MasterSeriesItemID,
|
MasterSeriesItemID: event.MasterSeriesItemID,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
return returnEvent;
|
return returnEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {IEventData} newEvent
|
* @param {IEventData} newEvent
|
||||||
|
@ -167,13 +167,12 @@ export default class spservices {
|
||||||
public async updateEvent(updateEvent: IEventData, siteUrl: string, listId: string) {
|
public async updateEvent(updateEvent: IEventData, siteUrl: string, listId: string) {
|
||||||
let results = null;
|
let results = null;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// delete all recursive extentions before update recurrence event
|
// delete all recursive extentions before update recurrence event
|
||||||
if (updateEvent.EventType.toString() == "1") await this.deleteRecurrenceExceptions(updateEvent, siteUrl, listId);
|
if (updateEvent.EventType.toString() == "1") await this.deleteRecurrenceExceptions(updateEvent, siteUrl, listId);
|
||||||
|
|
||||||
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
const siteTimeZoneHours: number = await this.getSiteTimeZoneHours(siteUrl);
|
||||||
|
|
||||||
const web = new Web(siteUrl);
|
const web = new Web(siteUrl);
|
||||||
|
|
||||||
//"Title","fRecurrence", "fAllDayEvent","EventDate", "EndDate", "Description","ID", "Location","Geolocation","ParticipantsPickerId"
|
//"Title","fRecurrence", "fAllDayEvent","EventDate", "EndDate", "Description","ID", "Location","Geolocation","ParticipantsPickerId"
|
||||||
let newItem: any = {
|
let newItem: any = {
|
||||||
Title: updateEvent.title,
|
Title: updateEvent.title,
|
||||||
|
@ -183,12 +182,13 @@ export default class spservices {
|
||||||
EventDate: new Date(moment(updateEvent.EventDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
EventDate: new Date(moment(updateEvent.EventDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
||||||
EndDate: new Date(moment(updateEvent.EndDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
EndDate: new Date(moment(updateEvent.EndDate).add(siteTimeZoneHours, 'hours').toISOString()),
|
||||||
Location: updateEvent.location,
|
Location: updateEvent.location,
|
||||||
fAllDayEvent: false,
|
fAllDayEvent: updateEvent.fAllDayEvent,
|
||||||
fRecurrence: updateEvent.fRecurrence,
|
fRecurrence: updateEvent.fRecurrence,
|
||||||
Category: updateEvent.Category,
|
Category: updateEvent.Category,
|
||||||
RecurrenceData: updateEvent.RecurrenceData ? await this.deCodeHtmlEntities(updateEvent.RecurrenceData) : "",
|
RecurrenceData: updateEvent.RecurrenceData ? await this.deCodeHtmlEntities(updateEvent.RecurrenceData) : "",
|
||||||
EventType: updateEvent.EventType,
|
EventType: updateEvent.EventType,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (updateEvent.UID) {
|
if (updateEvent.UID) {
|
||||||
newItem.UID = updateEvent.UID;
|
newItem.UID = updateEvent.UID;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,8 @@ export default class spservices {
|
||||||
}
|
}
|
||||||
|
|
||||||
results = await web.lists.getById(listId).items.getById(updateEvent.Id).update(newItem);
|
results = await web.lists.getById(listId).items.getById(updateEvent.Id).update(newItem);
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
@ -489,6 +490,7 @@ export default class spservices {
|
||||||
|
|
||||||
if (results && results.Row.length > 0) {
|
if (results && results.Row.length > 0) {
|
||||||
let event: any = '';
|
let event: any = '';
|
||||||
|
|
||||||
for (event of results.Row) {
|
for (event of results.Row) {
|
||||||
const initialsArray: string[] = event.Author[0].title.split(' ');
|
const initialsArray: string[] = event.Author[0].title.split(' ');
|
||||||
const initials: string = initialsArray[0].charAt(0) + initialsArray[initialsArray.length - 1].charAt(0);
|
const initials: string = initialsArray[0].charAt(0) + initialsArray[initialsArray.length - 1].charAt(0);
|
||||||
|
@ -501,22 +503,20 @@ export default class spservices {
|
||||||
const CategoryColorValue: any[] = categoryColor.filter((value) => {
|
const CategoryColorValue: any[] = categoryColor.filter((value) => {
|
||||||
return value.category == event.Category;
|
return value.category == event.Category;
|
||||||
});
|
});
|
||||||
|
const isAllDayEvent: boolean = event.fAllDayEvent === "Yes";
|
||||||
|
|
||||||
for (const attendee of event.ParticipantsPicker) {
|
for (const attendee of event.ParticipantsPicker) {
|
||||||
attendees.push(parseInt(attendee.id));
|
attendees.push(parseInt(attendee.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
events.push({
|
events.push({
|
||||||
Id: event.ID,
|
Id: event.ID,
|
||||||
ID: event.ID,
|
ID: event.ID,
|
||||||
EventType: event.EventType,
|
EventType: event.EventType,
|
||||||
title: await this.deCodeHtmlEntities(event.Title),
|
title: await this.deCodeHtmlEntities(event.Title),
|
||||||
Description: event.Description,
|
Description: event.Description,
|
||||||
|
EventDate: isAllDayEvent ? new Date(moment(event.EventDate).toISOString()) : new Date(moment(event.EventDate).subtract((siteTimeZoneHours), 'hour').toISOString()),
|
||||||
EventDate: new Date(moment(event.EventDate).subtract((siteTimeZoneHours), 'hour').toISOString()),
|
EndDate: isAllDayEvent ? new Date(moment(event.EndDate).toISOString()) : new Date(moment(event.EndDate).subtract(siteTimeZoneHours, 'hour').toISOString()),
|
||||||
|
|
||||||
EndDate: new Date(moment(event.EndDate).subtract(siteTimeZoneHours, 'hour').toISOString()),
|
|
||||||
location: event.Location,
|
location: event.Location,
|
||||||
ownerEmail: event.Author[0].email,
|
ownerEmail: event.Author[0].email,
|
||||||
ownerPhoto: userPictureUrl ?
|
ownerPhoto: userPictureUrl ?
|
||||||
|
@ -525,7 +525,7 @@ export default class spservices {
|
||||||
color: CategoryColorValue.length > 0 ? CategoryColorValue[0].color : '#1a75ff', // blue default
|
color: CategoryColorValue.length > 0 ? CategoryColorValue[0].color : '#1a75ff', // blue default
|
||||||
ownerName: event.Author[0].title,
|
ownerName: event.Author[0].title,
|
||||||
attendes: attendees,
|
attendes: attendees,
|
||||||
fAllDayEvent: false,
|
fAllDayEvent: isAllDayEvent,
|
||||||
geolocation: { Longitude: parseFloat(geolocation[0]), Latitude: parseFloat(geolocation[1]) },
|
geolocation: { Longitude: parseFloat(geolocation[0]), Latitude: parseFloat(geolocation[1]) },
|
||||||
Category: event.Category,
|
Category: event.Category,
|
||||||
Duration: event.Duration,
|
Duration: event.Duration,
|
||||||
|
@ -540,6 +540,7 @@ export default class spservices {
|
||||||
let parseEvt: parseRecurrentEvent = new parseRecurrentEvent();
|
let parseEvt: parseRecurrentEvent = new parseRecurrentEvent();
|
||||||
events = parseEvt.parseEvents(events, null, null);
|
events = parseEvt.parseEvents(events, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return Data
|
// Return Data
|
||||||
return events;
|
return events;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -115,6 +115,7 @@ define([], function () {
|
||||||
showMore: "more",
|
showMore: "more",
|
||||||
recurrenceEventLabel: "Recurrence Event",
|
recurrenceEventLabel: "Recurrence Event",
|
||||||
editRecurrenceSeries: "Edit Recurrence Series",
|
editRecurrenceSeries: "Edit Recurrence Series",
|
||||||
|
allDayEventLabel: "All Day Event ?",
|
||||||
ifRecurrenceLabel: "Recurrence ?",
|
ifRecurrenceLabel: "Recurrence ?",
|
||||||
onLabel: "On",
|
onLabel: "On",
|
||||||
offLabel: "Off",
|
offLabel: "Off",
|
||||||
|
|
|
@ -115,6 +115,7 @@ declare interface ICalendarWebPartStrings {
|
||||||
showMore: string;
|
showMore: string;
|
||||||
recurrenceEventLabel: string;
|
recurrenceEventLabel: string;
|
||||||
editRecurrenceSeries: string;
|
editRecurrenceSeries: string;
|
||||||
|
allDayEventLabel: string;
|
||||||
ifRecurrenceLabel: string;
|
ifRecurrenceLabel: string;
|
||||||
onLabel: string;
|
onLabel: string;
|
||||||
offLabel: string;
|
offLabel: string;
|
||||||
|
|
|
@ -114,6 +114,7 @@ define([], function () {
|
||||||
showMore: "mer",
|
showMore: "mer",
|
||||||
recurrenceEventLabel: "Återkommande händelse",
|
recurrenceEventLabel: "Återkommande händelse",
|
||||||
editRecurrenceSeries: "Redigera serie",
|
editRecurrenceSeries: "Redigera serie",
|
||||||
|
allDayEventLabel: "All Day Event ?",
|
||||||
ifRecurrenceLabel: "Återkommande ?",
|
ifRecurrenceLabel: "Återkommande ?",
|
||||||
onLabel: "På",
|
onLabel: "På",
|
||||||
offLabel: "Av",
|
offLabel: "Av",
|
||||||
|
|
|
@ -44,6 +44,14 @@ Site Url of library | Text| yes|
|
||||||
Picture Library| Choice/Dropdown | yes| this is filled with all Picture Libraries (BaseTemplate : 109)
|
Picture Library| Choice/Dropdown | yes| this is filled with all Picture Libraries (BaseTemplate : 109)
|
||||||
number images to load | number| yes | number between 1 and 200
|
number images to load | number| yes | number between 1 and 200
|
||||||
|
|
||||||
|
### react-slick Props
|
||||||
|
|
||||||
|
For all available props, go [here](https://react-slick.neostack.com/docs/api/).
|
||||||
|
|
||||||
|
### react-slick Methods
|
||||||
|
|
||||||
|
For all available methods, go [here](https://react-slick.neostack.com/docs/api#methods)
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
The web part Use PnPjs library, Microsoft Graph API, Office-ui-fabric-react components, react-slick Component
|
The web part Use PnPjs library, Microsoft Graph API, Office-ui-fabric-react components, react-slick Component
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||||
|
|
||||||
.carousel {
|
.carousel {
|
||||||
.container {
|
.container {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
margin: 0px auto;
|
margin: 0px auto;
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
@include ms-Grid-row;
|
@include ms-Grid-row;
|
||||||
@include ms-fontColor-white;
|
@include ms-fontColor-white;
|
||||||
background-color: $ms-color-themeDark;
|
background-color: $ms-color-themeDark;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
@include ms-Grid-col;
|
@include ms-Grid-col;
|
||||||
@include ms-lg10;
|
@include ms-lg10;
|
||||||
|
@ -21,33 +18,27 @@
|
||||||
@include ms-xlPush2;
|
@include ms-xlPush2;
|
||||||
@include ms-lgPush1;
|
@include ms-lgPush1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include ms-font-xl;
|
@include ms-font-xl;
|
||||||
@include ms-fontColor-white;
|
@include ms-fontColor-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subTitle {
|
.subTitle {
|
||||||
@include ms-font-l;
|
@include ms-font-l;
|
||||||
@include ms-fontColor-white;
|
@include ms-fontColor-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
@include ms-font-l;
|
@include ms-font-l;
|
||||||
@include ms-fontColor-white;
|
@include ms-fontColor-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
// Our button
|
// Our button
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
||||||
// Primary Button
|
// Primary Button
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
background-color: $ms-color-themePrimary;
|
background-color: $ms-color-themePrimary;
|
||||||
border-color: $ms-color-themePrimary;
|
border-color: $ms-color-themePrimary;
|
||||||
color: $ms-color-white;
|
color: $ms-color-white;
|
||||||
|
|
||||||
// Basic Button
|
// Basic Button
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -60,7 +51,6 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-weight: $ms-font-weight-semibold;
|
font-weight: $ms-font-weight-semibold;
|
||||||
font-size: $ms-font-size-m;
|
font-size: $ms-font-size-m;
|
||||||
|
@ -72,3 +62,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.slick-next,
|
||||||
|
.slick-prev {
|
||||||
|
background: $ms-color-themePrimary !important;
|
||||||
|
}
|
||||||
|
.slick-dots {
|
||||||
|
position: initial !important;
|
||||||
|
}
|
||||||
|
}
|
|
@ -173,7 +173,7 @@ export default class Carousel extends React.Component<ICarouselProps, ICarouselS
|
||||||
}
|
}
|
||||||
public render(): React.ReactElement<ICarouselProps> {
|
public render(): React.ReactElement<ICarouselProps> {
|
||||||
const sliderSettings = {
|
const sliderSettings = {
|
||||||
dots: false,
|
dots: true,
|
||||||
infinite: true,
|
infinite: true,
|
||||||
speed: 500,
|
speed: 500,
|
||||||
slidesToShow: 1,
|
slidesToShow: 1,
|
||||||
|
@ -181,7 +181,7 @@ export default class Carousel extends React.Component<ICarouselProps, ICarouselS
|
||||||
lazyLoad: 'progressive',
|
lazyLoad: 'progressive',
|
||||||
autoplaySpeed: 3000,
|
autoplaySpeed: 3000,
|
||||||
initialSlide: this.state.photoIndex,
|
initialSlide: this.state.photoIndex,
|
||||||
arrows: false,
|
arrows: true,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
adaptiveHeight: true,
|
adaptiveHeight: true,
|
||||||
useCSS: true,
|
useCSS: true,
|
||||||
|
@ -216,7 +216,7 @@ export default class Carousel extends React.Component<ICarouselProps, ICarouselS
|
||||||
<Label style={{ width: '250px', margin: 'auto', fontSize: FontSizes.size20 }}>No images in the library</Label>
|
<Label style={{ width: '250px', margin: 'auto', fontSize: FontSizes.size20 }}>No images in the library</Label>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
|
<div style={{ width: '100%', height: '100%'}}>
|
||||||
|
|
||||||
<div style={{ width: '100%'}}>
|
<div style={{ width: '100%'}}>
|
||||||
<Slider
|
<Slider
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/version-1.11-green.svg)
|
![SPFx 1.11](https://img.shields.io/badge/version-1.11-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
@ -47,16 +46,13 @@
|
||||||
|
|
||||||
Property |Type|Required| comments
|
Property |Type|Required| comments
|
||||||
--------------------|----|--------|----------
|
--------------------|----|--------|----------
|
||||||
Title | Text| no|WebPart Title
|
Title | Text| No|WebPart Title
|
||||||
searchFirstName | boolean|no| Lastname or Firstname search query
|
searchFirstName | boolean|No| Lastname or Firstname search query
|
||||||
Properties to search | text | no | By default **FirstName,LastName,WorkEmail,Department** are used for search. You can add custom properties separated by comma.
|
Properties to search | text | No | By default **FirstName,LastName,WorkEmail,Department** are used for search. You can add custom properties separated by comma.
|
||||||
Results per page | number | Number of people result to be displayed per page. Max of **20** is allowed, default of **10** is set.
|
Properties to sent as clear text | text | No | By default if the search key has empty spaces, its replaced with **+** before sending it to the search query. The search properties mentioned here will be sent without the empty space replacemnt.
|
||||||
|
Results per page | number | Yes | Number of people result to be displayed per page. Max of **20** is allowed, default of **10** is set.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
The web part use PnPjs library, Office-ui-fabric-react components
|
The web part use PnPjs library, Office-ui-fabric-react components
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
|
@ -71,7 +67,8 @@ Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0.0|July 29, 2019|Initial release
|
1.0.0|July 29, 2019|Initial release
|
||||||
1.0.1|July 19, 2020|Bugfix and mock-service for workbench (```LivePersonaCard``` not supported in workbench)
|
1.0.1|July 19, 2020|Bugfix and mock-service for workbench (```LivePersonaCard``` not supported in workbench)
|
||||||
2.0.0|Sep 18 2020|React hooks, paging, dynamic search props, result alignment using office ui fabric stack.
|
2.0.0.0|Sep 18 2020|React hooks, paging, dynamic search props, result alignment using office ui fabric stack.
|
||||||
|
3.0.0.0|Oct 17 2020|Minor fixes and add the additional web part property.
|
||||||
|
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
@ -89,8 +86,4 @@ Version|Date|Comments
|
||||||
- `gulp package-solution --ship`
|
- `gulp package-solution --ship`
|
||||||
- `Add to AppCatalog and deploy`
|
- `Add to AppCatalog and deploy`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-directory" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-directory" />
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
},
|
},
|
||||||
"name": "Search Directory",
|
"name": "Search Directory",
|
||||||
"id": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
"id": "5b62bc16-3a71-461d-be2f-16bfcb011e8a",
|
||||||
"version": "2.0.0.0",
|
"version": "3.0.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
|
|
|
@ -19,6 +19,7 @@ export interface IDirectoryWebPartProps {
|
||||||
title: string;
|
title: string;
|
||||||
searchFirstName: boolean;
|
searchFirstName: boolean;
|
||||||
searchProps: string;
|
searchProps: string;
|
||||||
|
clearTextSearchProps: string;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ export default class DirectoryWebPart extends BaseClientSideWebPart<
|
||||||
this.properties.title = value;
|
this.properties.title = value;
|
||||||
},
|
},
|
||||||
searchProps: this.properties.searchProps,
|
searchProps: this.properties.searchProps,
|
||||||
|
clearTextSearchProps: this.properties.clearTextSearchProps,
|
||||||
pageSize: this.properties.pageSize
|
pageSize: this.properties.pageSize
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -91,6 +93,13 @@ export default class DirectoryWebPart extends BaseClientSideWebPart<
|
||||||
multiline: false,
|
multiline: false,
|
||||||
resizable: false
|
resizable: false
|
||||||
}),
|
}),
|
||||||
|
PropertyPaneTextField('clearTextSearchProps', {
|
||||||
|
label: strings.ClearTextSearchPropsLabel,
|
||||||
|
description: strings.ClearTextSearchPropsDesc,
|
||||||
|
value: this.properties.clearTextSearchProps,
|
||||||
|
multiline: false,
|
||||||
|
resizable: false
|
||||||
|
}),
|
||||||
PropertyPaneSlider('pageSize', {
|
PropertyPaneSlider('pageSize', {
|
||||||
label: 'Results per page',
|
label: 'Results per page',
|
||||||
showValue: true,
|
showValue: true,
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { IDirectoryProps } from './IDirectoryProps';
|
||||||
import Paging from './Pagination/Paging';
|
import Paging from './Pagination/Paging';
|
||||||
|
|
||||||
const slice: any = require('lodash/slice');
|
const slice: any = require('lodash/slice');
|
||||||
|
const filter: any = require('lodash/filter');
|
||||||
const wrapStackTokens: IStackTokens = { childrenGap: 30 };
|
const wrapStackTokens: IStackTokens = { childrenGap: 30 };
|
||||||
|
|
||||||
const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
||||||
|
@ -131,11 +132,36 @@ const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
||||||
props.searchProps.split(',') : ['FirstName', 'LastName', 'WorkEmail', 'Department'];
|
props.searchProps.split(',') : ['FirstName', 'LastName', 'WorkEmail', 'Department'];
|
||||||
let qryText: string = '';
|
let qryText: string = '';
|
||||||
let finalSearchText: string = searchText ? searchText.replace(/ /g, '+') : searchText;
|
let finalSearchText: string = searchText ? searchText.replace(/ /g, '+') : searchText;
|
||||||
|
if (props.clearTextSearchProps) {
|
||||||
|
let tmpCTProps: string[] = props.clearTextSearchProps.indexOf(',') >= 0 ? props.clearTextSearchProps.split(',') : [props.clearTextSearchProps];
|
||||||
|
if (tmpCTProps.length > 0) {
|
||||||
|
searchProps.map((srchprop, index) => {
|
||||||
|
let ctPresent: any[] = filter(tmpCTProps, (o) => { return o.toLowerCase() == srchprop.toLowerCase(); });
|
||||||
|
if (ctPresent.length > 0) {
|
||||||
|
if(index == searchProps.length - 1) {
|
||||||
|
qryText += `${srchprop}:${searchText}*`;
|
||||||
|
} else qryText += `${srchprop}:${searchText}* OR `;
|
||||||
|
} else {
|
||||||
|
if(index == searchProps.length - 1) {
|
||||||
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
|
} else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
searchProps.map((srchprop, index) => {
|
searchProps.map((srchprop, index) => {
|
||||||
if (index == searchProps.length - 1)
|
if (index == searchProps.length - 1)
|
||||||
qryText += `${srchprop}:${finalSearchText}*`;
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searchProps.map((srchprop, index) => {
|
||||||
|
if (index == searchProps.length - 1)
|
||||||
|
qryText += `${srchprop}:${finalSearchText}*`;
|
||||||
|
else qryText += `${srchprop}:${finalSearchText}* OR `;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(qryText);
|
||||||
const users = await _services.searchUsersNew('', qryText, false);
|
const users = await _services.searchUsersNew('', qryText, false);
|
||||||
setstate({
|
setstate({
|
||||||
...state,
|
...state,
|
||||||
|
@ -252,12 +278,10 @@ const DirectoryHook: React.FC<IDirectoryProps> = (props) => {
|
||||||
}, [state.users, props.pageSize]);
|
}, [state.users, props.pageSize]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("Alpha change");
|
|
||||||
if (alphaKey.length > 0 && alphaKey != "0") _searchByAlphabets(false);
|
if (alphaKey.length > 0 && alphaKey != "0") _searchByAlphabets(false);
|
||||||
}, [alphaKey]);
|
}, [alphaKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("yes");
|
|
||||||
_loadAlphabets();
|
_loadAlphabets();
|
||||||
_searchByAlphabets(true);
|
_searchByAlphabets(true);
|
||||||
}, [props]);
|
}, [props]);
|
||||||
|
|
|
@ -7,5 +7,6 @@ export interface IDirectoryProps {
|
||||||
searchFirstName: boolean;
|
searchFirstName: boolean;
|
||||||
updateProperty: (value: string) => void;
|
updateProperty: (value: string) => void;
|
||||||
searchProps?: string;
|
searchProps?: string;
|
||||||
|
clearTextSearchProps?: string;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ define([], function() {
|
||||||
"LoadingText": "Searching for user. Please wait...",
|
"LoadingText": "Searching for user. Please wait...",
|
||||||
"SearchPropsLabel": "Properties to search",
|
"SearchPropsLabel": "Properties to search",
|
||||||
"SearchPropsDesc": "Enter the properties separated by comma to be used for search",
|
"SearchPropsDesc": "Enter the properties separated by comma to be used for search",
|
||||||
|
"ClearTextSearchPropsLabel":"Properties whose values are not replaced",
|
||||||
|
"ClearTextSearchPropsDesc":"Enter the properties separated by comma to be sent as it is without replacing space with '+'",
|
||||||
"PagingLabel": "Results per page"
|
"PagingLabel": "Results per page"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,8 @@ declare interface IDirectoryWebPartStrings {
|
||||||
LoadingText: string;
|
LoadingText: string;
|
||||||
SearchPropsLabel: string;
|
SearchPropsLabel: string;
|
||||||
SearchPropsDesc: string;
|
SearchPropsDesc: string;
|
||||||
|
ClearTextSearchPropsLabel: string;
|
||||||
|
ClearTextSearchPropsDesc: string;
|
||||||
PagingLabel: string;
|
PagingLabel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
{
|
{
|
||||||
"resource": "Microsoft Graph",
|
"resource": "Microsoft Graph",
|
||||||
"scope": "Directory.AccessAsUser.All"
|
"scope": "Directory.AccessAsUser.All"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resource": "Microsoft Graph",
|
||||||
|
"scope": "User.Read"
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
|
|
|
@ -59,6 +59,8 @@ react-outlook-add-todo-task|Luis Mañez (MVP, [ClearPeople](http://www.clearpeop
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0.0|Jun 3, 2020|Initial release
|
1.0.0|Jun 3, 2020|Initial release
|
||||||
|
1.1.0|Sep 3, 2020|To Do item body coming from email body
|
||||||
|
1.2.0|Oct 16, 2020|To Do item body included a "open in outlook" link
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
|
|
@ -162,8 +162,8 @@ export default class CreateTask extends React.Component<
|
||||||
status: "notStarted",
|
status: "notStarted",
|
||||||
title: taskTitle,
|
title: taskTitle,
|
||||||
body: {
|
body: {
|
||||||
content: this.props.context.item.body,
|
content: this._composeBody(this.props.context.item.body),
|
||||||
contentType: "text",
|
contentType: "html",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,4 +180,10 @@ export default class CreateTask extends React.Component<
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _composeBody(emailBody: string): string {
|
||||||
|
const id: string = encodeURIComponent(this.props.context.item.id);
|
||||||
|
const link: string = `<a href='https://outlook.office365.com/owa/?ItemID=${id}&exvsurl=1&viewmodel=ReadMessageItem'>Open in Outlook</a>`;
|
||||||
|
return `${emailBody}<p style='font-size: large; padding-top: 10px;'>${link}</p>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
"framework": "react",
|
"framework": "react",
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"version": "1.10.0",
|
"version": "1.11.0",
|
||||||
"libraryName": "react-personal-greeting",
|
"libraryName": "react-personal-greeting",
|
||||||
"libraryId": "5e7ea24d-fccc-4d96-a56c-488564d9c61c",
|
"libraryId": "5e7ea24d-fccc-4d96-a56c-488564d9c61c",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
|
|
@ -8,7 +8,7 @@ The web part pulls in the current user's name and displays it on the page. The g
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![1.10.0](https://img.shields.io/badge/version-1.10.0-green.svg)
|
![1.11.0](https://img.shields.io/badge/version-1.11.0-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ react-personal-greeting|Zach Roberts - [SPODev](https://spodev.com)
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
|
1.1|September 24, 2020| Updated SPFX version and added font-size
|
||||||
1.0|April 14, 2020|Initial release
|
1.0|April 14, 2020|Initial release
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
@ -56,7 +57,7 @@ This Web Part illustrates the following concepts on top of the SharePoint Framew
|
||||||
|
|
||||||
* Using the SPFx context to gather the current user's display name.
|
* Using the SPFx context to gather the current user's display name.
|
||||||
* Adjusting the styles of the component in the web part using the props adjusted through the property pane.
|
* Adjusting the styles of the component in the web part using the props adjusted through the property pane.
|
||||||
* PnP SPFx Placeholder - This component allows you to have a placeholder visble under certain conditions if your web parts requires some setup.
|
* PnP SPFx Placeholder - This component allows you to have a placeholder visible under certain conditions if your web parts requires some setup.
|
||||||
* PnP SPFx Color Picker - This component adds an awesome color picker to the property pane, great for adjusting colors in your web part.
|
* PnP SPFx Color Picker - This component adds an awesome color picker to the property pane, great for adjusting colors in your web part.
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-personal-greeting" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-personal-greeting" />
|
||||||
|
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 2.0 MiB |
|
@ -3,9 +3,16 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-personal-greeting-client-side-solution",
|
"name": "react-personal-greeting-client-side-solution",
|
||||||
"id": "5e7ea24d-fccc-4d96-a56c-488564d9c61c",
|
"id": "5e7ea24d-fccc-4d96-a56c-488564d9c61c",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"mpnId": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"websiteUrl": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-personal-greeting.sppkg"
|
"zippedPackage": "solution/react-personal-greeting.sppkg"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-personal-greeting",
|
"name": "react-personal-greeting",
|
||||||
"version": "0.0.1",
|
"version": "1.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -14,19 +14,15 @@
|
||||||
"postversion": "gulp dist"
|
"postversion": "gulp dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.10.0",
|
"@microsoft/sp-core-library": "1.11.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.10.0",
|
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
||||||
"@microsoft/sp-property-pane": "1.10.0",
|
"@microsoft/sp-property-pane": "1.11.0",
|
||||||
"@microsoft/sp-webpart-base": "1.10.0",
|
"@microsoft/sp-webpart-base": "1.11.0",
|
||||||
"@pnp/pnpjs": "^2.0.3",
|
"@pnp/pnpjs": "^2.0.3",
|
||||||
"@pnp/spfx-controls-react": "1.17.0",
|
"@pnp/spfx-controls-react": "1.17.0",
|
||||||
"@pnp/spfx-property-controls": "1.17.0",
|
"@pnp/spfx-property-controls": "1.17.0",
|
||||||
"@types/es6-promise": "0.0.33",
|
"office-ui-fabric-react": "6.214.0",
|
||||||
"@types/react": "16.8.8",
|
|
||||||
"@types/react-dom": "16.8.3",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"office-ui-fabric-react": "6.189.2",
|
|
||||||
"react": "16.8.5",
|
"react": "16.8.5",
|
||||||
"react-dom": "16.8.5"
|
"react-dom": "16.8.5"
|
||||||
},
|
},
|
||||||
|
@ -36,10 +32,10 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/microsoft-graph-types": "^1.12.0",
|
"@microsoft/microsoft-graph-types": "^1.12.0",
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||||
"@microsoft/sp-build-web": "1.10.0",
|
"@microsoft/sp-build-web": "1.11.0",
|
||||||
"@microsoft/sp-module-interfaces": "1.10.0",
|
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||||
"@microsoft/sp-tslint-rules": "1.10.0",
|
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||||
"@microsoft/sp-webpart-workbench": "1.10.0",
|
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||||
"@types/chai": "3.4.34",
|
"@types/chai": "3.4.34",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/mocha": "2.2.38",
|
||||||
"ajv": "~5.2.2",
|
"ajv": "~5.2.2",
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"group": { "default": "Other" },
|
"group": { "default": "Other" },
|
||||||
"title": { "default": "Personal Greeting" },
|
"title": { "default": "Personal Greeting" },
|
||||||
"description": { "default": "Personal Greeting description" },
|
"description": { "default": "Personal Greeting description" },
|
||||||
"officeFabricIconFontName": "Page",
|
"officeFabricIconFontName": "TextDocumentShared",
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": "Personal Greeting"
|
"description": "Personal Greeting"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import { Version } from '@microsoft/sp-core-library';
|
||||||
import {
|
import {
|
||||||
IPropertyPaneConfiguration,
|
IPropertyPaneConfiguration,
|
||||||
PropertyPaneTextField,
|
PropertyPaneTextField,
|
||||||
PropertyPaneDropdown
|
PropertyPaneDropdown,
|
||||||
|
IPropertyPaneDropdownOption
|
||||||
} from '@microsoft/sp-property-pane';
|
} from '@microsoft/sp-property-pane';
|
||||||
import { BaseClientSideWebPart, WebPartContext } from '@microsoft/sp-webpart-base';
|
import { BaseClientSideWebPart, WebPartContext } from '@microsoft/sp-webpart-base';
|
||||||
|
|
||||||
import * as strings from 'PersonalGreetingWebPartStrings';
|
|
||||||
import PersonalGreeting from './components/PersonalGreeting';
|
import PersonalGreeting from './components/PersonalGreeting';
|
||||||
import { IPersonalGreetingProps } from './components/IPersonalGreetingProps';
|
import { IPersonalGreetingProps } from './components/IPersonalGreetingProps';
|
||||||
import { PropertyFieldColorPicker, PropertyFieldColorPickerStyle } from '@pnp/spfx-property-controls/lib/PropertyFieldColorPicker';
|
import { PropertyFieldColorPicker, PropertyFieldColorPickerStyle } from '@pnp/spfx-property-controls/lib/PropertyFieldColorPicker';
|
||||||
|
@ -18,8 +18,56 @@ export interface IPersonalGreetingWebPartProps {
|
||||||
context: WebPartContext;
|
context: WebPartContext;
|
||||||
position: string;
|
position: string;
|
||||||
textColor: string;
|
textColor: string;
|
||||||
|
fontSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fontSizeOptions: IPropertyPaneDropdownOption[] = [
|
||||||
|
{
|
||||||
|
key: 12,
|
||||||
|
text: '12'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 14,
|
||||||
|
text: '16'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 18,
|
||||||
|
text: '18'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 20,
|
||||||
|
text: '20'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 24,
|
||||||
|
text: '24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 28,
|
||||||
|
text: '28'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 32,
|
||||||
|
text: '32'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 36,
|
||||||
|
text: '36'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 42,
|
||||||
|
text: '42'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 46,
|
||||||
|
text: '46'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 68,
|
||||||
|
text: '68'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default class PersonalGreetingWebPart extends BaseClientSideWebPart <IPersonalGreetingWebPartProps> {
|
export default class PersonalGreetingWebPart extends BaseClientSideWebPart <IPersonalGreetingWebPartProps> {
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
@ -29,7 +77,8 @@ export default class PersonalGreetingWebPart extends BaseClientSideWebPart <IPer
|
||||||
greetingText: this.properties.greetingText,
|
greetingText: this.properties.greetingText,
|
||||||
context: this.context,
|
context: this.context,
|
||||||
position: this.properties.position,
|
position: this.properties.position,
|
||||||
textColor: this.properties.textColor
|
textColor: this.properties.textColor,
|
||||||
|
fontSize: this.properties.fontSize
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -76,6 +125,11 @@ export default class PersonalGreetingWebPart extends BaseClientSideWebPart <IPer
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
PropertyPaneDropdown('fontSize', {
|
||||||
|
label: 'Font Size',
|
||||||
|
options: fontSizeOptions,
|
||||||
|
selectedKey: 20
|
||||||
|
}),
|
||||||
PropertyFieldColorPicker('textColor', {
|
PropertyFieldColorPicker('textColor', {
|
||||||
label: 'Text Color',
|
label: 'Text Color',
|
||||||
properties: this.properties,
|
properties: this.properties,
|
||||||
|
|
|
@ -6,4 +6,5 @@ export interface IPersonalGreetingProps {
|
||||||
context: WebPartContext;
|
context: WebPartContext;
|
||||||
position: string;
|
position: string;
|
||||||
textColor: string;
|
textColor: string;
|
||||||
|
fontSize: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
font-size: x-large;
|
|
||||||
font-weight: 375;
|
font-weight: 375;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,22 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styles from './PersonalGreeting.module.scss';
|
import styles from './PersonalGreeting.module.scss';
|
||||||
import { IPersonalGreetingProps } from './IPersonalGreetingProps';
|
import { IPersonalGreetingProps } from './IPersonalGreetingProps';
|
||||||
import { escape } from '@microsoft/sp-lodash-subset';
|
|
||||||
import { CommandBar, ICommandBarItemProps } from 'office-ui-fabric-react/lib/CommandBar';
|
|
||||||
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
|
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
|
||||||
|
|
||||||
|
|
||||||
export default class PersonalGreeting extends React.Component<IPersonalGreetingProps, {}> {
|
export default class PersonalGreeting extends React.Component<IPersonalGreetingProps, {}> {
|
||||||
public render(): React.ReactElement<IPersonalGreetingProps> {
|
public render(): React.ReactElement<IPersonalGreetingProps> {
|
||||||
|
|
||||||
const custstyles = {
|
const custStyles = {
|
||||||
'text-align': this.props.position,
|
'text-align': this.props.position,
|
||||||
'color': this.props.textColor
|
'color': this.props.textColor,
|
||||||
|
'fontSize': this.props.fontSize
|
||||||
} as React.CSSProperties;
|
} as React.CSSProperties;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.personalGreeting }>
|
<div className={ styles.personalGreeting }>
|
||||||
{this.props.greetingText == null ?
|
{this.props.greetingText == null ?
|
||||||
<Placeholder iconName='Edit' iconText='Configure the web part' description='Please configure the web part' buttonLabel='Configure' onConfigure={this._onConfigure} />
|
<Placeholder iconName='Edit' iconText='Configure the web part' description='Please configure the web part' buttonLabel='Configure' onConfigure={this._onConfigure} />
|
||||||
: <div className={ styles.title } style={custstyles}>{this.props.greetingText} {this.props.context.pageContext.user.displayName}</div>
|
: <div className={ styles.title } style={custStyles}>{this.props.greetingText} {this.props.context.pageContext.user.displayName}</div>
|
||||||
// : <h2>{this.props.greetingText} {this.props.context.pageContext.user.displayName} </h2>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
"version": "1.10.0",
|
"version": "1.11.0",
|
||||||
"libraryName": "react-simple-poll",
|
"libraryName": "react-simple-poll",
|
||||||
"libraryId": "890ced10-dacc-4d0d-b9df-355a289980b3",
|
"libraryId": "890ced10-dacc-4d0d-b9df-355a289980b3",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# React Quick Poll
|
# React Quick Poll
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
> This component is developed for the users who really need to create a **_Poll_** within a minute and with less maintenance. **_'QuickPoll'_** list will be created automatically to store the user response.
|
> This component is developed for the users who really need to create a **_Poll_** within a minute and with less maintenance. **_'QuickPoll'_** list will be created automatically to store the user response.
|
||||||
> Following are some of the features of this component.
|
> Following are some of the features of this component.
|
||||||
* **_Easy_** to setup with most of the configurations are optional.
|
* **_Easy_** to setup with most of the configurations are optional.
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
* **_Start Date_** - Date when the end user can start seeing the poll question.
|
* **_Start Date_** - Date when the end user can start seeing the poll question.
|
||||||
* **_End Date_** - Last day of the poll question visible to the end user.
|
* **_End Date_** - Last day of the poll question visible to the end user.
|
||||||
|
|
||||||
3. **_Success Message_** - Message to be displayed to the user after successful submission. It is optional, if not provided the default message '**Thank you for your submission**' will be displayed.
|
3. **_Success Message_** - Message to be displayed to the user after a successful submission. It is optional, if not provided the default message '**Thank you for your submission**' will be displayed.
|
||||||
|
|
||||||
4. **_Response Message_** - Message to be displayed to the user with the user response, once the user has submitted. It is optional, if not provided the default message '**You voted for: ~User Response~**' will be displayed below the chart.
|
4. **_Response Message_** - Message to be displayed to the user with the user response, once the user has submitted. It is optional, if not provided the default message '**You voted for: ~User Response~**' will be displayed below the chart.
|
||||||
|
|
||||||
|
@ -36,33 +37,37 @@
|
||||||
* Make sure the **Multi Choice** option is chosen wisely, do not change once the user started to response to the poll.
|
* Make sure the **Multi Choice** option is chosen wisely, do not change once the user started to response to the poll.
|
||||||
|
|
||||||
## Preview
|
## Preview
|
||||||
![Advanced-Comments-Box](./assets/react-quick-poll.gif)
|
|
||||||
|
![React-Quick-Poll](./assets/react-quick-poll.gif)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
![drop](https://img.shields.io/badge/version-GA-green.svg)
|
|
||||||
|
![SPFx 1.11](https://img.shields.io/badge/version-1.11-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
* [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
|
* [SharePoint Framework](https:/dev.office.com/sharepoint)
|
||||||
* [Office 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
|
* [Office 365 tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment)
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
> **@microsoft/generator-sharepoint - 1.10.0**
|
> **@microsoft/generator-sharepoint - 1.11.0**
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-quick-poll | Sudharsan K.([@sudharsank](https://twitter.com/sudharsank), [Know More](http://windowssharepointserver.blogspot.com/))
|
react-quick-poll | Sudharsan K.([@sudharsank](https://twitter.com/sudharsank), [Know More](https://spknowledge.com/))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0.0.1|Feb 24 2020|Initial release
|
1.0.0.1|Feb 24 2020|Initial release
|
||||||
|
2.0.0.0|Oct 17 2020|Initial release
|
||||||
|
|
||||||
## Disclaimer
|
## 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.**
|
**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
|
## Minimal Path to Awesome
|
||||||
|
@ -71,26 +76,27 @@ Version|Date|Comments
|
||||||
- in the command line run:
|
- in the command line run:
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `gulp bundle --ship && gulp package-solution --ship`
|
- `gulp bundle --ship && gulp package-solution --ship`
|
||||||
- Add the .sppkg file to the app catalog and add the **'_Quick Poll_'** web part to the page.
|
- Add the `.sppkg` file to the app catalog and add the **'_Quick Poll_'** web part to the page.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Used [PnP Property Pane Controls](https://sharepoint.github.io/sp-dev-fx-property-controls/) to create the property pane controls
|
- Used [PnP Property Pane Controls](https://sharepoint.github.io/sp-dev-fx-property-controls/) to create the property pane controls
|
||||||
* [PropertyFieldToggleWithCallout](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldToggleWithCallout/)
|
* [PropertyFieldToggleWithCallout](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldToggleWithCallout/)
|
||||||
* [PropertyFieldCollectionData](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldCollectionData/)
|
* [PropertyFieldCollectionData](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldCollectionData/)
|
||||||
* [PropertyFieldChoiceGroupWithCallout](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldChoiceGroupWithCallout/)
|
* [PropertyFieldChoiceGroupWithCallout](https://sharepoint.github.io/sp-dev-fx-property-controls/controls/PropertyFieldChoiceGroupWithCallout/)
|
||||||
* PropertyPaneTextField (From base property controls)
|
* PropertyPaneTextField (From base property controls)
|
||||||
- Used [PnP Reusable REact Controls](https://sharepoint.github.io/sp-dev-fx-controls-react/)
|
- Used [PnP Reusable React Controls](https://sharepoint.github.io/sp-dev-fx-controls-react/)
|
||||||
* [Placeholder](https://sharepoint.github.io/sp-dev-fx-controls-react/controls/Placeholder/)
|
* [Placeholder](https://sharepoint.github.io/sp-dev-fx-controls-react/controls/Placeholder/)
|
||||||
* [ChartControl](https://sharepoint.github.io/sp-dev-fx-controls-react/controls/ChartControl/)
|
* [ChartControl](https://sharepoint.github.io/sp-dev-fx-controls-react/controls/ChartControl/)
|
||||||
- Used few styles and controls (Text, MessageBar, ProgressIndicator, PrimaryButton, ChoiceGroup, List, Checkbox) from [Office UI Fabric](https://developer.microsoft.com/en-us/fabric)
|
- Used few styles and controls (Text, MessageBar, ProgressIndicator, PrimaryButton, ChoiceGroup, List, Checkbox) from [Office UI Fabric](https://developer.microsoft.com/en-us/fabric)
|
||||||
- Used [PnP](https://pnp.github.io/pnpjs/) for communication with SharePoint.
|
- Used [PnP](https://pnp.github.io/pnpjs/) for communication with SharePoint.
|
||||||
- Used [Moment.js](https://momentjs.com/) for datetime formatting.
|
- Used [Moment.js](https://momentjs.com/) for datetime formatting.
|
||||||
|
|
||||||
#### Local Mode
|
### Local Mode
|
||||||
|
|
||||||
This solution doesn't work on local mode.
|
This solution doesn't work on local mode.
|
||||||
|
|
||||||
#### SharePoint Mode
|
### SharePoint Mode
|
||||||
|
|
||||||
If you want to try on a real environment, open:
|
If you want to try on a real environment, open:
|
||||||
[O365 Workbench](https://your-domain.sharepoint.com/_layouts/15/workbench.aspx)
|
[O365 Workbench](https://your-domain.sharepoint.com/_layouts/15/workbench.aspx)
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-quick-poll" />
|
|
||||||
|
|
|
@ -3,9 +3,16 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "React Quick Poll",
|
"name": "React Quick Poll",
|
||||||
"id": "890ced10-dacc-4d0d-b9df-355a289980b3",
|
"id": "890ced10-dacc-4d0d-b9df-355a289980b3",
|
||||||
"version": "1.0.0.1",
|
"version": "2.0.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "Sudharsan K.",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"websiteUrl": "https://spknowledge.com/",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-quick-poll.sppkg"
|
"zippedPackage": "solution/react-quick-poll.sppkg"
|
||||||
|
|
|
@ -12,20 +12,17 @@
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.10.0",
|
"@microsoft/sp-core-library": "1.11.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.10.0",
|
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
||||||
"@microsoft/sp-property-pane": "1.10.0",
|
"@microsoft/sp-property-pane": "1.11.0",
|
||||||
"@microsoft/sp-webpart-base": "1.10.0",
|
"@microsoft/sp-webpart-base": "1.11.0",
|
||||||
|
"@pnp/polyfill-ie11": "^2.0.1-5",
|
||||||
"@pnp/sp": "^2.0.2",
|
"@pnp/sp": "^2.0.2",
|
||||||
"@pnp/spfx-controls-react": "^1.16.0",
|
"@pnp/spfx-controls-react": "^1.16.0",
|
||||||
"@pnp/spfx-property-controls": "^1.16.0",
|
"@pnp/spfx-property-controls": "^1.16.0",
|
||||||
"@types/es6-promise": "0.0.33",
|
|
||||||
"@types/react": "16.8.8",
|
|
||||||
"@types/react-dom": "16.8.3",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"office-ui-fabric-react": "6.189.2",
|
"office-ui-fabric-react": "6.214.0",
|
||||||
"react": "16.8.5",
|
"react": "16.8.5",
|
||||||
"react-dom": "16.8.5"
|
"react-dom": "16.8.5"
|
||||||
},
|
},
|
||||||
|
@ -33,14 +30,14 @@
|
||||||
"@types/react": "16.8.8"
|
"@types/react": "16.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "1.10.0",
|
|
||||||
"@microsoft/sp-tslint-rules": "1.10.0",
|
|
||||||
"@microsoft/sp-module-interfaces": "1.10.0",
|
|
||||||
"@microsoft/sp-webpart-workbench": "1.10.0",
|
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||||
"gulp": "~3.9.1",
|
"@microsoft/sp-build-web": "1.11.0",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||||
"@types/chai": "3.4.34",
|
"@types/chai": "3.4.34",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/mocha": "2.2.38",
|
||||||
"ajv": "~5.2.2"
|
"ajv": "~5.2.2",
|
||||||
|
"gulp": "~3.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { PropertyFieldToggleWithCallout } from '@pnp/spfx-property-controls/lib/
|
||||||
import { PropertyFieldChoiceGroupWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldChoiceGroupWithCallout';
|
import { PropertyFieldChoiceGroupWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldChoiceGroupWithCallout';
|
||||||
import { PropertyFieldCollectionData, CustomCollectionFieldType } from '@pnp/spfx-property-controls/lib/PropertyFieldCollectionData';
|
import { PropertyFieldCollectionData, CustomCollectionFieldType } from '@pnp/spfx-property-controls/lib/PropertyFieldCollectionData';
|
||||||
import { DateTimePicker, DateConvention, TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker';
|
import { DateTimePicker, DateConvention, TimeConvention } from '@pnp/spfx-controls-react/lib/DateTimePicker';
|
||||||
|
import "@pnp/polyfill-ie11";
|
||||||
import { sp } from "@pnp/sp/presets/all";
|
import { sp } from "@pnp/sp/presets/all";
|
||||||
import * as strings from 'SimplePollWebPartStrings';
|
import * as strings from 'SimplePollWebPartStrings';
|
||||||
import SimplePoll from './components/SimplePoll';
|
import SimplePoll from './components/SimplePoll';
|
||||||
|
@ -35,7 +36,10 @@ export default class SimplePollWebPart extends BaseClientSideWebPart<ISimplePoll
|
||||||
private userinfo: IUserInfo = null;
|
private userinfo: IUserInfo = null;
|
||||||
protected async onInit(): Promise<void> {
|
protected async onInit(): Promise<void> {
|
||||||
await super.onInit();
|
await super.onInit();
|
||||||
sp.setup(this.context);
|
sp.setup({
|
||||||
|
ie11: true,
|
||||||
|
spfxContext: this.context
|
||||||
|
});
|
||||||
this.helper = new SPHelper();
|
this.helper = new SPHelper();
|
||||||
this.userinfo = await this.helper.getCurrentUserInfo();
|
this.userinfo = await this.helper.getCurrentUserInfo();
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,7 @@ export default class SimplePollWebPart extends BaseClientSideWebPart<ISimplePoll
|
||||||
React.createElement("div", null,
|
React.createElement("div", null,
|
||||||
React.createElement("textarea",
|
React.createElement("textarea",
|
||||||
{
|
{
|
||||||
style: { width: "250px", height: "70px" },
|
style: { width: "220px", height: "70px" },
|
||||||
placeholder: strings.Q_Title_Placeholder,
|
placeholder: strings.Q_Title_Placeholder,
|
||||||
key: itemId,
|
key: itemId,
|
||||||
value: value,
|
value: value,
|
||||||
|
@ -135,7 +139,7 @@ export default class SimplePollWebPart extends BaseClientSideWebPart<ISimplePoll
|
||||||
React.createElement("div", null,
|
React.createElement("div", null,
|
||||||
React.createElement("textarea",
|
React.createElement("textarea",
|
||||||
{
|
{
|
||||||
style: { width: "250px", height: "70px" },
|
style: { width: "220px", height: "70px" },
|
||||||
placeholder: strings.Q_Options_Placeholder,
|
placeholder: strings.Q_Options_Placeholder,
|
||||||
key: itemId,
|
key: itemId,
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -40,18 +40,23 @@ export default class OptionsContainer extends React.Component<IOptionsContainerP
|
||||||
private getOptions = (): string[] => {
|
private getOptions = (): string[] => {
|
||||||
let tempChoices: string[] = [];
|
let tempChoices: string[] = [];
|
||||||
if (this.props.options.indexOf(',') >= 0) {
|
if (this.props.options.indexOf(',') >= 0) {
|
||||||
tempChoices = this.props.options.split(',');
|
let tmpChoices = this.props.options.split(',');
|
||||||
|
tmpChoices.map(choice => {
|
||||||
|
if (choice && choice.trim().length > 0) tempChoices.push(choice);
|
||||||
|
});
|
||||||
} else tempChoices.push(this.props.options);
|
} else tempChoices.push(this.props.options);
|
||||||
return tempChoices;
|
return tempChoices;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onRenderCell = (item: any, index: number | undefined): JSX.Element => {
|
private _onRenderCell = (item: any, index: number | undefined): JSX.Element => {
|
||||||
|
if (item && item.length > 0) {
|
||||||
return (
|
return (
|
||||||
<div style={{ marginBottom: "15px" }}>
|
<div style={{ marginBottom: "15px" }}>
|
||||||
<Checkbox label={item} onChange={this._makeChangeHandler(item)} />
|
<Checkbox label={item} onChange={this._makeChangeHandler(item)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private onRenderChoiceOptions(): IChoiceGroupOption[] {
|
private onRenderChoiceOptions(): IChoiceGroupOption[] {
|
||||||
let choices: IChoiceGroupOption[] = [];
|
let choices: IChoiceGroupOption[] = [];
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
# Upgrade project react-simple-poll to v1.11.0
|
||||||
|
|
||||||
|
Date: 10/16/2020
|
||||||
|
|
||||||
|
## Findings
|
||||||
|
|
||||||
|
Following is the list of steps required to upgrade your project to SharePoint Framework version 1.11.0. [Summary](#Summary) of the modifications is included at the end of the report.
|
||||||
|
|
||||||
|
### FN001001 @microsoft/sp-core-library | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-core-library
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001002 @microsoft/sp-lodash-subset | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-lodash-subset
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-lodash-subset@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001003 @microsoft/sp-office-ui-fabric-core | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-office-ui-fabric-core
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-office-ui-fabric-core@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001004 @microsoft/sp-webpart-base | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-webpart-base
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-webpart-base@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001005 @types/react | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/react
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001006 @types/react-dom | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/react-dom
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/react-dom
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001007 @types/webpack-env | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/webpack-env
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/webpack-env
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001010 @types/es6-promise | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/es6-promise
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/es6-promise
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001021 @microsoft/sp-property-pane | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-property-pane
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-property-pane@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001022 office-ui-fabric-react | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package office-ui-fabric-react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE office-ui-fabric-react@6.214.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002001 @microsoft/sp-build-web | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-build-web
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-build-web@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002002 @microsoft/sp-module-interfaces | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-module-interfaces
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-module-interfaces@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002003 @microsoft/sp-webpart-workbench | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-webpart-workbench
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-webpart-workbench@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002009 @microsoft/sp-tslint-rules | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-tslint-rules
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-tslint-rules@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002013 @types/webpack-env | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/webpack-env
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/webpack-env@1.13.1
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002014 @types/es6-promise | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/es6-promise
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/es6-promise@0.0.33
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002015 @types/react | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/react@16.8.8
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002016 @types/react-dom | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/react-dom
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/react-dom@16.8.3
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN006004 package-solution.json developer | Optional
|
||||||
|
|
||||||
|
In package-solution.json add developer section
|
||||||
|
|
||||||
|
In file [./config/package-solution.json](./config/package-solution.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"solution": {
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./config/package-solution.json](./config/package-solution.json)
|
||||||
|
|
||||||
|
### FN010001 .yo-rc.json version | Recommended
|
||||||
|
|
||||||
|
Update version in .yo-rc.json
|
||||||
|
|
||||||
|
In file [./.yo-rc.json](./.yo-rc.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.11.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./.yo-rc.json](./.yo-rc.json)
|
||||||
|
|
||||||
|
### FN012012 tsconfig.json include property | Required
|
||||||
|
|
||||||
|
Update tsconfig.json include property
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN017001 Run npm dedupe | Optional
|
||||||
|
|
||||||
|
If, after upgrading npm packages, when building the project you have errors similar to: "error TS2345: Argument of type 'SPHttpClientConfiguration' is not assignable to parameter of type 'SPHttpClientConfiguration'", try running 'npm dedupe' to cleanup npm packages.
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm dedupe
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
### Execute script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.11.0 @microsoft/sp-lodash-subset@1.11.0 @microsoft/sp-office-ui-fabric-core@1.11.0 @microsoft/sp-webpart-base@1.11.0 @microsoft/sp-property-pane@1.11.0 office-ui-fabric-react@6.214.0
|
||||||
|
npm i -DE @microsoft/sp-build-web@1.11.0 @microsoft/sp-module-interfaces@1.11.0 @microsoft/sp-webpart-workbench@1.11.0 @microsoft/sp-tslint-rules@1.11.0 @types/webpack-env@1.13.1 @types/es6-promise@0.0.33 @types/react@16.8.8 @types/react-dom@16.8.3
|
||||||
|
npm un -S @types/react @types/react-dom @types/webpack-env @types/es6-promise
|
||||||
|
npm dedupe
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modify files
|
||||||
|
|
||||||
|
#### [./config/package-solution.json](./config/package-solution.json)
|
||||||
|
|
||||||
|
In package-solution.json add developer section:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"solution": {
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [./.yo-rc.json](./.yo-rc.json)
|
||||||
|
|
||||||
|
Update version in .yo-rc.json:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.11.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
Update tsconfig.json include property:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,25 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
|
||||||
|
# change these settings to your own preference
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# we recommend you to keep these unchanged
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[{package,bower}.json]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Build generated files
|
||||||
|
dist
|
||||||
|
lib
|
||||||
|
solution
|
||||||
|
temp
|
||||||
|
*.sppkg
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Visual Studio files
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
.vs
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
|
||||||
|
# Resx Generated Code
|
||||||
|
*.resx.ts
|
||||||
|
|
||||||
|
# Styles Generated Code
|
||||||
|
*.scss.ts
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.11.0",
|
||||||
|
"libraryName": "react-tailwindcss",
|
||||||
|
"libraryId": "62daa1f6-c9b4-4664-b101-37ccbddb47da",
|
||||||
|
"environment": "spo",
|
||||||
|
"packageManager": "npm",
|
||||||
|
"isCreatingSolution": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"componentType": "webpart"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
page_type: sample
|
||||||
|
products:
|
||||||
|
- office-sp
|
||||||
|
languages:
|
||||||
|
- javascript
|
||||||
|
- typescript
|
||||||
|
extensions:
|
||||||
|
contentType: samples
|
||||||
|
technologies:
|
||||||
|
- SharePoint Framework
|
||||||
|
- TailWind CSS
|
||||||
|
platforms:
|
||||||
|
- React
|
||||||
|
createdDate: 10/17/2020 12:00:00 AM
|
||||||
|
---
|
||||||
|
|
||||||
|
# react-tailwindcss
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This project shows how to integrate [Tailwind CSS](https://tailwindcss.com/) framework into a SPFx React project by:
|
||||||
|
- Create a custom Tailwind CSS config file
|
||||||
|
- Create a custom Gulp Task to process the Tailwind CSS generated file and optimize it
|
||||||
|
- Using CSS custom properties to manage in Tailwind CSS Classes the Theme Variant into sections
|
||||||
|
- Avoid writing SASS but only use Tailwind CSS classes to style components
|
||||||
|
|
||||||
|
![WebPart](./assets/react-tailwindcss-overview.gif)
|
||||||
|
|
||||||
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
|
![SPFx 1.11](https://img.shields.io/badge/version-1.11-green.svg)
|
||||||
|
|
||||||
|
## Applies to
|
||||||
|
|
||||||
|
- [SharePoint Framework](https://aka.ms/spfx)
|
||||||
|
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
|
||||||
|
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Basic knowledge of [Tailwind CSS](https://tailwindcss.com/)
|
||||||
|
- Basic knowledge of [GulpJs](https://gulpjs.com/)
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Solution|Author(s)
|
||||||
|
--------|---------
|
||||||
|
react-tailwindcss | Fabio Franzini, [@franzinifabio](https://twitter.com/franzinifabio)
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Version|Date|Comments
|
||||||
|
-------|----|--------
|
||||||
|
1.0|October 17, 2020|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
|
||||||
|
- Ensure that you are at the solution folder
|
||||||
|
- in the command-line run:
|
||||||
|
- **npm install**
|
||||||
|
- **gulp serve**
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Getting started with Tailwind CSS](https://tailwindcss.com/)
|
||||||
|
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||||
|
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
|
||||||
|
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
|
||||||
|
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
||||||
|
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
||||||
|
|
||||||
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-tailwindcss" />
|
After Width: | Height: | Size: 13 MiB |
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||||
|
"version": "2.0",
|
||||||
|
"bundles": {
|
||||||
|
"hello-tailwind-web-part": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"entrypoint": "./lib/webparts/HelloTailwindCss/HelloTailwindCssWebPart.js",
|
||||||
|
"manifest": "./src/webparts/HelloTailwindCss/HelloTailwindCssWebPart.manifest.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externals": {},
|
||||||
|
"localizedResources": {
|
||||||
|
"HelloTailwindCssWebPartStrings": "lib/webparts/HelloTailwindCss/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-tailwindcss",
|
||||||
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
|
"solution": {
|
||||||
|
"name": "react-tailwindcss-client-side-solution",
|
||||||
|
"id": "62daa1f6-c9b4-4664-b101-37ccbddb47da",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"includeClientSideAssets": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"mpnId": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"zippedPackage": "solution/react-tailwindcss.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,24 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const build = require('@microsoft/sp-build-web');
|
||||||
|
|
||||||
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
|
// Step 1 + './src/tailwind.css' + './tailwind.config.js'
|
||||||
|
let tailwindBuild = build.subTask('build-tailwind', (gulp, buildOptions, done) => {
|
||||||
|
const postcss = require('gulp-postcss');
|
||||||
|
|
||||||
|
gulp.src(`${buildOptions.srcFolder}/tailwind.css`)
|
||||||
|
.pipe(postcss([
|
||||||
|
require('tailwindcss')('./tailwind.config.js'),
|
||||||
|
require('gulp-autoprefixer')
|
||||||
|
]))
|
||||||
|
.pipe(gulp.dest(buildOptions.libFolder));
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
build.rig.addPostBuildTask(tailwindBuild);
|
||||||
|
// End Step 1
|
||||||
|
|
||||||
|
build.initialize(require('gulp'));
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"name": "react-tailwindcss",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "npm run tailwind:css && gulp bundle",
|
||||||
|
"clean": "gulp clean",
|
||||||
|
"test": "gulp test",
|
||||||
|
"build:tailwind": "postcss tailwind.source.css -o src/tailwind.css"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@microsoft/sp-core-library": "1.11.0",
|
||||||
|
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||||
|
"@microsoft/sp-office-ui-fabric-core": "^1.11.0",
|
||||||
|
"@microsoft/sp-property-pane": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-base": "1.11.0",
|
||||||
|
"office-ui-fabric-react": "6.214.0",
|
||||||
|
"react": "16.8.5",
|
||||||
|
"react-dom": "16.8.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||||
|
"@microsoft/sp-build-web": "1.11.0",
|
||||||
|
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||||
|
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||||
|
"@types/chai": "3.4.34",
|
||||||
|
"@types/es6-promise": "0.0.33",
|
||||||
|
"@types/mocha": "2.2.38",
|
||||||
|
"@types/react": "16.8.8",
|
||||||
|
"@types/react-dom": "16.8.3",
|
||||||
|
"@types/webpack-env": "1.13.1",
|
||||||
|
"ajv": "~5.2.2",
|
||||||
|
"gulp": "~3.9.1",
|
||||||
|
"gulp-autoprefixer": "^7.0.1",
|
||||||
|
"gulp-postcss": "^8.0.0",
|
||||||
|
"gulp-sass": "^4.1.0",
|
||||||
|
"tailwindcss": "^1.8.10"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,136 @@
|
||||||
|
@import "tailwindcss/components";
|
||||||
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--tw-fui-themeDarker: #004578;
|
||||||
|
--tw-fui-themeDark: #005a9e;
|
||||||
|
--tw-fui-themeDarkAlt: #106ebe;
|
||||||
|
--tw-fui-themePrimary: #0078d4;
|
||||||
|
--tw-fui-themeSecondary: #2b88d8;
|
||||||
|
--tw-fui-themeTertiary: #71afe5;
|
||||||
|
--tw-fui-themeLight: #c7e0f4;
|
||||||
|
--tw-fui-themeLighter: #deecf9;
|
||||||
|
--tw-fui-themeLighterAlt: #eff6fc;
|
||||||
|
--tw-fui-black: #000000;
|
||||||
|
--tw-fui-blackTranslucent40: rgba(0, 0, 0, .4);
|
||||||
|
--tw-fui-neutralDark: #212121;
|
||||||
|
--tw-fui-neutralPrimary: #333333;
|
||||||
|
--tw-fui-neutralPrimaryAlt: #3c3c3c;
|
||||||
|
--tw-fui-neutralSecondary: #666666;
|
||||||
|
--tw-fui-neutralSecondaryAlt: #767676;
|
||||||
|
--tw-fui-neutralTertiary: #a6a6a6;
|
||||||
|
--tw-fui-neutralTertiaryAlt: #c8c8c8;
|
||||||
|
--tw-fui-neutralQuaternary: #d0d0d0;
|
||||||
|
--tw-fui-neutralQuaternaryAlt: #dadada;
|
||||||
|
--tw-fui-neutralLight: #eaeaea;
|
||||||
|
--tw-fui-neutralLighter: #f4f4f4;
|
||||||
|
--tw-fui-neutralLighterAlt: #f8f8f8;
|
||||||
|
--tw-fui-accent: #0078d4;
|
||||||
|
--tw-fui-white: #ffffff;
|
||||||
|
--tw-fui-whiteTranslucent40: rgba(255, 255, 255, .4);
|
||||||
|
--tw-fui-yellow: #ffb900;
|
||||||
|
--tw-fui-yellowLight: #fff100;
|
||||||
|
--tw-fui-orange: #d83b01;
|
||||||
|
--tw-fui-orangeLight: #ea4300;
|
||||||
|
--tw-fui-orangeLighter: #ff8c00;
|
||||||
|
--tw-fui-redDark: #a80000;
|
||||||
|
--tw-fui-red: #e81123;
|
||||||
|
--tw-fui-magentaDark: #5c005c;
|
||||||
|
--tw-fui-magenta: #b4009e;
|
||||||
|
--tw-fui-magentaLight: #e3008c;
|
||||||
|
--tw-fui-purpleDark: #32145a;
|
||||||
|
--tw-fui-purple: #5c2d91;
|
||||||
|
--tw-fui-purpleLight: #b4a0ff;
|
||||||
|
--tw-fui-blueDark: #002050;
|
||||||
|
--tw-fui-blueMid: #00188f;
|
||||||
|
--tw-fui-blue: #0078d4;
|
||||||
|
--tw-fui-blueLight: #00bcf2;
|
||||||
|
--tw-fui-tealDark: #004b50;
|
||||||
|
--tw-fui-teal: #008272;
|
||||||
|
--tw-fui-tealLight: #00b294;
|
||||||
|
--tw-fui-greenDark: #004b1c;
|
||||||
|
--tw-fui-green: #107c10;
|
||||||
|
--tw-fui-greenLight: #bad80a;
|
||||||
|
/* ***** */
|
||||||
|
--tw-fui-bodyBackground: #ffffff;
|
||||||
|
--tw-fui-bodyStandoutBackground: #f8f8f8;
|
||||||
|
--tw-fui-bodyFrameBackground: #ffffff;
|
||||||
|
--tw-fui-bodyFrameDivider: #eaeaea;
|
||||||
|
--tw-fui-bodyText: #333333;
|
||||||
|
--tw-fui-bodyTextChecked: #000000;
|
||||||
|
--tw-fui-bodySubtext: #666666;
|
||||||
|
--tw-fui-bodyDivider: #eaeaea;
|
||||||
|
--tw-fui-disabledBackground: #f4f4f4;
|
||||||
|
--tw-fui-disabledText: #a6a6a6;
|
||||||
|
--tw-fui-disabledSubtext: #d0d0d0;
|
||||||
|
--tw-fui-disabledBodyText: #a6a6a6;
|
||||||
|
--tw-fui-disabledBodySubtext: #c8c8c8;
|
||||||
|
--tw-fui-focusBorder: #666666;
|
||||||
|
--tw-fui-variantBorder: #eaeaea;
|
||||||
|
--tw-fui-variantBorderHovered: #a6a6a6;
|
||||||
|
--tw-fui-defaultStateBackground: #f8f8f8;
|
||||||
|
--tw-fui-errorText: #a80000;
|
||||||
|
--tw-fui-warningText: #333333;
|
||||||
|
--tw-fui-errorBackground: rgba(232, 17, 35, .2);
|
||||||
|
--tw-fui-blockingBackground: rgba(234, 67, 0, .2);
|
||||||
|
--tw-fui-warningBackground: rgba(255, 185, 0, .2);
|
||||||
|
--tw-fui-warningHighlight: #ffb900;
|
||||||
|
--tw-fui-successBackground: rgba(186, 216, 10, .2);
|
||||||
|
--tw-fui-inputBorder: #a6a6a6;
|
||||||
|
--tw-fui-inputBorderHovered: #333333;
|
||||||
|
--tw-fui-inputBackground: #ffffff;
|
||||||
|
--tw-fui-inputBackgroundChecked: #0078d4;
|
||||||
|
--tw-fui-inputBackgroundCheckedHovered: #106ebe;
|
||||||
|
--tw-fui-inputForegroundChecked: #ffffff;
|
||||||
|
--tw-fui-inputFocusBorderAlt: #0078d4;
|
||||||
|
--tw-fui-smallInputBorder: #666666;
|
||||||
|
--tw-fui-inputText: #333333;
|
||||||
|
--tw-fui-inputTextHovered: #212121;
|
||||||
|
--tw-fui-inputPlaceholderText: #666666;
|
||||||
|
--tw-fui-buttonBackground: #f4f4f4;
|
||||||
|
--tw-fui-buttonBackgroundChecked: #c8c8c8;
|
||||||
|
--tw-fui-buttonBackgroundHovered: #eaeaea;
|
||||||
|
--tw-fui-buttonBackgroundCheckedHovered: #eaeaea;
|
||||||
|
--tw-fui-buttonBackgroundPressed: #eaeaea;
|
||||||
|
--tw-fui-buttonBackgroundDisabled: #f4f4f4;
|
||||||
|
--tw-fui-buttonBorder: transparent;
|
||||||
|
--tw-fui-buttonText: #333333;
|
||||||
|
--tw-fui-buttonTextHovered: #212121;
|
||||||
|
--tw-fui-buttonTextChecked: #212121;
|
||||||
|
--tw-fui-buttonTextCheckedHovered: #000000;
|
||||||
|
--tw-fui-buttonTextPressed: #212121;
|
||||||
|
--tw-fui-buttonTextDisabled: #a6a6a6;
|
||||||
|
--tw-fui-buttonBorderDisabled: transparent;
|
||||||
|
--tw-fui-primaryButtonBackground: #0078d4;
|
||||||
|
--tw-fui-primaryButtonBackgroundHovered: #106ebe;
|
||||||
|
--tw-fui-primaryButtonBackgroundPressed: #005a9e;
|
||||||
|
--tw-fui-primaryButtonBackgroundDisabled: #f4f4f4;
|
||||||
|
--tw-fui-primaryButtonBorder: transparent;
|
||||||
|
--tw-fui-primaryButtonText: #ffffff;
|
||||||
|
--tw-fui-primaryButtonTextHovered: #ffffff;
|
||||||
|
--tw-fui-primaryButtonTextPressed: #ffffff;
|
||||||
|
--tw-fui-primaryButtonTextDisabled: #d0d0d0;
|
||||||
|
--tw-fui-accentButtonBackground: #0078d4;
|
||||||
|
--tw-fui-accentButtonText: #ffffff;
|
||||||
|
--tw-fui-menuBackground: #ffffff;
|
||||||
|
--tw-fui-menuDivider: #c8c8c8;
|
||||||
|
--tw-fui-menuIcon: #0078d4;
|
||||||
|
--tw-fui-menuHeader: #0078d4;
|
||||||
|
--tw-fui-menuItemBackgroundHovered: #f4f4f4;
|
||||||
|
--tw-fui-menuItemBackgroundPressed: #eaeaea;
|
||||||
|
--tw-fui-menuItemText: #333333;
|
||||||
|
--tw-fui-menuItemTextHovered: #212121;
|
||||||
|
--tw-fui-listBackground: #ffffff;
|
||||||
|
--tw-fui-listText: #333333;
|
||||||
|
--tw-fui-listItemBackgroundHovered: #f4f4f4;
|
||||||
|
--tw-fui-listItemBackgroundChecked: #eaeaea;
|
||||||
|
--tw-fui-listItemBackgroundCheckedHovered: #dadada;
|
||||||
|
--tw-fui-listHeaderBackgroundHovered: #f4f4f4;
|
||||||
|
--tw-fui-listHeaderBackgroundPressed: #eaeaea;
|
||||||
|
--tw-fui-actionLink: #333333;
|
||||||
|
--tw-fui-actionLinkHovered: #212121;
|
||||||
|
--tw-fui-link: #0078d4;
|
||||||
|
--tw-fui-linkHovered: #004578;
|
||||||
|
--tw-fui-listTextColor: #333333;
|
||||||
|
--tw-fui-menuItemBackgroundChecked: #eaeaea;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
|
"id": "acebbfec-5fc8-42b0-94e5-cfbc43222cae",
|
||||||
|
"alias": "HelloTailwindCssWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
"supportsThemeVariants": true,
|
||||||
|
// 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": "Hello TailwindCss" },
|
||||||
|
"description": { "default": "Hello TailwindCss description" },
|
||||||
|
"officeFabricIconFontName": "Duststorm",
|
||||||
|
"properties": {
|
||||||
|
"description": "Hello TailwindCss"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDom from 'react-dom';
|
||||||
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
|
import {
|
||||||
|
IPropertyPaneConfiguration,
|
||||||
|
PropertyPaneTextField
|
||||||
|
} from '@microsoft/sp-property-pane';
|
||||||
|
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||||
|
import * as strings from 'HelloTailwindCssWebPartStrings';
|
||||||
|
import HelloTailwindCss from './components/HelloTailwindCss';
|
||||||
|
import { IHelloTailwindCssProps } from './components/IHelloTailwindCssProps';
|
||||||
|
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||||
|
|
||||||
|
|
||||||
|
export interface IHelloTailwindCssWebPartProps {
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class HelloTailwindCssWebPart extends BaseClientSideWebPart<IHelloTailwindCssWebPartProps> {
|
||||||
|
|
||||||
|
private _themeProvider: ThemeProvider;
|
||||||
|
private _themeVariant: IReadonlyTheme | undefined;
|
||||||
|
|
||||||
|
protected onInit(): Promise<void> {
|
||||||
|
// Consume the new ThemeProvider service
|
||||||
|
this._themeProvider = this.context.serviceScope.consume(ThemeProvider.serviceKey);
|
||||||
|
|
||||||
|
// If it exists, get the theme variant
|
||||||
|
this._themeVariant = this._themeProvider.tryGetTheme();
|
||||||
|
|
||||||
|
// Register a handler to be notified if the theme variant changes
|
||||||
|
this._themeProvider.themeChangedEvent.add(this, this._handleThemeChangedEvent);
|
||||||
|
|
||||||
|
// Apply theme variant as CSS Variables at current DOM node
|
||||||
|
this._applyThemeVariant();
|
||||||
|
|
||||||
|
return super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
|
||||||
|
this._themeVariant = args.theme;
|
||||||
|
this._applyThemeVariant();
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _applyThemeVariant() {
|
||||||
|
let style = this.domElement.style;
|
||||||
|
|
||||||
|
style.setProperty('--tw-fui-themeDarker', this._themeVariant.palette.themeDarker);
|
||||||
|
style.setProperty('--tw-fui-themeDark', this._themeVariant.palette.themeDark);
|
||||||
|
style.setProperty('--tw-fui-themeDarkAlt', this._themeVariant.palette.themeDarkAlt);
|
||||||
|
style.setProperty('--tw-fui-themePrimary', this._themeVariant.palette.themePrimary);
|
||||||
|
style.setProperty('--tw-fui-themeSecondary', this._themeVariant.palette.themeSecondary);
|
||||||
|
style.setProperty('--tw-fui-themeTertiary', this._themeVariant.palette.themeTertiary);
|
||||||
|
style.setProperty('--tw-fui-themeLight', this._themeVariant.palette.themeLight);
|
||||||
|
style.setProperty('--tw-fui-themeLighter', this._themeVariant.palette.themeLighter);
|
||||||
|
style.setProperty('--tw-fui-themeLighterAlt', this._themeVariant.palette.themeLighterAlt);
|
||||||
|
style.setProperty('--tw-fui-black', this._themeVariant.palette.black);
|
||||||
|
style.setProperty('--tw-fui-blackTranslucent40', this._themeVariant.palette.blackTranslucent40);
|
||||||
|
style.setProperty('--tw-fui-neutralDark', this._themeVariant.palette.neutralDark);
|
||||||
|
style.setProperty('--tw-fui-neutralPrimary', this._themeVariant.palette.neutralPrimary);
|
||||||
|
style.setProperty('--tw-fui-neutralPrimaryAlt', this._themeVariant.palette.neutralPrimaryAlt);
|
||||||
|
style.setProperty('--tw-fui-neutralSecondary', this._themeVariant.palette.neutralSecondary);
|
||||||
|
style.setProperty('--tw-fui-neutralSecondaryAlt', this._themeVariant.palette.neutralSecondaryAlt);
|
||||||
|
style.setProperty('--tw-fui-neutralTertiary', this._themeVariant.palette.neutralTertiary);
|
||||||
|
style.setProperty('--tw-fui-neutralTertiaryAlt', this._themeVariant.palette.neutralTertiaryAlt);
|
||||||
|
style.setProperty('--tw-fui-neutralQuaternary', this._themeVariant.palette.neutralQuaternary);
|
||||||
|
style.setProperty('--tw-fui-neutralQuaternaryAlt', this._themeVariant.palette.neutralQuaternaryAlt);
|
||||||
|
style.setProperty('--tw-fui-neutralLight', this._themeVariant.palette.neutralLight);
|
||||||
|
style.setProperty('--tw-fui-neutralLighter', this._themeVariant.palette.neutralLighter);
|
||||||
|
style.setProperty('--tw-fui-neutralLighterAlt', this._themeVariant.palette.neutralLighterAlt);
|
||||||
|
style.setProperty('--tw-fui-accent', this._themeVariant.palette.accent);
|
||||||
|
style.setProperty('--tw-fui-white', this._themeVariant.palette.white);
|
||||||
|
style.setProperty('--tw-fui-whiteTranslucent40', this._themeVariant.palette.whiteTranslucent40);
|
||||||
|
style.setProperty('--tw-fui-yellow', this._themeVariant.palette.yellow);
|
||||||
|
style.setProperty('--tw-fui-yellowLight', this._themeVariant.palette.yellowLight);
|
||||||
|
style.setProperty('--tw-fui-orange', this._themeVariant.palette.orange);
|
||||||
|
style.setProperty('--tw-fui-orangeLight', this._themeVariant.palette.orangeLight);
|
||||||
|
style.setProperty('--tw-fui-orangeLighter', this._themeVariant.palette.orangeLighter);
|
||||||
|
style.setProperty('--tw-fui-redDark', this._themeVariant.palette.redDark);
|
||||||
|
style.setProperty('--tw-fui-red', this._themeVariant.palette.red);
|
||||||
|
style.setProperty('--tw-fui-magentaDark', this._themeVariant.palette.magentaDark);
|
||||||
|
style.setProperty('--tw-fui-magenta', this._themeVariant.palette.magenta);
|
||||||
|
style.setProperty('--tw-fui-magentaLight', this._themeVariant.palette.magentaLight);
|
||||||
|
style.setProperty('--tw-fui-purpleDark', this._themeVariant.palette.purpleDark);
|
||||||
|
style.setProperty('--tw-fui-purple', this._themeVariant.palette.purple);
|
||||||
|
style.setProperty('--tw-fui-purpleLight', this._themeVariant.palette.purpleLight);
|
||||||
|
style.setProperty('--tw-fui-blueDark', this._themeVariant.palette.blueDark);
|
||||||
|
style.setProperty('--tw-fui-blueMid', this._themeVariant.palette.blueMid);
|
||||||
|
style.setProperty('--tw-fui-blue', this._themeVariant.palette.blue);
|
||||||
|
style.setProperty('--tw-fui-blueLight', this._themeVariant.palette.blueLight);
|
||||||
|
style.setProperty('--tw-fui-tealDark', this._themeVariant.palette.tealDark);
|
||||||
|
style.setProperty('--tw-fui-teal', this._themeVariant.palette.teal);
|
||||||
|
style.setProperty('--tw-fui-tealLight', this._themeVariant.palette.tealLight);
|
||||||
|
style.setProperty('--tw-fui-greenDark', this._themeVariant.palette.greenDark);
|
||||||
|
style.setProperty('--tw-fui-green', this._themeVariant.palette.green);
|
||||||
|
style.setProperty('--tw-fui-greenLight', this._themeVariant.palette.greenLight);
|
||||||
|
|
||||||
|
style.setProperty('--tw-fui-bodyBackground', this._themeVariant.semanticColors.bodyBackground);
|
||||||
|
style.setProperty('--tw-fui-bodyStandoutBackground', this._themeVariant.semanticColors.bodyStandoutBackground);
|
||||||
|
style.setProperty('--tw-fui-bodyFrameBackground', this._themeVariant.semanticColors.bodyFrameBackground);
|
||||||
|
style.setProperty('--tw-fui-bodyFrameDivider', this._themeVariant.semanticColors.bodyFrameDivider);
|
||||||
|
style.setProperty('--tw-fui-bodyText', this._themeVariant.semanticColors.bodyText);
|
||||||
|
style.setProperty('--tw-fui-bodyTextChecked', this._themeVariant.semanticColors.bodyTextChecked);
|
||||||
|
style.setProperty('--tw-fui-bodySubtext', this._themeVariant.semanticColors.bodySubtext);
|
||||||
|
style.setProperty('--tw-fui-bodyDivider', this._themeVariant.semanticColors.bodyDivider);
|
||||||
|
style.setProperty('--tw-fui-disabledBackground', this._themeVariant.semanticColors.disabledBackground);
|
||||||
|
style.setProperty('--tw-fui-disabledText', this._themeVariant.semanticColors.disabledText);
|
||||||
|
style.setProperty('--tw-fui-disabledSubtext', this._themeVariant.semanticColors.disabledSubtext);
|
||||||
|
style.setProperty('--tw-fui-disabledBodyText', this._themeVariant.semanticColors.disabledBodyText);
|
||||||
|
style.setProperty('--tw-fui-disabledBodySubtext', this._themeVariant.semanticColors.disabledBodySubtext);
|
||||||
|
style.setProperty('--tw-fui-focusBorder', this._themeVariant.semanticColors.focusBorder);
|
||||||
|
style.setProperty('--tw-fui-variantBorder', this._themeVariant.semanticColors.variantBorder);
|
||||||
|
style.setProperty('--tw-fui-variantBorderHovered', this._themeVariant.semanticColors.variantBorderHovered);
|
||||||
|
style.setProperty('--tw-fui-defaultStateBackground', this._themeVariant.semanticColors.defaultStateBackground);
|
||||||
|
style.setProperty('--tw-fui-errorText', this._themeVariant.semanticColors.errorText);
|
||||||
|
style.setProperty('--tw-fui-warningText', this._themeVariant.semanticColors.warningText);
|
||||||
|
style.setProperty('--tw-fui-errorBackground', this._themeVariant.semanticColors.errorBackground);
|
||||||
|
style.setProperty('--tw-fui-blockingBackground', this._themeVariant.semanticColors.blockingBackground);
|
||||||
|
style.setProperty('--tw-fui-warningBackground', this._themeVariant.semanticColors.warningBackground);
|
||||||
|
style.setProperty('--tw-fui-warningHighlight', this._themeVariant.semanticColors.warningHighlight);
|
||||||
|
style.setProperty('--tw-fui-successBackground', this._themeVariant.semanticColors.successBackground);
|
||||||
|
style.setProperty('--tw-fui-inputBorder', this._themeVariant.semanticColors.inputBorder);
|
||||||
|
style.setProperty('--tw-fui-inputBorderHovered', this._themeVariant.semanticColors.inputBorderHovered);
|
||||||
|
style.setProperty('--tw-fui-inputBackground', this._themeVariant.semanticColors.inputBackground);
|
||||||
|
style.setProperty('--tw-fui-inputBackgroundChecked', this._themeVariant.semanticColors.inputBackgroundChecked);
|
||||||
|
style.setProperty('--tw-fui-inputBackgroundCheckedHovered', this._themeVariant.semanticColors.inputBackgroundCheckedHovered);
|
||||||
|
style.setProperty('--tw-fui-inputForegroundChecked', this._themeVariant.semanticColors.inputForegroundChecked);
|
||||||
|
style.setProperty('--tw-fui-inputFocusBorderAlt', this._themeVariant.semanticColors.inputFocusBorderAlt);
|
||||||
|
style.setProperty('--tw-fui-smallInputBorder', this._themeVariant.semanticColors.smallInputBorder);
|
||||||
|
style.setProperty('--tw-fui-inputText', this._themeVariant.semanticColors.inputText);
|
||||||
|
style.setProperty('--tw-fui-inputTextHovered', this._themeVariant.semanticColors.inputTextHovered);
|
||||||
|
style.setProperty('--tw-fui-inputPlaceholderText', this._themeVariant.semanticColors.inputPlaceholderText);
|
||||||
|
style.setProperty('--tw-fui-buttonBackground', this._themeVariant.semanticColors.buttonBackground);
|
||||||
|
style.setProperty('--tw-fui-buttonBackgroundChecked', this._themeVariant.semanticColors.buttonBackgroundChecked);
|
||||||
|
style.setProperty('--tw-fui-buttonBackgroundHovered', this._themeVariant.semanticColors.buttonBackgroundHovered);
|
||||||
|
style.setProperty('--tw-fui-buttonBackgroundCheckedHovered', this._themeVariant.semanticColors.buttonBackgroundCheckedHovered);
|
||||||
|
style.setProperty('--tw-fui-buttonBackgroundPressed', this._themeVariant.semanticColors.buttonBackgroundPressed);
|
||||||
|
style.setProperty('--tw-fui-buttonBackgroundDisabled', this._themeVariant.semanticColors.buttonBackgroundDisabled);
|
||||||
|
style.setProperty('--tw-fui-buttonBorder', this._themeVariant.semanticColors.buttonBorder);
|
||||||
|
style.setProperty('--tw-fui-buttonText', this._themeVariant.semanticColors.buttonText);
|
||||||
|
style.setProperty('--tw-fui-buttonTextHovered', this._themeVariant.semanticColors.buttonTextHovered);
|
||||||
|
style.setProperty('--tw-fui-buttonTextChecked', this._themeVariant.semanticColors.buttonTextChecked);
|
||||||
|
style.setProperty('--tw-fui-buttonTextCheckedHovered', this._themeVariant.semanticColors.buttonTextCheckedHovered);
|
||||||
|
style.setProperty('--tw-fui-buttonTextPressed', this._themeVariant.semanticColors.buttonTextPressed);
|
||||||
|
style.setProperty('--tw-fui-buttonTextDisabled', this._themeVariant.semanticColors.buttonTextDisabled);
|
||||||
|
style.setProperty('--tw-fui-buttonBorderDisabled', this._themeVariant.semanticColors.buttonBorderDisabled);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonBackground', this._themeVariant.semanticColors.primaryButtonBackground);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonBackgroundHovered', this._themeVariant.semanticColors.primaryButtonBackgroundHovered);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonBackgroundPressed', this._themeVariant.semanticColors.primaryButtonBackgroundPressed);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonBackgroundDisabled', this._themeVariant.semanticColors.primaryButtonBackgroundDisabled);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonBorder', this._themeVariant.semanticColors.primaryButtonBorder);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonText', this._themeVariant.semanticColors.primaryButtonText);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonTextHovered', this._themeVariant.semanticColors.primaryButtonTextHovered);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonTextPressed', this._themeVariant.semanticColors.primaryButtonTextPressed);
|
||||||
|
style.setProperty('--tw-fui-primaryButtonTextDisabled', this._themeVariant.semanticColors.primaryButtonTextDisabled);
|
||||||
|
style.setProperty('--tw-fui-accentButtonBackground', this._themeVariant.semanticColors.accentButtonBackground);
|
||||||
|
style.setProperty('--tw-fui-accentButtonText', this._themeVariant.semanticColors.accentButtonText);
|
||||||
|
style.setProperty('--tw-fui-menuBackground', this._themeVariant.semanticColors.menuBackground);
|
||||||
|
style.setProperty('--tw-fui-menuDivider', this._themeVariant.semanticColors.menuDivider);
|
||||||
|
style.setProperty('--tw-fui-menuIcon', this._themeVariant.semanticColors.menuIcon);
|
||||||
|
style.setProperty('--tw-fui-menuHeader', this._themeVariant.semanticColors.menuHeader);
|
||||||
|
style.setProperty('--tw-fui-menuItemBackgroundHovered', this._themeVariant.semanticColors.menuItemBackgroundHovered);
|
||||||
|
style.setProperty('--tw-fui-menuItemBackgroundPressed', this._themeVariant.semanticColors.menuItemBackgroundPressed);
|
||||||
|
style.setProperty('--tw-fui-menuItemText', this._themeVariant.semanticColors.menuItemText);
|
||||||
|
style.setProperty('--tw-fui-menuItemTextHovered', this._themeVariant.semanticColors.menuItemTextHovered);
|
||||||
|
style.setProperty('--tw-fui-listBackground', this._themeVariant.semanticColors.listBackground);
|
||||||
|
style.setProperty('--tw-fui-listText', this._themeVariant.semanticColors.listText);
|
||||||
|
style.setProperty('--tw-fui-listItemBackgroundHovered', this._themeVariant.semanticColors.listItemBackgroundHovered);
|
||||||
|
style.setProperty('--tw-fui-listItemBackgroundChecked', this._themeVariant.semanticColors.listItemBackgroundChecked);
|
||||||
|
style.setProperty('--tw-fui-listItemBackgroundCheckedHovered', this._themeVariant.semanticColors.listItemBackgroundCheckedHovered);
|
||||||
|
style.setProperty('--tw-fui-listHeaderBackgroundHovered', this._themeVariant.semanticColors.listHeaderBackgroundHovered);
|
||||||
|
style.setProperty('--tw-fui-listHeaderBackgroundPressed', this._themeVariant.semanticColors.listHeaderBackgroundPressed);
|
||||||
|
style.setProperty('--tw-fui-actionLink', this._themeVariant.semanticColors.actionLink);
|
||||||
|
style.setProperty('--tw-fui-actionLinkHovered', this._themeVariant.semanticColors.actionLinkHovered);
|
||||||
|
style.setProperty('--tw-fui-link', this._themeVariant.semanticColors.link);
|
||||||
|
style.setProperty('--tw-fui-linkHovered', this._themeVariant.semanticColors.linkHovered);
|
||||||
|
style.setProperty('--tw-fui-listTextColor', this._themeVariant.semanticColors.listTextColor);
|
||||||
|
style.setProperty('--tw-fui-menuItemBackgroundChecked', this._themeVariant.semanticColors.menuItemBackgroundChecked);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): void {
|
||||||
|
const element: React.ReactElement<IHelloTailwindCssProps> = React.createElement(
|
||||||
|
HelloTailwindCss,
|
||||||
|
{
|
||||||
|
description: this.properties.description
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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('description', {
|
||||||
|
label: strings.DescriptionFieldLabel
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { escape } from '@microsoft/sp-lodash-subset';
|
||||||
|
import './../../../tailwind.css';
|
||||||
|
import User, { IUserProps } from './User';
|
||||||
|
|
||||||
|
export interface IDocumentCardProps {
|
||||||
|
title: string;
|
||||||
|
documentImageUrl: string;
|
||||||
|
lastEditUserInfo: IUserProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class DocumentCard extends React.Component<IDocumentCardProps, {}> {
|
||||||
|
public render(): React.ReactElement<IDocumentCardProps> {
|
||||||
|
return (
|
||||||
|
<div className="max-w-sm overflow-hidden bg-white text-black border border-solid border-gray-400 hover:outline-none hover:shadow-lg hover:cursor-pointer">
|
||||||
|
<img className="w-full border-0 border-solid border-b border-gray-400" src={this.props.documentImageUrl} alt="Document Preview" />
|
||||||
|
<div className="px-4 py-3 pt-1">
|
||||||
|
<div className="text-lg mb-2">{this.props.title}</div>
|
||||||
|
<User profileImageUrl={this.props.lastEditUserInfo.profileImageUrl}
|
||||||
|
line1={this.props.lastEditUserInfo.line1}
|
||||||
|
line2={this.props.lastEditUserInfo.line1} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { IHelloTailwindCssProps } from './IHelloTailwindCssProps';
|
||||||
|
import { escape } from '@microsoft/sp-lodash-subset';
|
||||||
|
import './../../../tailwind.css';
|
||||||
|
import DocumentCard from './DocumentCard';
|
||||||
|
import HorizontalCard from './HorizontalCard';
|
||||||
|
import { Stack } from 'office-ui-fabric-react';
|
||||||
|
|
||||||
|
export default class HelloTailwindCss extends React.Component<IHelloTailwindCssProps, {}> {
|
||||||
|
public render(): React.ReactElement<IHelloTailwindCssProps> {
|
||||||
|
return (
|
||||||
|
<Stack gap="20">
|
||||||
|
<DocumentCard title="Revenue stream proposal fiscal year 2016 version02.pptx"
|
||||||
|
documentImageUrl="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/document-preview.png"
|
||||||
|
lastEditUserInfo={{
|
||||||
|
profileImageUrl: "https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/persona-female.png",
|
||||||
|
line1: "Annie Lindqvist",
|
||||||
|
line2: "Created a few minutes ago"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<HorizontalCard title="Can coffee make you a better developer?"
|
||||||
|
description="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil."
|
||||||
|
documentImageUrl="//tailwindcss.com/img/card-left.jpg"
|
||||||
|
lastEditUserInfo={{
|
||||||
|
profileImageUrl: "https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/persona-female.png",
|
||||||
|
line1: "Annie Lindqvist",
|
||||||
|
line2: "Aug 18"
|
||||||
|
}}
|
||||||
|
/></Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { escape } from '@microsoft/sp-lodash-subset';
|
||||||
|
import './../../../tailwind.css';
|
||||||
|
import User, { IUserProps } from './User';
|
||||||
|
|
||||||
|
export interface IHorizontalCardProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
documentImageUrl: string;
|
||||||
|
lastEditUserInfo: IUserProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootClassName = "sp-col-1/3:max-w-sm sp-col-1:max-w-full sp-col-1:flex overflow-hidden shadow hover:outline-none hover:shadow-lg hover:cursor-pointer";
|
||||||
|
|
||||||
|
export default class HorizontalCard extends React.Component<IHorizontalCardProps, {}> {
|
||||||
|
public render(): React.ReactElement<IHorizontalCardProps> {
|
||||||
|
return (
|
||||||
|
<div className={rootClassName}>
|
||||||
|
<div className="h-48 sp-col-1:h-auto sp-col-1:w-48 flex-none bg-cover text-center overflow-hidden" style={{ backgroundImage: "url('//tailwindcss.com/img/card-left.jpg')" }} title="Woman holding a mug">
|
||||||
|
</div>
|
||||||
|
<div className="border-r border-b border-l border-gray-400 sp-col-1:border-l-0 sp-col-1:border-t bg-buttonBackground text-buttonText p-4 flex flex-col justify-between leading-normal">
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="font-bold text-xl mb-2">{this.props.title}</div>
|
||||||
|
<p className="text-base text-buttonTextDisabled">{this.props.description}</p>
|
||||||
|
</div>
|
||||||
|
<User profileImageUrl={this.props.lastEditUserInfo.profileImageUrl}
|
||||||
|
line1={this.props.lastEditUserInfo.line1}
|
||||||
|
line2={this.props.lastEditUserInfo.line1} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface IHelloTailwindCssProps {
|
||||||
|
description: string;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { escape } from '@microsoft/sp-lodash-subset';
|
||||||
|
import './../../../tailwind.css';
|
||||||
|
|
||||||
|
export interface IUserProps {
|
||||||
|
profileImageUrl: string;
|
||||||
|
line1: string;
|
||||||
|
line2: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class User extends React.Component<IUserProps, {}> {
|
||||||
|
public render(): React.ReactElement<IUserProps> {
|
||||||
|
return (
|
||||||
|
<div className="flex mt-4">
|
||||||
|
<img className="h-8 w-8 rounded-full mr-2" src={this.props.profileImageUrl} />
|
||||||
|
<div className="text-left">
|
||||||
|
<div className="font-bold text-xs">{this.props.line1}</div>
|
||||||
|
<div className="text-xs text-buttonTextDisabled">{this.props.line2}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"PropertyPaneDescription": "Description",
|
||||||
|
"BasicGroupName": "Group Name",
|
||||||
|
"DescriptionFieldLabel": "Description Field"
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,10 @@
|
||||||
|
declare interface IHelloTailwindCssWebPartStrings {
|
||||||
|
PropertyPaneDescription: string;
|
||||||
|
BasicGroupName: string;
|
||||||
|
DescriptionFieldLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'HelloTailwindCssWebPartStrings' {
|
||||||
|
const strings: IHelloTailwindCssWebPartStrings;
|
||||||
|
export = strings;
|
||||||
|
}
|
|
@ -0,0 +1,289 @@
|
||||||
|
const plugin = require('tailwindcss/plugin');
|
||||||
|
const customSpSectionVariant = ['sp-col-1', 'sp-col-1/2', 'sp-col-1/3', 'sp-col-2/3'];
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
purge: {
|
||||||
|
enabled: true,
|
||||||
|
content: ['./src/**/*.tsx'],
|
||||||
|
options: {
|
||||||
|
whitelistPatterns: [/^CanvasSection*/]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
themeDarker: 'var(--tw-fui-themeDarker)',
|
||||||
|
themeDark: 'var(--tw-fui-themeDark)',
|
||||||
|
themeDarkAlt: 'var(--tw-fui-themeDarkAlt)',
|
||||||
|
themePrimary: 'var(--tw-fui-themePrimary)',
|
||||||
|
themeSecondary: 'var(--tw-fui-themeSecondary)',
|
||||||
|
themeTertiary: 'var(--tw-fui-themeTertiary)',
|
||||||
|
themeLight: 'var(--tw-fui-themeLight)',
|
||||||
|
themeLighter: 'var(--tw-fui-themeLighter)',
|
||||||
|
themeLighterAlt: 'var(--tw-fui-themeLighterAlt)',
|
||||||
|
//black: 'var(--tw-fui-black)',
|
||||||
|
blackTranslucent40: 'var(--tw-fui-blackTranslucent40)',
|
||||||
|
neutralDark: 'var(--tw-fui-neutralDark)',
|
||||||
|
neutralPrimary: 'var(--tw-fui-neutralPrimary)',
|
||||||
|
neutralPrimaryAlt: 'var(--tw-fui-neutralPrimaryAlt)',
|
||||||
|
neutralSecondary: 'var(--tw-fui-neutralSecondary)',
|
||||||
|
neutralSecondaryAlt: 'var(--tw-fui-neutralSecondaryAlt)',
|
||||||
|
neutralTertiary: 'var(--tw-fui-neutralTertiary)',
|
||||||
|
neutralTertiaryAlt: 'var(--tw-fui-neutralTertiaryAlt)',
|
||||||
|
neutralQuaternary: 'var(--tw-fui-neutralQuaternary)',
|
||||||
|
neutralQuaternaryAlt: 'var(--tw-fui-neutralQuaternaryAlt)',
|
||||||
|
neutralLight: 'var(--tw-fui-neutralLight)',
|
||||||
|
neutralLighter: 'var(--tw-fui-neutralLighter)',
|
||||||
|
neutralLighterAlt: 'var(--tw-fui-neutralLighterAlt)',
|
||||||
|
accent: 'var(--tw-fui-accent)',
|
||||||
|
//white: 'var(--tw-fui-white)',
|
||||||
|
whiteTranslucent40: 'var(--tw-fui-whiteTranslucent40)',
|
||||||
|
yellow: 'var(--tw-fui-yellow)',
|
||||||
|
yellowLight: 'var(--tw-fui-yellowLight)',
|
||||||
|
orange: 'var(--tw-fui-orange)',
|
||||||
|
orangeLight: 'var(--tw-fui-orangeLight)',
|
||||||
|
orangeLighter: 'var(--tw-fui-orangeLighter)',
|
||||||
|
redDark: 'var(--tw-fui-redDark)',
|
||||||
|
red: 'var(--tw-fui-red)',
|
||||||
|
magentaDark: 'var(--tw-fui-magentaDark)',
|
||||||
|
magenta: 'var(--tw-fui-magenta)',
|
||||||
|
magentaLight: 'var(--tw-fui-magentaLight)',
|
||||||
|
purpleDark: 'var(--tw-fui-purpleDark)',
|
||||||
|
purple: 'var(--tw-fui-purple)',
|
||||||
|
purpleLight: 'var(--tw-fui-purpleLight)',
|
||||||
|
blueDark: 'var(--tw-fui-blueDark)',
|
||||||
|
blueMid: 'var(--tw-fui-blueMid)',
|
||||||
|
blue: 'var(--tw-fui-blue)',
|
||||||
|
blueLight: 'var(--tw-fui-blueLight)',
|
||||||
|
tealDark: 'var(--tw-fui-tealDark)',
|
||||||
|
teal: 'var(--tw-fui-teal)',
|
||||||
|
tealLight: 'var(--tw-fui-tealLight)',
|
||||||
|
greenDark: 'var(--tw-fui-greenDark)',
|
||||||
|
green: 'var(--tw-fui-green)',
|
||||||
|
greenLight: 'var(--tw-fui-greenLight)',
|
||||||
|
/* ***** */
|
||||||
|
bodyBackground: 'var(--tw-fui-bodyBackground)',
|
||||||
|
bodyStandoutBackground: 'var(--tw-fui-bodyStandoutBackground)',
|
||||||
|
bodyFrameBackground: 'var(--tw-fui-bodyFrameBackground)',
|
||||||
|
bodyFrameDivider: 'var(--tw-fui-bodyFrameDivider)',
|
||||||
|
bodyText: 'var(--tw-fui-bodyText)',
|
||||||
|
bodyTextChecked: 'var(--tw-fui-bodyTextChecked)',
|
||||||
|
bodySubtext: 'var(--tw-fui-bodySubtext)',
|
||||||
|
bodyDivider: 'var(--tw-fui-bodyDivider)',
|
||||||
|
disabledBackground: 'var(--tw-fui-disabledBackground)',
|
||||||
|
disabledText: 'var(--tw-fui-disabledText)',
|
||||||
|
disabledSubtext: 'var(--tw-fui-disabledSubtext)',
|
||||||
|
disabledBodyText: 'var(--tw-fui-disabledBodyText)',
|
||||||
|
disabledBodySubtext: 'var(--tw-fui-disabledBodySubtext)',
|
||||||
|
focusBorder: 'var(--tw-fui-focusBorder)',
|
||||||
|
variantBorder: 'var(--tw-fui-variantBorder)',
|
||||||
|
variantBorderHovered: 'var(--tw-fui-variantBorderHovered)',
|
||||||
|
defaultStateBackground: 'var(--tw-fui-defaultStateBackground)',
|
||||||
|
errorText: 'var(--tw-fui-errorText)',
|
||||||
|
warningText: 'var(--tw-fui-warningText)',
|
||||||
|
errorBackground: 'var(--tw-fui-errorBackground)',
|
||||||
|
blockingBackground: 'var(--tw-fui-blockingBackground)',
|
||||||
|
warningBackground: 'var(--tw-fui-warningBackground)',
|
||||||
|
warningHighlight: 'var(--tw-fui-warningHighlight)',
|
||||||
|
successBackground: 'var(--tw-fui-successBackground)',
|
||||||
|
inputBorder: 'var(--tw-fui-inputBorder)',
|
||||||
|
inputBorderHovered: 'var(--tw-fui-inputBorderHovered)',
|
||||||
|
inputBackground: 'var(--tw-fui-inputBackground)',
|
||||||
|
inputBackgroundChecked: 'var(--tw-fui-inputBackgroundChecked)',
|
||||||
|
inputBackgroundCheckedHovered: 'var(--tw-fui-inputBackgroundCheckedHovered)',
|
||||||
|
inputForegroundChecked: 'var(--tw-fui-inputForegroundChecked)',
|
||||||
|
inputFocusBorderAlt: 'var(--tw-fui-inputFocusBorderAlt)',
|
||||||
|
smallInputBorder: 'var(--tw-fui-smallInputBorder)',
|
||||||
|
inputText: 'var(--tw-fui-inputText)',
|
||||||
|
inputTextHovered: 'var(--tw-fui-inputTextHovered)',
|
||||||
|
inputPlaceholderText: 'var(--tw-fui-inputPlaceholderText)',
|
||||||
|
buttonBackground: 'var(--tw-fui-buttonBackground)',
|
||||||
|
buttonBackgroundChecked: 'var(--tw-fui-buttonBackgroundChecked)',
|
||||||
|
buttonBackgroundHovered: 'var(--tw-fui-buttonBackgroundHovered)',
|
||||||
|
buttonBackgroundCheckedHovered: 'var(--tw-fui-buttonBackgroundCheckedHovered)',
|
||||||
|
buttonBackgroundPressed: 'var(--tw-fui-buttonBackgroundPressed)',
|
||||||
|
buttonBackgroundDisabled: 'var(--tw-fui-buttonBackgroundDisabled)',
|
||||||
|
buttonBorder: 'var(--tw-fui-buttonBorder)',
|
||||||
|
buttonText: 'var(--tw-fui-buttonText)',
|
||||||
|
buttonTextHovered: 'var(--tw-fui-buttonTextHovered)',
|
||||||
|
buttonTextChecked: 'var(--tw-fui-buttonTextChecked)',
|
||||||
|
buttonTextCheckedHovered: 'var(--tw-fui-buttonTextCheckedHovered)',
|
||||||
|
buttonTextPressed: 'var(--tw-fui-buttonTextPressed)',
|
||||||
|
buttonTextDisabled: 'var(--tw-fui-buttonTextDisabled)',
|
||||||
|
buttonBorderDisabled: 'var(--tw-fui-buttonBorderDisabled)',
|
||||||
|
primaryButtonBackground: 'var(--tw-fui-primaryButtonBackground)',
|
||||||
|
primaryButtonBackgroundHovered: 'var(--tw-fui-primaryButtonBackgroundHovered)',
|
||||||
|
primaryButtonBackgroundPressed: 'var(--tw-fui-primaryButtonBackgroundPressed)',
|
||||||
|
primaryButtonBackgroundDisabled: 'var(--tw-fui-primaryButtonBackgroundDisabled)',
|
||||||
|
primaryButtonBorder: 'var(--tw-fui-primaryButtonBorder)',
|
||||||
|
primaryButtonText: 'var(--tw-fui-primaryButtonText)',
|
||||||
|
primaryButtonTextHovered: 'var(--tw-fui-primaryButtonTextHovered)',
|
||||||
|
primaryButtonTextPressed: 'var(--tw-fui-primaryButtonTextPressed)',
|
||||||
|
primaryButtonTextDisabled: 'var(--tw-fui-primaryButtonTextDisabled)',
|
||||||
|
accentButtonBackground: 'var(--tw-fui-accentButtonBackground)',
|
||||||
|
accentButtonText: 'var(--tw-fui-accentButtonText)',
|
||||||
|
menuBackground: 'var(--tw-fui-menuBackground)',
|
||||||
|
menuDivider: 'var(--tw-fui-menuDivider)',
|
||||||
|
menuIcon: 'var(--tw-fui-menuIcon)',
|
||||||
|
menuHeader: 'var(--tw-fui-menuHeader)',
|
||||||
|
menuItemBackgroundHovered: 'var(--tw-fui-menuItemBackgroundHovered)',
|
||||||
|
menuItemBackgroundPressed: 'var(--tw-fui-menuItemBackgroundPressed)',
|
||||||
|
menuItemText: 'var(--tw-fui-menuItemText)',
|
||||||
|
menuItemTextHovered: 'var(--tw-fui-menuItemTextHovered)',
|
||||||
|
listBackground: 'var(--tw-fui-listBackground)',
|
||||||
|
listText: 'var(--tw-fui-listText)',
|
||||||
|
listItemBackgroundHovered: 'var(--tw-fui-listItemBackgroundHovered)',
|
||||||
|
listItemBackgroundChecked: 'var(--tw-fui-listItemBackgroundChecked)',
|
||||||
|
listItemBackgroundCheckedHovered: 'var(--tw-fui-listItemBackgroundCheckedHovered)',
|
||||||
|
listHeaderBackgroundHovered: 'var(--tw-fui-listHeaderBackgroundHovered)',
|
||||||
|
listHeaderBackgroundPressed: 'var(--tw-fui-listHeaderBackgroundPressed)',
|
||||||
|
actionLink: 'var(--tw-fui-actionLink)',
|
||||||
|
actionLinkHovered: 'var(--tw-fui-actionLinkHovered)',
|
||||||
|
link: 'var(--tw-fui-link)',
|
||||||
|
linkHovered: 'var(--tw-fui-linkHovered)',
|
||||||
|
listTextColor: 'var(--tw-fui-listTextColor)',
|
||||||
|
menuItemBackgroundChecked: 'var(--tw-fui-menuItemBackgroundChecked)',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
accessibility: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
alignContent: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
alignItems: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
alignSelf: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
appearance: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundAttachment: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundClip: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundColor: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundImage: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gradientColorStops: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundOpacity: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundPosition: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundRepeat: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
backgroundSize: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderCollapse: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderColor: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderOpacity: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderRadius: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderStyle: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
borderWidth: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
boxShadow: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
boxSizing: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
container: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
cursor: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
display: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
divideColor: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
divideOpacity: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
divideStyle: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
divideWidth: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fill: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
flex: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
flexDirection: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
flexGrow: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
flexShrink: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
flexWrap: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
float: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
clear: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontFamily: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontSize: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontSmoothing: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontVariantNumeric: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontStyle: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
fontWeight: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
height: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
inset: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
justifyContent: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
justifyItems: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
justifySelf: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
letterSpacing: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
lineHeight: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
listStylePosition: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
listStyleType: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
margin: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
maxHeight: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
maxWidth: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
minHeight: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
minWidth: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
objectFit: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
objectPosition: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
opacity: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
order: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
outline: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
overflow: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
overscrollBehavior: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
padding: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
placeContent: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
placeItems: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
placeSelf: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
placeholderColor: customSpSectionVariant.concat(['focus']),
|
||||||
|
placeholderOpacity: customSpSectionVariant.concat(['focus']),
|
||||||
|
pointerEvents: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
position: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
resize: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
space: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
stroke: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
strokeWidth: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
tableLayout: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
textAlign: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
textColor: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
textOpacity: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
textDecoration: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
textTransform: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
userSelect: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
verticalAlign: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
visibility: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
whitespace: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
width: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
wordBreak: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
zIndex: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gap: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridAutoFlow: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridTemplateColumns: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridColumn: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridColumnStart: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridColumnEnd: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridTemplateRows: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridRow: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridRowStart: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
gridRowEnd: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transform: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transformOrigin: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
scale: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
rotate: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
translate: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
skew: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transitionProperty: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transitionTimingFunction: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transitionDuration: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
transitionDelay: customSpSectionVariant.concat(['hover', 'focus']),
|
||||||
|
animation: customSpSectionVariant
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
plugin(function ({ addVariant, e }) {
|
||||||
|
addVariant('sp-col-1', ({ modifySelectors, separator }) => {
|
||||||
|
modifySelectors(({ className }) => {
|
||||||
|
return `.CanvasSection.CanvasSection-col.CanvasSection-xl12 .${e(`sp-col-1${separator}${className}`)}`
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
addVariant('sp-col-1/2', ({ modifySelectors, separator }) => {
|
||||||
|
modifySelectors(({ className }) => {
|
||||||
|
return `.CanvasSection.CanvasSection-col.CanvasSection-xl6 .${e(`sp-col-1/2${separator}${className}`)}`
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
addVariant('sp-col-1/3', ({ modifySelectors, separator }) => {
|
||||||
|
modifySelectors(({ className }) => {
|
||||||
|
return `.CanvasSection.CanvasSection-col.CanvasSection-xl4 .${e(`sp-col-1/3${separator}${className}`)}`
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
addVariant('sp-col-2/3', ({ modifySelectors, separator }) => {
|
||||||
|
modifySelectors(({ className }) => {
|
||||||
|
return `.CanvasSection.CanvasSection-col.CanvasSection-xl8 .${e(`sp-col-2/3${separator}${className}`)}`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
future: {
|
||||||
|
removeDeprecatedGapUtilities: true,
|
||||||
|
purgeLayersByDefault: true
|
||||||
|
}
|
||||||
|
};
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 383 B |
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react",
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types",
|
||||||
|
"./node_modules/@microsoft"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"es6-promise",
|
||||||
|
"webpack-env"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es5",
|
||||||
|
"dom",
|
||||||
|
"es2015.collection"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"class-name": false,
|
||||||
|
"export-name": false,
|
||||||
|
"forin": false,
|
||||||
|
"label-position": false,
|
||||||
|
"member-access": true,
|
||||||
|
"no-arg": false,
|
||||||
|
"no-console": false,
|
||||||
|
"no-construct": false,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-eval": false,
|
||||||
|
"no-function-expression": true,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-unnecessary-semicolons": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"no-with-statement": true,
|
||||||
|
"semicolon": true,
|
||||||
|
"trailing-comma": false,
|
||||||
|
"typedef": false,
|
||||||
|
"typedef-whitespace": false,
|
||||||
|
"use-named-parameter": true,
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": false
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
"framework": "react",
|
"framework": "react",
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"version": "1.7.1",
|
"version": "1.11.0",
|
||||||
"libraryName": "react-tenant-properties",
|
"libraryName": "react-tenant-properties",
|
||||||
"libraryId": "d5bc38a6-0b5c-4644-9087-efa6de87ece1",
|
"libraryId": "d5bc38a6-0b5c-4644-9087-efa6de87ece1",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
|
|
@ -1,28 +1,35 @@
|
||||||
# React Tenant Properties Web Part
|
# React Tenant Properties Web Part
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
This web part allows tenant administrators to manage tenant properties through a graphical interface.
|
This web part allows tenant administrators to manage tenant properties through a graphical interface.
|
||||||
We can create, edit or delete tenant properties.
|
We can create, edit or delete tenant properties.
|
||||||
|
|
||||||
Only users with Tenant Admin Role are allowed to managed tenant properties.
|
Only users with Tenant Admin Role are allowed to managed tenant properties.
|
||||||
#### User without Tenant Admin Role got this message
|
|
||||||
|
### User without Tenant Admin Role got this message
|
||||||
|
|
||||||
![tenant properties](./assets/TenantProperties5.jpg)
|
![tenant properties](./assets/TenantProperties5.jpg)
|
||||||
#### List tenant properties
|
|
||||||
|
### List tenant properties
|
||||||
|
|
||||||
![tenant properties](./assets/TenantProperties1.jpg)
|
![tenant properties](./assets/TenantProperties1.jpg)
|
||||||
|
|
||||||
#### Add Tenant property
|
### Add Tenant property
|
||||||
|
|
||||||
![tenant properties](./assets/TenantProperties2.jpg)
|
![tenant properties](./assets/TenantProperties2.jpg)
|
||||||
|
|
||||||
#### Edit tenant property
|
### Edit tenant property
|
||||||
|
|
||||||
![tenant properties](./assets/TenantProperties3.jpg)
|
![tenant properties](./assets/TenantProperties3.jpg)
|
||||||
|
|
||||||
#### Delete tenant property
|
### Delete tenant property
|
||||||
![tenant properties](./assets/TenantProperties4.jpg)
|
|
||||||
|
|
||||||
|
![tenant properties](./assets/TenantProperties4.jpg)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![drop](https://img.shields.io/badge/version-1.7.1-green.svg)
|
![SPFx 1.11](https://img.shields.io/badge/version-1.11.0-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -38,6 +45,7 @@ WebPart Title| Text| no|
|
||||||
|
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
The Web Part Use MSGraph API and need to SharePoint Administrator approve de scope "Directory.ReadWrite.All" in SharePoint Admin Center.
|
The Web Part Use MSGraph API and need to SharePoint Administrator approve de scope "Directory.ReadWrite.All" in SharePoint Admin Center.
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
|
@ -49,8 +57,10 @@ Tenant Properties WebPart|João Mendes
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0.0|Mar 08, 2019|Initial release
|
1.0.0|Mar 08, 2019|Initial release
|
||||||
|
1.0.1|October 20, 2020|Update to SPFx 1.11.0
|
||||||
|
|
||||||
## Disclaimer
|
## 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.**
|
**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.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -63,7 +73,7 @@ Version|Date|Comments
|
||||||
- `gulp build`
|
- `gulp build`
|
||||||
- `gulp bundle --ship`
|
- `gulp bundle --ship`
|
||||||
- `gulp package-solution --ship`
|
- `gulp package-solution --ship`
|
||||||
- `Add to AppCatalog and deploy`
|
- Add to AppCatalog and deploy
|
||||||
- `Approve API permission on SharePoint Admin Center`
|
- Approve API permission on SharePoint Admin Center
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-tenant-properties" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-tenant-properties" />
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-tenant-properties-client-side-solution",
|
"name": "react-tenant-properties-client-side-solution",
|
||||||
"id": "d5bc38a6-0b5c-4644-9087-efa6de87ece1",
|
"id": "d5bc38a6-0b5c-4644-9087-efa6de87ece1",
|
||||||
"version": "1.0.0.0",
|
"version": "1.0.1.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"webApiPermissionRequests": [
|
"webApiPermissionRequests": [
|
||||||
|
@ -11,7 +11,14 @@
|
||||||
"resource": "Microsoft Graph",
|
"resource": "Microsoft Graph",
|
||||||
"scope": "Directory.ReadWrite.All"
|
"scope": "Directory.ReadWrite.All"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-tenant-properties.sppkg"
|
"zippedPackage": "solution/react-tenant-properties.sppkg"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"name": "react-tenant-properties",
|
"name": "react-tenant-properties",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
},
|
},
|
||||||
|
@ -15,30 +16,29 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/office-ui-fabric-react-bundle": "^1.7.1",
|
"@microsoft/office-ui-fabric-react-bundle": "^1.7.1",
|
||||||
"@microsoft/sp-core-library": "1.7.1",
|
"@microsoft/sp-core-library": "1.11.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.7.1",
|
"@microsoft/sp-lodash-subset": "1.11.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.7.1",
|
"@microsoft/sp-office-ui-fabric-core": "1.11.0",
|
||||||
"@microsoft/sp-webpart-base": "1.7.1",
|
"@microsoft/sp-property-pane": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-base": "1.11.0",
|
||||||
"@pnp/pnpjs": "^1.3.0",
|
"@pnp/pnpjs": "^1.3.0",
|
||||||
"@pnp/spfx-controls-react": "1.12.0",
|
"@pnp/spfx-controls-react": "1.12.0",
|
||||||
"@pnp/spfx-property-controls": "1.14.1",
|
"@pnp/spfx-property-controls": "1.14.1",
|
||||||
"@types/es6-promise": "0.0.33",
|
|
||||||
"@types/jquery": "^3.3.29",
|
"@types/jquery": "^3.3.29",
|
||||||
"@types/react": "16.4.2",
|
|
||||||
"@types/react-dom": "16.0.5",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.3.1",
|
||||||
"react": "16.3.2",
|
"office-ui-fabric-react": "6.214.0",
|
||||||
"react-dom": "16.3.2"
|
"react": "16.8.5",
|
||||||
|
"react-dom": "16.8.5"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react": "16.4.2"
|
"@types/react": "16.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "1.7.1",
|
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
||||||
"@microsoft/sp-module-interfaces": "1.7.1",
|
"@microsoft/sp-build-web": "1.11.0",
|
||||||
"@microsoft/sp-tslint-rules": "1.7.1",
|
"@microsoft/sp-module-interfaces": "1.11.0",
|
||||||
"@microsoft/sp-webpart-workbench": "1.7.1",
|
"@microsoft/sp-tslint-rules": "1.11.0",
|
||||||
|
"@microsoft/sp-webpart-workbench": "1.11.0",
|
||||||
"@types/chai": "3.4.34",
|
"@types/chai": "3.4.34",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/mocha": "2.2.38",
|
||||||
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
// 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
|
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||||
"requiresCustomScript": false,
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": ["SharePointWebPart"],
|
||||||
|
|
||||||
"preconfiguredEntries": [{
|
"preconfiguredEntries": [{
|
||||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { Version } from '@microsoft/sp-core-library';
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
import {
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
BaseClientSideWebPart,
|
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
||||||
IPropertyPaneConfiguration,
|
|
||||||
PropertyPaneTextField
|
|
||||||
} from '@microsoft/sp-webpart-base';
|
|
||||||
|
|
||||||
import * as strings from 'TenantPropertiesWebPartStrings';
|
import * as strings from 'TenantPropertiesWebPartStrings';
|
||||||
import TenantProperties from './components/TenantProperties';
|
import TenantProperties from './components/TenantProperties';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {IListViewItems } from "./IListViewItems";
|
import {IListViewItems } from "./IListViewItems";
|
||||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||||
|
import { SyntheticEvent } from "react";
|
||||||
export enum panelMode {
|
export enum panelMode {
|
||||||
"New",
|
"New",
|
||||||
"edit",
|
"edit",
|
||||||
|
@ -10,6 +11,6 @@ export interface ITenantPropertyPanelProps {
|
||||||
mode:panelMode;
|
mode:panelMode;
|
||||||
showPanel: boolean;
|
showPanel: boolean;
|
||||||
TenantProperty: IListViewItems ;
|
TenantProperty: IListViewItems ;
|
||||||
onDismiss(refresh?:boolean) : void;
|
onDismiss(ev?: SyntheticEvent<HTMLElement, Event>, refresh?: boolean) : void;
|
||||||
context: WebPartContext;
|
context: WebPartContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||||
|
|
||||||
.tenantProperties {
|
.tenantProperties {
|
||||||
.container {
|
.container {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBa
|
||||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||||
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
||||||
import * as strings from 'TenantPropertiesWebPartStrings';
|
import * as strings from 'TenantPropertiesWebPartStrings';
|
||||||
|
import { SyntheticEvent } from 'react';
|
||||||
|
|
||||||
// ListView Columns
|
// ListView Columns
|
||||||
const viewFields: IViewField[] = [
|
const viewFields: IViewField[] = [
|
||||||
|
@ -97,7 +98,7 @@ export default class TenantProperties extends React.Component<ITenantPropertiesP
|
||||||
}
|
}
|
||||||
// Panel Dismiss CallBack
|
// Panel Dismiss CallBack
|
||||||
// @param refresh refresh list?
|
// @param refresh refresh list?
|
||||||
public async onDismissPanel(refresh?: boolean) {
|
public async onDismissPanel(ev?: SyntheticEvent<HTMLElement, Event>, refresh?: boolean) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showPanel: false
|
showPanel: false
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,7 +58,9 @@ export default class TenantPropertyPanel extends React.Component<ITenantProperty
|
||||||
Description: this.state.tenantProperty.tenantPropertyDescription,
|
Description: this.state.tenantProperty.tenantPropertyDescription,
|
||||||
Comment: this.state.tenantProperty.tenantPropertyComment
|
Comment: this.state.tenantProperty.tenantPropertyComment
|
||||||
});
|
});
|
||||||
result ? this.props.onDismiss(true) : null;
|
if (result) {
|
||||||
|
this.props.onDismiss(null, true);
|
||||||
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
this.setState({errorMessage:error});
|
this.setState({errorMessage:error});
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,9 @@ export default class TenantPropertyPanel extends React.Component<ITenantProperty
|
||||||
Description: this.state.tenantProperty.tenantPropertyDescription,
|
Description: this.state.tenantProperty.tenantPropertyDescription,
|
||||||
Comment: this.state.tenantProperty.tenantPropertyComment
|
Comment: this.state.tenantProperty.tenantPropertyComment
|
||||||
});
|
});
|
||||||
result ? this.props.onDismiss(true) : null;
|
if (result) {
|
||||||
|
this.props.onDismiss(null, true);
|
||||||
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
this.setState({errorMessage:error});
|
this.setState({errorMessage:error});
|
||||||
}
|
}
|
||||||
|
@ -86,7 +90,9 @@ export default class TenantPropertyPanel extends React.Component<ITenantProperty
|
||||||
Description: this.state.tenantProperty.tenantPropertyDescription,
|
Description: this.state.tenantProperty.tenantPropertyDescription,
|
||||||
Comment: this.state.tenantProperty.tenantPropertyComment
|
Comment: this.state.tenantProperty.tenantPropertyComment
|
||||||
});
|
});
|
||||||
result ? this.props.onDismiss(true) : null;
|
if (result) {
|
||||||
|
this.props.onDismiss(null, true);
|
||||||
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
this.setState({errorMessage:error});
|
this.setState({errorMessage:error});
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 933 B |
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
@ -10,6 +11,9 @@
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
|
"inlineSources": false,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noUnusedLocals": false,
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types",
|
"./node_modules/@types",
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
|
@ -25,7 +29,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts", "src/webparts/tenantProperties/components/TenantPropertyPanel.tsx"
|
"src/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -0,0 +1,653 @@
|
||||||
|
# Upgrade project react-tenant-properties to v1.11.0
|
||||||
|
|
||||||
|
Date: 10/20/2020
|
||||||
|
|
||||||
|
## Findings
|
||||||
|
|
||||||
|
Following is the list of steps required to upgrade your project to SharePoint Framework version 1.11.0. [Summary](#Summary) of the modifications is included at the end of the report.
|
||||||
|
|
||||||
|
### FN001001 @microsoft/sp-core-library | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-core-library
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001002 @microsoft/sp-lodash-subset | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-lodash-subset
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-lodash-subset@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001003 @microsoft/sp-office-ui-fabric-core | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-office-ui-fabric-core
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-office-ui-fabric-core@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001004 @microsoft/sp-webpart-base | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package @microsoft/sp-webpart-base
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-webpart-base@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001005 @types/react | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/react
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001006 @types/react-dom | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/react-dom
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/react-dom
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001007 @types/webpack-env | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/webpack-env
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/webpack-env
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001010 @types/es6-promise | Required
|
||||||
|
|
||||||
|
Remove SharePoint Framework dependency package @types/es6-promise
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm un -S @types/es6-promise
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001021 @microsoft/sp-property-pane | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dependency package @microsoft/sp-property-pane
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-property-pane@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001022 office-ui-fabric-react | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dependency package office-ui-fabric-react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE office-ui-fabric-react@6.214.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002001 @microsoft/sp-build-web | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-build-web
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-build-web@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002002 @microsoft/sp-module-interfaces | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-module-interfaces
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-module-interfaces@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002003 @microsoft/sp-webpart-workbench | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-webpart-workbench
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-webpart-workbench@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002009 @microsoft/sp-tslint-rules | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dev dependency package @microsoft/sp-tslint-rules
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/sp-tslint-rules@1.11.0
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002013 @types/webpack-env | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/webpack-env
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/webpack-env@1.13.1
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002014 @types/es6-promise | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/es6-promise
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/es6-promise@0.0.33
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002015 @types/react | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/react@16.8.8
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN002016 @types/react-dom | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @types/react-dom
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @types/react-dom@16.8.3
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN006004 package-solution.json developer | Optional
|
||||||
|
|
||||||
|
In package-solution.json add developer section
|
||||||
|
|
||||||
|
In file [./config/package-solution.json](./config/package-solution.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"solution": {
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./config/package-solution.json](./config/package-solution.json)
|
||||||
|
|
||||||
|
### FN010001 .yo-rc.json version | Recommended
|
||||||
|
|
||||||
|
Update version in .yo-rc.json
|
||||||
|
|
||||||
|
In file [./.yo-rc.json](./.yo-rc.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.11.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./.yo-rc.json](./.yo-rc.json)
|
||||||
|
|
||||||
|
### FN012012 tsconfig.json include property | Required
|
||||||
|
|
||||||
|
Update tsconfig.json include property
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN002012 @microsoft/rush-stack-compiler-3.3 | Required
|
||||||
|
|
||||||
|
Install SharePoint Framework dev dependency package @microsoft/rush-stack-compiler-3.3
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -DE @microsoft/rush-stack-compiler-3.3@0.3.5
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN012017 tsconfig.json extends property | Required
|
||||||
|
|
||||||
|
Update tsconfig.json extends property
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN016004 Property pane property import change to @microsoft/sp-property-pane | Required
|
||||||
|
|
||||||
|
Refactor the code to import property pane property from the @microsoft/sp-property-pane npm package instead of the @microsoft/sp-webpart-base package
|
||||||
|
|
||||||
|
In file [src/webparts/tenantProperties/TenantPropertiesWebPart.ts](src/webparts/tenantProperties/TenantPropertiesWebPart.ts) update the code as follows:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
|
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [src/webparts/tenantProperties/TenantPropertiesWebPart.ts:4:1](src/webparts/tenantProperties/TenantPropertiesWebPart.ts)
|
||||||
|
|
||||||
|
### FN020001 @types/react | Required
|
||||||
|
|
||||||
|
Add resolution for package @types/react
|
||||||
|
|
||||||
|
In file [./package.json](./package.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resolutions": {
|
||||||
|
"@types/react": "16.8.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN021001 main | Required
|
||||||
|
|
||||||
|
Add package.json property
|
||||||
|
|
||||||
|
In file [./package.json](./package.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"main": "lib/index.js"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001008 react | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package react
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE react@16.8.5
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN001009 react-dom | Required
|
||||||
|
|
||||||
|
Upgrade SharePoint Framework dependency package react-dom
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE react-dom@16.8.5
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
### FN022001 Scss file import | Required
|
||||||
|
|
||||||
|
Remove scss file import
|
||||||
|
|
||||||
|
In file [src/webparts/tenantProperties/components/TenantProperties.module.scss](src/webparts/tenantProperties/components/TenantProperties.module.scss) update the code as follows:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss'
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [src/webparts/tenantProperties/components/TenantProperties.module.scss](src/webparts/tenantProperties/components/TenantProperties.module.scss)
|
||||||
|
|
||||||
|
### FN022002 Scss file import | Optional
|
||||||
|
|
||||||
|
Add scss file import
|
||||||
|
|
||||||
|
In file [src/webparts/tenantProperties/components/TenantProperties.module.scss](src/webparts/tenantProperties/components/TenantProperties.module.scss) update the code as follows:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@import '~office-ui-fabric-react/dist/sass/References.scss'
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [src/webparts/tenantProperties/components/TenantProperties.module.scss](src/webparts/tenantProperties/components/TenantProperties.module.scss)
|
||||||
|
|
||||||
|
### FN011011 Web part manifest supportedHosts | Required
|
||||||
|
|
||||||
|
Update the supportedHosts property in the manifest
|
||||||
|
|
||||||
|
In file [src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json](src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"supportedHosts": ["SharePointWebPart"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json](src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json)
|
||||||
|
|
||||||
|
### FN012014 tsconfig.json compiler options inlineSources | Required
|
||||||
|
|
||||||
|
Update tsconfig.json inlineSources value
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"inlineSources": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN012015 tsconfig.json compiler options strictNullChecks | Required
|
||||||
|
|
||||||
|
Update tsconfig.json strictNullChecks value
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN012016 tsconfig.json compiler options noUnusedLocals | Required
|
||||||
|
|
||||||
|
Update tsconfig.json noUnusedLocals value
|
||||||
|
|
||||||
|
In file [./tsconfig.json](./tsconfig.json) update the code as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"noUnusedLocals": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
### FN018001 Web part Microsoft Teams tab resources folder | Optional
|
||||||
|
|
||||||
|
Create folder for Microsoft Teams tab resources
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [teams](teams)
|
||||||
|
|
||||||
|
### FN018003 Web part Microsoft Teams tab small icon | Optional
|
||||||
|
|
||||||
|
Create Microsoft Teams tab small icon for the web part
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp /home/jfmr/.nvm/versions/node/v10.20.1/lib/node_modules/@pnp/cli-microsoft365/dist/m365/spfx/commands/project/project-upgrade/assets/tab20x20.png /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams/fe85bc01-3650-4533-9c42-5c078fdd579c_outline.png
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [teams/fe85bc01-3650-4533-9c42-5c078fdd579c_outline.png](teams/fe85bc01-3650-4533-9c42-5c078fdd579c_outline.png)
|
||||||
|
|
||||||
|
### FN018004 Web part Microsoft Teams tab large icon | Optional
|
||||||
|
|
||||||
|
Create Microsoft Teams tab large icon for the web part
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp /home/jfmr/.nvm/versions/node/v10.20.1/lib/node_modules/@pnp/cli-microsoft365/dist/m365/spfx/commands/project/project-upgrade/assets/tab96x96.png /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams/fe85bc01-3650-4533-9c42-5c078fdd579c_color.png
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [teams/fe85bc01-3650-4533-9c42-5c078fdd579c_color.png](teams/fe85bc01-3650-4533-9c42-5c078fdd579c_color.png)
|
||||||
|
|
||||||
|
### FN017001 Run npm dedupe | Optional
|
||||||
|
|
||||||
|
If, after upgrading npm packages, when building the project you have errors similar to: "error TS2345: Argument of type 'SPHttpClientConfiguration' is not assignable to parameter of type 'SPHttpClientConfiguration'", try running 'npm dedupe' to cleanup npm packages.
|
||||||
|
|
||||||
|
Execute the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm dedupe
|
||||||
|
```
|
||||||
|
|
||||||
|
File: [./package.json](./package.json)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
### Execute script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -SE @microsoft/sp-core-library@1.11.0 @microsoft/sp-lodash-subset@1.11.0 @microsoft/sp-office-ui-fabric-core@1.11.0 @microsoft/sp-webpart-base@1.11.0 @microsoft/sp-property-pane@1.11.0 office-ui-fabric-react@6.214.0 react@16.8.5 react-dom@16.8.5
|
||||||
|
npm i -DE @microsoft/sp-build-web@1.11.0 @microsoft/sp-module-interfaces@1.11.0 @microsoft/sp-webpart-workbench@1.11.0 @microsoft/sp-tslint-rules@1.11.0 @types/webpack-env@1.13.1 @types/es6-promise@0.0.33 @types/react@16.8.8 @types/react-dom@16.8.3 @microsoft/rush-stack-compiler-3.3@0.3.5
|
||||||
|
npm un -S @types/react @types/react-dom @types/webpack-env @types/es6-promise
|
||||||
|
npm dedupe
|
||||||
|
mkdir /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams
|
||||||
|
cp /home/jfmr/.nvm/versions/node/v10.20.1/lib/node_modules/@pnp/cli-microsoft365/dist/m365/spfx/commands/project/project-upgrade/assets/tab20x20.png /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams/fe85bc01-3650-4533-9c42-5c078fdd579c_outline.png
|
||||||
|
cp /home/jfmr/.nvm/versions/node/v10.20.1/lib/node_modules/@pnp/cli-microsoft365/dist/m365/spfx/commands/project/project-upgrade/assets/tab96x96.png /home/jfmr/dev/github/sp-dev-fx-webparts/samples/react-tenant-properties/teams/fe85bc01-3650-4533-9c42-5c078fdd579c_color.png
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modify files
|
||||||
|
|
||||||
|
#### [./config/package-solution.json](./config/package-solution.json)
|
||||||
|
|
||||||
|
In package-solution.json add developer section:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"solution": {
|
||||||
|
"developer": {
|
||||||
|
"name": "Contoso",
|
||||||
|
"privacyUrl": "https://contoso.com/privacy",
|
||||||
|
"termsOfUseUrl": "https://contoso.com/terms-of-use",
|
||||||
|
"websiteUrl": "https://contoso.com/my-app",
|
||||||
|
"mpnId": "000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [./.yo-rc.json](./.yo-rc.json)
|
||||||
|
|
||||||
|
Update version in .yo-rc.json:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@microsoft/generator-sharepoint": {
|
||||||
|
"version": "1.11.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [./tsconfig.json](./tsconfig.json)
|
||||||
|
|
||||||
|
Update tsconfig.json include property:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"src/**/*.tsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Update tsconfig.json extends property:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Update tsconfig.json inlineSources value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"inlineSources": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Update tsconfig.json strictNullChecks value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Update tsconfig.json noUnusedLocals value:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"noUnusedLocals": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [src/webparts/tenantProperties/TenantPropertiesWebPart.ts](src/webparts/tenantProperties/TenantPropertiesWebPart.ts)
|
||||||
|
|
||||||
|
Refactor the code to import property pane property from the @microsoft/sp-property-pane npm package instead of the @microsoft/sp-webpart-base package:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
|
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [./package.json](./package.json)
|
||||||
|
|
||||||
|
Add resolution for package @types/react:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resolutions": {
|
||||||
|
"@types/react": "16.8.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Add package.json property:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"main": "lib/index.js"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [src/webparts/tenantProperties/components/TenantProperties.module.scss](src/webparts/tenantProperties/components/TenantProperties.module.scss)
|
||||||
|
|
||||||
|
Remove scss file import:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss'
|
||||||
|
```
|
||||||
|
|
||||||
|
Add scss file import:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@import '~office-ui-fabric-react/dist/sass/References.scss'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json](src/webparts/tenantProperties/TenantPropertiesWebPart.manifest.json)
|
||||||
|
|
||||||
|
Update the supportedHosts property in the manifest:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"supportedHosts": ["SharePointWebPart"]
|
||||||
|
}
|
||||||
|
```
|