Merge branch 'main' into React-List-Items-Menu-SPfx-Upgrade
This commit is contained in:
commit
5e32931fc9
|
@ -128,6 +128,10 @@ This Web Part illustrates the following concepts on top of the SharePoint Framew
|
||||||
|
|
||||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/labels/YOUR-SOLUTION-NAME) to see if anybody else is having the same issues.
|
||||||
|
|
||||||
|
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=label%3AYOUR-SOLUTION-NAME) and see what the community is saying.
|
||||||
|
|
||||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
||||||
|
|
||||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=YOUR-SOLUTION-NAME&authors=@YOURGITHUBUSERNAME&title=YOUR-SOLUTION-NAME%20-%20).
|
||||||
|
|
|
@ -47,6 +47,7 @@ Solution|Author(s)
|
||||||
js-modern-calendar | Jeremy Coleman (MCP, PC Professional, Inc.)
|
js-modern-calendar | Jeremy Coleman (MCP, PC Professional, Inc.)
|
||||||
js-modern-calendar | Nanddeep Nachan ([@NanddeepNachan](twitter.com/NanddeepNachan))
|
js-modern-calendar | Nanddeep Nachan ([@NanddeepNachan](twitter.com/NanddeepNachan))
|
||||||
js-modern-calendar | Ravi Chandra ([Ravikadri](https://github.com/Ravikadri))
|
js-modern-calendar | Ravi Chandra ([Ravikadri](https://github.com/Ravikadri))
|
||||||
|
js-modern-calendar | Peter Paul Kirschner ([@petkir_at](https://twitter.com/petkir_at))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ Version|Date|Comments
|
||||||
1.0.0.0|February 11, 2017|Initial release
|
1.0.0.0|February 11, 2017|Initial release
|
||||||
1.0.0.1|June 05, 2020|Updated the external CDN references to public CDN references
|
1.0.0.1|June 05, 2020|Updated the external CDN references to public CDN references
|
||||||
1.0.2.0|February 9, 2021|Upgraded to SPFx 1.11 and fixed issues with missing dependencies
|
1.0.2.0|February 9, 2021|Upgraded to SPFx 1.11 and fixed issues with missing dependencies
|
||||||
|
1.0.3.0|October 28, 2021|fixed issues with Timezones. The Browser Timezone Settings are now used
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.6.0"
|
"value": "1.11.0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
@ -45,6 +45,13 @@
|
||||||
"pictureUrl": "https://github.com/nanddeepn.png",
|
"pictureUrl": "https://github.com/nanddeepn.png",
|
||||||
"name": "Nanddeep Nachan",
|
"name": "Nanddeep Nachan",
|
||||||
"twitter": "NanddeepNachan"
|
"twitter": "NanddeepNachan"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gitHubAccount": "petkir",
|
||||||
|
"company": "Cubido Business Solutions GmbH",
|
||||||
|
"pictureUrl": "https://github.com/petkir.png",
|
||||||
|
"name": "Peter Paul Kirschner",
|
||||||
|
"twitter": "petkir_at"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "SPFx Modern Calendar",
|
"name": "SPFx Modern Calendar",
|
||||||
"id": "3d593a2f-73f1-486f-9dae-555c6f6b584d",
|
"id": "3d593a2f-73f1-486f-9dae-555c6f6b584d",
|
||||||
"version": "1.0.2.0",
|
"version": "1.0.3.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"developer": {
|
"developer": {
|
||||||
"name": "",
|
"name": "",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "modern-calendar",
|
"name": "modern-calendar",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -390,10 +390,12 @@ export default class ModernCalendarWebPart extends BaseClientSideWebPart<IModern
|
||||||
|
|
||||||
private _renderList(items: any[]): void {
|
private _renderList(items: any[]): void {
|
||||||
var calItems: EventObjectInput[] = items.map((list: any) => {
|
var calItems: EventObjectInput[] = items.map((list: any) => {
|
||||||
|
const start = list[this.properties.start];
|
||||||
|
const end = list[this.properties.end];
|
||||||
return {
|
return {
|
||||||
title: list[this.properties.title],
|
title: list[this.properties.title],
|
||||||
start: list[this.properties.start],
|
start: moment.utc(start,'YYYY-MM-DD HH:mm:ss').toDate(),
|
||||||
end: list[this.properties.end],
|
end: moment.utc(end,'YYYY-MM-DD HH:mm:ss').toDate(),
|
||||||
id: list["Id"],
|
id: list["Id"],
|
||||||
detail: list[this.properties.detail],
|
detail: list[this.properties.detail],
|
||||||
};
|
};
|
||||||
|
@ -405,9 +407,9 @@ export default class ModernCalendarWebPart extends BaseClientSideWebPart<IModern
|
||||||
events: calItems,
|
events: calItems,
|
||||||
eventClick: (_event) => {
|
eventClick: (_event) => {
|
||||||
var eventDetail =
|
var eventDetail =
|
||||||
moment(_event["start"]).format("MM/DD/YYYY hh:mm") +
|
moment.utc(_event["start"]).local().format('YYYY-MM-DD hh:mm A') +
|
||||||
" - " +
|
" - " +
|
||||||
moment(_event["end"]).format("MM/DD/YYYY hh:mm") +
|
moment.utc(_event["end"]).local().format('YYYY-MM-DD hh:mm A') +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
_event["detail"];
|
_event["detail"];
|
||||||
swal2.default(_event.title, eventDetail, "info");
|
swal2.default(_event.title, eventDetail, "info");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# react-at-a-glance
|
# At a glance
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ This sample shows a web part to show the first few sentences of an article in a
|
||||||
The idea is based of the *At a glance* section of a news in the BBC news app (beta).
|
The idea is based of the *At a glance* section of a news in the BBC news app (beta).
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
- Usage of `SPHttpClient` or `PnP JS`
|
- Usage of `SPHttpClient` or `PnPjs`
|
||||||
- Conditional property enabling
|
- Conditional property enabling
|
||||||
- Usage of regex to get the sentences from article content
|
- Usage of regex to get the sentences from article content
|
||||||
- Usage of Carousel for mobile view
|
- Usage of Carousel for mobile view
|
||||||
|
@ -31,14 +31,16 @@ The idea is based of the *At a glance* section of a news in the BBC news app (be
|
||||||
|
|
||||||
![article-content-desktop](./assets/article-content-desktop.png)
|
![article-content-desktop](./assets/article-content-desktop.png)
|
||||||
|
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to a news page to work")
|
||||||
|
![Hosted Workbench Partially](https://img.shields.io/badge/Hosted%20Workbench-Partially-yellow.svg "The solution needs to run on a news page to work")
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -62,17 +64,18 @@ react-at-a-glance | [Anoop Tatti](https://github.com/anoopt) ([https://linktr.ee
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|September 07, 2021|Initial release
|
1.0|September 07, 2021|Initial release
|
||||||
|
1.1|October 20, 2021|Minor CSS changes
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
- Ensure that you are at the solution folder
|
- Ensure that you are at the solution folder
|
||||||
- in the command-line run:
|
- in the command-line run:
|
||||||
- **npm install**
|
- `npm install`
|
||||||
- **gulp serve**
|
- `gulp serve`
|
||||||
- Open a news article
|
- Open a news article
|
||||||
- Add `?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js` to the URL
|
- Add `?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js` to the URL
|
||||||
- Add the `At a glance` web part to the page
|
- Add the **At a glance** web part to the page
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"The idea is based of the At a glance section of a news in the BBC news app."
|
"The idea is based of the At a glance section of a news in the BBC news app."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2021-09-07",
|
"creationDateTime": "2021-09-07",
|
||||||
"updateDateTime": "2021-09-07",
|
"updateDateTime": "2021-10-20",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -77,6 +77,10 @@ export default class NewsGlanceWebPart extends BaseClientSideWebPart<INewsGlance
|
||||||
let element: any;
|
let element: any;
|
||||||
|
|
||||||
if (this.width < 400) {
|
if (this.width < 400) {
|
||||||
|
this.sentences = this.sentences.map(sentence => {
|
||||||
|
return sentence.length > 100 ? `${sentence.slice(0, 100)}...` : sentence;
|
||||||
|
});
|
||||||
|
|
||||||
element = React.createElement(
|
element = React.createElement(
|
||||||
NewsGlanceSmall,
|
NewsGlanceSmall,
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,13 +25,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftItem {
|
.leftItem {
|
||||||
max-width: 150px;
|
max-width: 200px;
|
||||||
object-fit: contain;
|
flex: 1;
|
||||||
align-self: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rightItem {
|
.rightItem {
|
||||||
flex: 1 1 auto;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.articleImage {
|
.articleImage {
|
||||||
|
|
|
@ -8,10 +8,8 @@
|
||||||
|
|
||||||
.carouselItem {
|
.carouselItem {
|
||||||
background-color: $ms-color-themeDark;
|
background-color: $ms-color-themeDark;
|
||||||
// display: flex;
|
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
height: 98%;
|
height: 98%;
|
||||||
// justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carouselDotList {
|
.carouselDotList {
|
||||||
|
|
|
@ -140,6 +140,7 @@ Version|Date|Comments
|
||||||
1.0.11|May 10, 2021|Optimized page refresh using local storage
|
1.0.11|May 10, 2021|Optimized page refresh using local storage
|
||||||
1.0.12|June 21, 2021|Fixes overlap with Year-view and the comment section by adding a vertical scrollbar.
|
1.0.12|June 21, 2021|Fixes overlap with Year-view and the comment section by adding a vertical scrollbar.
|
||||||
1.0.13|October 2, 2021|Fix to make sure Today is always visible and highlighted.
|
1.0.13|October 2, 2021|Fix to make sure Today is always visible and highlighted.
|
||||||
|
1.0.14|October 16, 2021|Resolve unhandled exception that happens clicking on recurrent events
|
||||||
|
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
"longDescription": [
|
"longDescription": [
|
||||||
"This Web Part allows you to manage events in a calendar. Uses a list of existing calendars on any website. The location and name of the list and the dates of the events to be displayed are defined in the properties of the web part."
|
"This Web Part allows you to manage events in a calendar. Uses a list of existing calendars on any website. The location and name of the list and the dates of the events to be displayed are defined in the properties of the web part."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2020-12-04",
|
"created": "2020-12-04",
|
||||||
"updateDateTime": "2021-10-02",
|
"modified": "2021-10-16",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -369,6 +369,8 @@ export default class parseRecurrentEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.fRecurrence === "1" && e.MasterSeriesItemID !== "") {
|
if (e.fRecurrence === "1" && e.MasterSeriesItemID !== "") {
|
||||||
|
e.EventDate = new Date(this.parseDate(e.EventDate, e.fAllDayEvent));
|
||||||
|
e.EndDate = new Date(this.parseDate(e.EndDate, e.fAllDayEvent));
|
||||||
const ni = this.cloneObj(e);
|
const ni = this.cloneObj(e);
|
||||||
er.push(ni);
|
er.push(ni);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ I got the idea from this great article [Use Power Automate to Notify of Upcoming
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
![Node.js LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
||||||
|
@ -32,6 +32,7 @@ react-graph-app-secret-expiration | [Aimery Thomas](https://github.com/a1mery) (
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|September 17, 2021|Initial release
|
1.0|September 17, 2021|Initial release
|
||||||
|
1.1|October 10, 2021|Add pagination
|
||||||
|
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
@ -39,14 +40,14 @@ Version|Date|Comments
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
- Ensure that you are at the solution folder
|
- Ensure that you are at the solution folder
|
||||||
- In the command-line run:
|
- In the command-line run:
|
||||||
- **npm install**
|
- `npm install`
|
||||||
- **gulp bundle**
|
- `gulp bundle`
|
||||||
- **gulp package-solution**
|
- `gulp package-solution`
|
||||||
- Deploy the package to your app catalog
|
- Deploy the package to your app catalog
|
||||||
- Approve the API permission request from the SharePoint admin
|
- Approve the API permission request from the SharePoint admin
|
||||||
- Add the web part to a page
|
- Add the web part to a page
|
||||||
- In the command-line run:
|
- In the command-line run:
|
||||||
- **gulp serve --nobrowser**
|
- `gulp serve --nobrowser`
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This sample web part shows the list of your applications registered in Azure AD along with their associated client secret/certificate expiration date."
|
"This sample web part shows the list of your applications registered in Azure AD along with their associated client secret/certificate expiration date."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2021-09-17",
|
"creationDateTime": "2021-09-17",
|
||||||
"updateDateTime": "2021-09-17",
|
"updateDateTime": "2021-10-10",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
@ -22,6 +22,10 @@
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.12.1"
|
"value": "1.12.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "PNPCONTROLS",
|
||||||
|
"value": "Pagination"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-graph-app-secret-expiration-client-side-solution",
|
"name": "react-graph-app-secret-expiration-client-side-solution",
|
||||||
"id": "b25d85a4-7310-408a-a263-25959b0a5b1b",
|
"id": "b25d85a4-7310-408a-a263-25959b0a5b1b",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-graph-app-secret-expiration",
|
"name": "react-graph-app-secret-expiration",
|
||||||
"version": "0.0.1",
|
"version": "1.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-graph-app-secret-expiration",
|
"name": "react-graph-app-secret-expiration",
|
||||||
"version": "0.0.1",
|
"version": "1.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -5,7 +5,9 @@ import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp
|
||||||
import { IApplications, IApplication, IFormattedApplication } from '../../../models/IApplication';
|
import { IApplications, IApplication, IFormattedApplication } from '../../../models/IApplication';
|
||||||
import { IGraphAppSecretExpirationState } from './GraphAppSecretExpirationState';
|
import { IGraphAppSecretExpirationState } from './GraphAppSecretExpirationState';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { DefaultButton, Spinner, mergeStyles } from '@fluentui/react';
|
import { DefaultButton, Spinner, mergeStyles, SearchBox } from '@fluentui/react';
|
||||||
|
import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
|
||||||
|
import * as strings from 'GraphAppSecretExpirationWebPartStrings';
|
||||||
|
|
||||||
const stackItemHidden = mergeStyles({
|
const stackItemHidden = mergeStyles({
|
||||||
display: 'none',
|
display: 'none',
|
||||||
|
@ -57,9 +59,13 @@ export default class GraphAppSecretExpiration extends React.Component<IGraphAppS
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
applications: [],
|
applications: [],
|
||||||
|
filteredApplications: [],
|
||||||
|
filterValue: "",
|
||||||
|
searchFilter: "",
|
||||||
error: undefined,
|
error: undefined,
|
||||||
loading: true,
|
loading: true,
|
||||||
groupByFields: []
|
groupByFields: [],
|
||||||
|
page: 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +119,6 @@ export default class GraphAppSecretExpiration extends React.Component<IGraphAppS
|
||||||
var today = (moment(Date.now())).format('DD-MMM-YYYY');
|
var today = (moment(Date.now())).format('DD-MMM-YYYY');
|
||||||
try {
|
try {
|
||||||
applications.forEach(app => {
|
applications.forEach(app => {
|
||||||
|
|
||||||
if (app.passwordCredentials.length > 0) {
|
|
||||||
app.passwordCredentials.forEach(pswd => {
|
app.passwordCredentials.forEach(pswd => {
|
||||||
let daysBeforeExpiration = moment.duration((moment(pswd.endDateTime)).diff(today, 'days'), 'days').asDays();
|
let daysBeforeExpiration = moment.duration((moment(pswd.endDateTime)).diff(today, 'days'), 'days').asDays();
|
||||||
let formatedApp: IFormattedApplication = {
|
let formatedApp: IFormattedApplication = {
|
||||||
|
@ -126,8 +130,6 @@ export default class GraphAppSecretExpiration extends React.Component<IGraphAppS
|
||||||
};
|
};
|
||||||
displayedApplication.push(formatedApp);
|
displayedApplication.push(formatedApp);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (app.keyCredentials.length > 0) {
|
|
||||||
app.keyCredentials.forEach(keyCred => {
|
app.keyCredentials.forEach(keyCred => {
|
||||||
let daysBeforeExpiration = moment.duration((moment(keyCred.endDateTime)).diff(today, 'days'), 'days').asDays();
|
let daysBeforeExpiration = moment.duration((moment(keyCred.endDateTime)).diff(today, 'days'), 'days').asDays();
|
||||||
let formatedApp: IFormattedApplication = {
|
let formatedApp: IFormattedApplication = {
|
||||||
|
@ -139,16 +141,58 @@ export default class GraphAppSecretExpiration extends React.Component<IGraphAppS
|
||||||
};
|
};
|
||||||
displayedApplication.push(formatedApp);
|
displayedApplication.push(formatedApp);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
applications: displayedApplication
|
applications: displayedApplication,
|
||||||
|
filteredApplications: displayedApplication
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _getPage(selectedPage: number) {
|
||||||
|
this.setState({
|
||||||
|
page: selectedPage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _filterApplication = (value, clear: boolean) => {
|
||||||
|
let searchResult: IFormattedApplication[] = [];
|
||||||
|
if (clear) {
|
||||||
|
this.state.applications.forEach(app => {
|
||||||
|
if (this._filterByProperties(app, value)) {
|
||||||
|
searchResult.push(app);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.setState({
|
||||||
|
filteredApplications: searchResult,
|
||||||
|
filterValue: value
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
filteredApplications: this.state.applications,
|
||||||
|
filterValue: value,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _filterByProperties(application: IFormattedApplication, filterValue) {
|
||||||
|
if (application.applicationId.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) {
|
||||||
|
return true;
|
||||||
|
} else if (application.displayName.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) {
|
||||||
|
return true;
|
||||||
|
} else if (application.expirationDate.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) {
|
||||||
|
return true;
|
||||||
|
} else if (application.type.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _groupView = () => {
|
private _groupView = () => {
|
||||||
if (this.state.groupByFields.length === 0) {
|
if (this.state.groupByFields.length === 0) {
|
||||||
let groupByFields: IGrouping[] = [
|
let groupByFields: IGrouping[] = [
|
||||||
|
@ -181,17 +225,27 @@ export default class GraphAppSecretExpiration extends React.Component<IGraphAppS
|
||||||
</div>
|
</div>
|
||||||
<div className={this.state.loading ? stackItemHidden : ""}>
|
<div className={this.state.loading ? stackItemHidden : ""}>
|
||||||
<DefaultButton text={this.state.groupByFields.length === 0 ? "Group by App ID" : "Ungroup"} onClick={this._groupView} />
|
<DefaultButton text={this.state.groupByFields.length === 0 ? "Group by App ID" : "Ungroup"} onClick={this._groupView} />
|
||||||
|
<SearchBox placeholder="Search" onChange={(e, text) => this._filterApplication(text, false)} onClear={() => this._filterApplication("", true)} value={this.state.filterValue} />
|
||||||
<ListView
|
<ListView
|
||||||
items={this.state.applications}
|
items={this.state.filteredApplications.slice(this.state.page === 1 || this.state.filterValue !== "" ? 0 : this.state.page * 10 - 10, this.state.page * 10)}
|
||||||
viewFields={_viewFields}
|
viewFields={_viewFields}
|
||||||
iconFieldName="ServerRelativeUrl"
|
iconFieldName="ServerRelativeUrl"
|
||||||
compact={true}
|
compact={true}
|
||||||
selectionMode={SelectionMode.none}
|
selectionMode={SelectionMode.none}
|
||||||
selection={this._getSelection}
|
selection={this._getSelection}
|
||||||
groupByFields={this.state.groupByFields}
|
groupByFields={this.state.groupByFields}
|
||||||
showFilter={true}
|
showFilter={false}
|
||||||
filterPlaceHolder="Search..." />
|
filterPlaceHolder="Search..." />
|
||||||
</div>
|
</div>
|
||||||
|
<Pagination
|
||||||
|
currentPage={1}
|
||||||
|
totalPages={Math.floor(this.state.filteredApplications.length / 10) + 1}
|
||||||
|
onChange={(page) => this._getPage(page)}
|
||||||
|
limiter={3} // Optional - default value 3
|
||||||
|
hideFirstPageJump // Optional
|
||||||
|
hideLastPageJump // Optional
|
||||||
|
limiterIcon={"Emoji12"} // Optional
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,11 @@ import { IApplications, IApplication,IPasswordCredential,IKeyCredential,IFormatt
|
||||||
|
|
||||||
export interface IGraphAppSecretExpirationState {
|
export interface IGraphAppSecretExpirationState {
|
||||||
applications: IFormattedApplication[];
|
applications: IFormattedApplication[];
|
||||||
|
filteredApplications: IFormattedApplication[];
|
||||||
|
filterValue: string;
|
||||||
|
searchFilter: string;
|
||||||
groupByFields: IGrouping[];
|
groupByFields: IGrouping[];
|
||||||
|
page: number;
|
||||||
error: string;
|
error: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ node_modules
|
||||||
dist
|
dist
|
||||||
lib
|
lib
|
||||||
solution
|
solution
|
||||||
|
release
|
||||||
temp
|
temp
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,13 @@ Web part pulls all Microsoft 365 Groups and Teams that the logged in user has ac
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
![SPFx 1.10](https://img.shields.io/badge/SPFx-1.10.0-green.svg)
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
![Node.js LTS 8.x | LTS 10.x](https://img.shields.io/badge/Node.js-LTS%208.x%20%7C%20LTS%210.x-green.svg)
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%202019-Not%20compatible-red.svg)
|
||||||
![Workbench Hosted: Only after API permissions granted](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Only after API permissions granted")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%202016%20(Feature%20Pack%202)-Not%20compatible-red.svg)
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "This solution requires API permissions")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-yellow.svg "Only after API permissions granted")
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ Web part pulls all Microsoft 365 Groups and Teams that the logged in user has ac
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
React-Groups-Teams | [Alison Collins](https://github.com/ReactIntern) |
|
React-Groups-Teams | [Alison Collins](https://github.com/ReactIntern) ([Blog](https://graphgod.dev), [LinkedIn](https://www.linkedin.com/in/alison-collins-53192b219/)) |
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ React-Groups-Teams | [Alison Collins](https://github.com/ReactIntern) |
|
||||||
| ------- | ---------------- | --------------- |
|
| ------- | ---------------- | --------------- |
|
||||||
| 1.0.0 | April 16, 2021 | Initial release |
|
| 1.0.0 | April 16, 2021 | Initial release |
|
||||||
| 1.0.1 | August 1, 2021 | Fixed references to Office.com |
|
| 1.0.1 | August 1, 2021 | Fixed references to Office.com |
|
||||||
|
| 1.1.0 | October 8, 2021 | Upgraded to SPFx 1.12.1 for higher compatibility and added Teams Tab deployment support. |
|
||||||
|
|
||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"Web part pulls all Microsoft 365 Groups and Teams that the logged in user has access to view."
|
"Web part pulls all Microsoft 365 Groups and Teams that the logged in user has access to view."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2021-05-06",
|
"creationDateTime": "2021-05-06",
|
||||||
"updateDateTime": "2021-08-01",
|
"updateDateTime": "2021-10-08",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.10.0"
|
"value": "1.12.1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const gulp = require('gulp');
|
|
||||||
const build = require('@microsoft/sp-build-web');
|
const build = require('@microsoft/sp-build-web');
|
||||||
|
|
||||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
build.initialize(gulp);
|
var getTasks = build.rig.getTasks;
|
||||||
|
build.rig.getTasks = function () {
|
||||||
|
var result = getTasks.call(build.rig);
|
||||||
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
build.initialize(require('gulp'));
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -12,10 +12,10 @@
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.9.1",
|
"@microsoft/sp-core-library": "1.12.1",
|
||||||
"@microsoft/sp-lodash-subset": "1.9.1",
|
"@microsoft/sp-lodash-subset": "1.12.1",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.9.1",
|
"@microsoft/sp-office-ui-fabric-core": "1.12.1",
|
||||||
"@microsoft/sp-webpart-base": "1.9.1",
|
"@microsoft/sp-webpart-base": "1.12.1",
|
||||||
"@types/es6-promise": "0.0.33",
|
"@types/es6-promise": "0.0.33",
|
||||||
"@types/react": "16.8.8",
|
"@types/react": "16.8.8",
|
||||||
"@types/react-dom": "16.8.3",
|
"@types/react-dom": "16.8.3",
|
||||||
|
@ -28,10 +28,10 @@
|
||||||
"@types/react": "16.8.8"
|
"@types/react": "16.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "1.9.1",
|
"@microsoft/sp-build-web": "1.12.1",
|
||||||
"@microsoft/sp-tslint-rules": "1.9.1",
|
"@microsoft/sp-tslint-rules": "1.12.1",
|
||||||
"@microsoft/sp-module-interfaces": "1.9.1",
|
"@microsoft/sp-module-interfaces": "1.12.1",
|
||||||
"@microsoft/sp-webpart-workbench": "1.9.1",
|
"@microsoft/sp-webpart-workbench": "1.12.1",
|
||||||
"@microsoft/rush-stack-compiler-2.9": "0.7.16",
|
"@microsoft/rush-stack-compiler-2.9": "0.7.16",
|
||||||
"gulp": "~3.9.1",
|
"gulp": "~3.9.1",
|
||||||
"@types/chai": "3.4.34",
|
"@types/chai": "3.4.34",
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"id": "5ced32db-af85-469a-a3cb-39f3986e1f1a",
|
||||||
|
"alias": "MicrosoftGroupsWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"manifestVersion": 2,
|
||||||
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": [
|
||||||
|
"SharePointWebPart",
|
||||||
|
"TeamsTab"
|
||||||
|
],
|
||||||
|
"preconfiguredEntries": [
|
||||||
|
{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
|
||||||
|
"group": {
|
||||||
|
"default": "Other"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"default": "Microsoft Groups"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"default": "Microsoft Groups description"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"description": "Microsoft Groups"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"loaderConfig": {
|
||||||
|
"internalModuleBaseUrls": [
|
||||||
|
"https://localhost:4321/dist/"
|
||||||
|
],
|
||||||
|
"entryModuleId": "microsoft-groups-web-part",
|
||||||
|
"scriptResources": {
|
||||||
|
"microsoft-groups-web-part": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "microsoft-groups-web-part_da003a7fb7fd1f14fcb7.js"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-core-library": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "7263c7d0-1d6a-45ec-8d85-d4d1d234171b",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-webpart-base": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "974a7777-0990-4136-8fa6-95d80114c2e0",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"MicrosoftGroupsWebPartStrings": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "MicrosoftGroupsWebPartStrings_en-us_b41dd8b4c7f5f69692bd8f24e2b83745.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
define([], function() {
|
||||||
|
return {
|
||||||
|
"PropertyPaneDescription": "Description",
|
||||||
|
"BasicGroupName": "Group Name",
|
||||||
|
"DescriptionFieldLabel": "Description Field"
|
||||||
|
}
|
||||||
|
});
|
1
samples/react-groups-teams/release/assets/microsoft-groups-web-part_da003a7fb7fd1f14fcb7.js
vendored
Normal file
1
samples/react-groups-teams/release/assets/microsoft-groups-web-part_da003a7fb7fd1f14fcb7.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"bundles": {
|
||||||
|
"microsoft-groups-web-part": {
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"componentId": "7263c7d0-1d6a-45ec-8d85-d4d1d234171b",
|
||||||
|
"componentName": "@microsoft/sp-core-library",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "01c4df03-e775-48cb-aa14-171ee5199a15",
|
||||||
|
"componentName": "tslib",
|
||||||
|
"componentVersion": "1.10.0",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "2e09fb9b-13bb-48f2-859f-97d6fff71176",
|
||||||
|
"componentName": "@ms/odsp-core-bundle",
|
||||||
|
"componentVersion": "1.1.13",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "73e1dc6c-8441-42cc-ad47-4bd3659f8a3a",
|
||||||
|
"componentName": "@microsoft/sp-lodash-subset",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "974a7777-0990-4136-8fa6-95d80114c2e0",
|
||||||
|
"componentName": "@microsoft/sp-webpart-base",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "8217e442-8ed3-41fd-957d-b112e841286a",
|
||||||
|
"componentName": "@ms/sp-telemetry",
|
||||||
|
"componentVersion": "0.19.2",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "467dc675-7cc5-4709-8aac-78e3b71bd2f6",
|
||||||
|
"componentName": "@microsoft/sp-component-base",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "e40f8203-b39d-425a-a957-714852e33b79",
|
||||||
|
"componentName": "@microsoft/sp-dynamic-data",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "78359e4b-07c2-43c6-8d0b-d060b4d577e8",
|
||||||
|
"componentName": "@microsoft/sp-diagnostics",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "1c4541f7-5c31-41aa-9fa8-fbc9dc14c0a8",
|
||||||
|
"componentName": "@microsoft/sp-page-context",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "229b8d08-79f3-438b-8c21-4613fc877abd",
|
||||||
|
"componentName": "@microsoft/load-themed-styles",
|
||||||
|
"componentVersion": "0.1.2",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "c07208f0-ea3b-4c1a-9965-ac1b825211a6",
|
||||||
|
"componentName": "@microsoft/sp-http",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "1c6c9123-7aac-41f3-a376-3caea41ed83f",
|
||||||
|
"componentName": "@microsoft/sp-loader",
|
||||||
|
"componentVersion": "1.12.1",
|
||||||
|
"isDirectDependency": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
|
||||||
|
"componentName": "react",
|
||||||
|
"componentVersion": "16.8.5",
|
||||||
|
"isDirectDependency": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentId": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
|
||||||
|
"componentName": "react-dom",
|
||||||
|
"componentVersion": "16.8.5",
|
||||||
|
"isDirectDependency": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"id": "5ced32db-af85-469a-a3cb-39f3986e1f1a",
|
||||||
|
"alias": "MicrosoftGroupsWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"manifestVersion": 2,
|
||||||
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": [
|
||||||
|
"SharePointWebPart",
|
||||||
|
"TeamsTab"
|
||||||
|
],
|
||||||
|
"preconfiguredEntries": [
|
||||||
|
{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
|
||||||
|
"group": {
|
||||||
|
"default": "Other"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"default": "Microsoft Groups"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"default": "Microsoft Groups description"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"description": "Microsoft Groups"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"loaderConfig": {
|
||||||
|
"internalModuleBaseUrls": [
|
||||||
|
"<!-- PATH TO CDN -->"
|
||||||
|
],
|
||||||
|
"entryModuleId": "microsoft-groups-web-part",
|
||||||
|
"scriptResources": {
|
||||||
|
"microsoft-groups-web-part": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "microsoft-groups-web-part_da003a7fb7fd1f14fcb7.js"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-core-library": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "7263c7d0-1d6a-45ec-8d85-d4d1d234171b",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-webpart-base": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "974a7777-0990-4136-8fa6-95d80114c2e0",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"MicrosoftGroupsWebPartStrings": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "MicrosoftGroupsWebPartStrings_en-us_b41dd8b4c7f5f69692bd8f24e2b83745.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"id": "5ced32db-af85-469a-a3cb-39f3986e1f1a",
|
||||||
|
"alias": "MicrosoftGroupsWebPart",
|
||||||
|
"componentType": "WebPart",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"manifestVersion": 2,
|
||||||
|
"requiresCustomScript": false,
|
||||||
|
"supportedHosts": [
|
||||||
|
"SharePointWebPart",
|
||||||
|
"TeamsTab"
|
||||||
|
],
|
||||||
|
"preconfiguredEntries": [
|
||||||
|
{
|
||||||
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
|
||||||
|
"group": {
|
||||||
|
"default": "Other"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"default": "Microsoft Groups"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"default": "Microsoft Groups description"
|
||||||
|
},
|
||||||
|
"officeFabricIconFontName": "Page",
|
||||||
|
"properties": {
|
||||||
|
"description": "Microsoft Groups"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"loaderConfig": {
|
||||||
|
"internalModuleBaseUrls": [
|
||||||
|
"<!-- PATH TO CDN -->"
|
||||||
|
],
|
||||||
|
"entryModuleId": "microsoft-groups-web-part",
|
||||||
|
"scriptResources": {
|
||||||
|
"microsoft-groups-web-part": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "microsoft-groups-web-part_da003a7fb7fd1f14fcb7.js"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-core-library": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "7263c7d0-1d6a-45ec-8d85-d4d1d234171b",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"@microsoft/sp-webpart-base": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "974a7777-0990-4136-8fa6-95d80114c2e0",
|
||||||
|
"version": "1.12.1"
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "0d910c1c-13b9-4e1c-9aa4-b008c5e42d7d",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"type": "component",
|
||||||
|
"id": "aa0a46ec-1505-43cd-a44a-93f3a5aa460a",
|
||||||
|
"version": "16.8.5"
|
||||||
|
},
|
||||||
|
"MicrosoftGroupsWebPartStrings": {
|
||||||
|
"type": "path",
|
||||||
|
"path": "MicrosoftGroupsWebPartStrings_en-us_b41dd8b4c7f5f69692bd8f24e2b83745.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +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"],
|
"supportedHosts": ["SharePointWebPart", "TeamsTab"],
|
||||||
|
|
||||||
"preconfiguredEntries": [{
|
"preconfiguredEntries": [{
|
||||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
# 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
|
|
|
@ -11,6 +11,7 @@ dist
|
||||||
lib
|
lib
|
||||||
solution
|
solution
|
||||||
temp
|
temp
|
||||||
|
release
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
!dist
|
||||||
|
config
|
||||||
|
|
||||||
|
gulpfile.js
|
||||||
|
|
||||||
|
release
|
||||||
|
src
|
||||||
|
temp
|
||||||
|
|
||||||
|
tsconfig.json
|
||||||
|
tslint.json
|
||||||
|
|
||||||
|
*.log
|
||||||
|
|
||||||
|
.yo-rc.json
|
||||||
|
.vscode
|
|
@ -4,23 +4,7 @@
|
||||||
* Chrome browser: https://aka.ms/spfx-debugger-extensions
|
* Chrome browser: https://aka.ms/spfx-debugger-extensions
|
||||||
*/
|
*/
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [{
|
"configurations": [
|
||||||
"name": "Local workbench",
|
|
||||||
"type": "chrome",
|
|
||||||
"request": "launch",
|
|
||||||
"url": "https://localhost:4321/temp/workbench.html",
|
|
||||||
"webRoot": "${workspaceRoot}",
|
|
||||||
"sourceMaps": true,
|
|
||||||
"sourceMapPathOverrides": {
|
|
||||||
"webpack:///.././src/*": "${webRoot}/src/*",
|
|
||||||
"webpack:///../../../src/*": "${webRoot}/src/*",
|
|
||||||
"webpack:///../../../../src/*": "${webRoot}/src/*",
|
|
||||||
"webpack:///../../../../../src/*": "${webRoot}/src/*"
|
|
||||||
},
|
|
||||||
"runtimeArgs": [
|
|
||||||
"--remote-debugging-port=9222"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Hosted workbench",
|
"name": "Hosted workbench",
|
||||||
"type": "chrome",
|
"type": "chrome",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
"version": "1.10.0",
|
"version": "1.13.0",
|
||||||
"libraryName": "react-kanban-board",
|
"libraryName": "react-kanban-board",
|
||||||
"libraryId": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
"libraryId": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
|
|
@ -24,9 +24,17 @@ The web part uses the default columns of the SharePoint Tasks list for showing t
|
||||||
|
|
||||||
![picture of the web part in action](assets/kanbanofficeUI.gif)
|
![picture of the web part in action](assets/kanbanofficeUI.gif)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
|
|
||||||
![1.10.0](https://img.shields.io/badge/version-1.10.0-green.svg)
|
## Compatibility
|
||||||
|
|
||||||
|
![SPFx 1.13.0](https://img.shields.io/badge/SPFx-1.13.0-green.svg)
|
||||||
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -49,9 +57,10 @@ The Task list can be chosen using the web part properties (BaseTemplate 171 or 1
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-kanban-board | [Ram](https://twitter.com/ram_meenavalli)
|
react-kanban-board | [Ram Prasad Meenavalli](https://github.com/RamPrasadMeenavalli) ([@ram_meenavalli](https://twitter.com/ram_meenavalli))
|
||||||
react-kanban-board | Daniel Westerdale ([Westerdale Solutions Ltd.](https://westerdale.blog), [@westerdaled](https://twitter.com/westerdaled?s=20))
|
react-kanban-board | [Daniel Westerdale](https://github.com/westerdaled) ([Westerdale Solutions Ltd.](https://westerdale.blog), [@westerdaled](https://twitter.com/westerdaled?s=20))
|
||||||
react-kanban-board | Peter Paul Kirschner ([@petkir_at](https://twitter.com/petkir_at))
|
react-kanban-board | [Peter Paul Kirschner](https://github.com/petkir) ([@petkir_at](https://twitter.com/petkir_at))
|
||||||
|
react-kanban-board | [Alex Terentiev](https://github.com/AJIXuMuK) ([@alexaterentiev](https://twitter.com/alexaterentiev))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
@ -60,6 +69,7 @@ Version|Date|Comments
|
||||||
1.0.0.0|July 17, 2019|Initial release
|
1.0.0.0|July 17, 2019|Initial release
|
||||||
1.0.1.0|April 21, 2020|Added support for Teams hosts
|
1.0.1.0|April 21, 2020|Added support for Teams hosts
|
||||||
2.0.0.0|July 10, 2020| jqwidgets replaced with a custom Kanban Board based on Office UI Component and IE11 Support
|
2.0.0.0|July 10, 2020| jqwidgets replaced with a custom Kanban Board based on Office UI Component and IE11 Support
|
||||||
|
3.0.0.0|October 29, 2021| SPFx 1.13, PnPJS v2, PnP Controls v3
|
||||||
|
|
||||||
[Read More about the implementation of this Board](./src/kanban/README.md)
|
[Read More about the implementation of this Board](./src/kanban/README.md)
|
||||||
|
|
||||||
|
@ -80,13 +90,6 @@ Version|Date|Comments
|
||||||
<!---* [Jean-Philippe CIVADE](https://github.com/ewidance) for Bug Report IE11 (initiator of rewrite of this sample)-->
|
<!---* [Jean-Philippe CIVADE](https://github.com/ewidance) for Bug Report IE11 (initiator of rewrite of this sample)-->
|
||||||
<!---* [RamPrasadMeenavalli](https://github.com/RamPrasadMeenavalli) for the initial Idea-->
|
<!---* [RamPrasadMeenavalli](https://github.com/RamPrasadMeenavalli) for the initial Idea-->
|
||||||
|
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
* Clone this repository
|
* Clone this repository
|
||||||
|
@ -102,4 +105,26 @@ This sample highlights the following concepts
|
||||||
|
|
||||||
When a task is moved to different columns in the Kanban Board, the status of the respective SharePoint list item is updated using PnP JS
|
When a task is moved to different columns in the Kanban Board, the status of the respective SharePoint list item is updated using PnP JS
|
||||||
|
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/labels/react-kanban-board) to see if anybody else is having the same issues.
|
||||||
|
|
||||||
|
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=label%3Areact-kanban-board) and see what the community is saying
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-kanban-board&authors=@RamPrasadMeenavalli%20@westerdaled%20@petkir%20@AJIXuMuK&title=react-kanban-board%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-kanban-board&authors=@RamPrasadMeenavalli%20@westerdaled%20@petkir%20@AJIXuMuK&title=react-kanban-board%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-kanban-board&authors=@RamPrasadMeenavalli%20@westerdaled%20@petkir%20@AJIXuMuK&title=react-kanban-board%20-%20).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-kanban-board" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-kanban-board" />
|
||||||
|
|
|
@ -21,11 +21,15 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.10.0"
|
"value": "1.13.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-TEAMSTAB",
|
"key": "SPFX-TEAMSTAB",
|
||||||
"value": "true"
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "PNPCONTROLS",
|
||||||
|
"value": "PropertyFieldListPicker, PropertyFieldOrder, WebPartTitle, Placeholder"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
@ -57,6 +61,13 @@
|
||||||
"pictureUrl": "https://github.com/petkir.png",
|
"pictureUrl": "https://github.com/petkir.png",
|
||||||
"name": "Peter Paul Kirschner",
|
"name": "Peter Paul Kirschner",
|
||||||
"twitter": "petkir_at"
|
"twitter": "petkir_at"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gitHubAccount": "AJIXuMuK",
|
||||||
|
"company": "Sharepointalist",
|
||||||
|
"pictureUrl": "https://avatars.githubusercontent.com/u/17036219?s=460\u0026u=b8e83fb70a90eae0c0e0078c206990785e1a5b6f\u0026v=4",
|
||||||
|
"name": "Alex Terentiev",
|
||||||
|
"twitter": "alexaterentiev"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
|
||||||
"deployCdnPath": "temp/deploy"
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
"workingDir": "./temp/deploy/",
|
"workingDir": "./release/assets/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "react-kanban-board",
|
"container": "react-kanban-board",
|
||||||
"accessKey": "<!-- ACCESS KEY -->"
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
|
|
@ -3,10 +3,17 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-kanban-board-client-side-solution",
|
"name": "react-kanban-board-client-side-solution",
|
||||||
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
||||||
"version": "2.0.0.0",
|
"version": "3.0.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false,
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"mpnId": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-kanban-board.sppkg"
|
"zippedPackage": "solution/react-kanban-board.sppkg"
|
||||||
|
|
|
@ -2,9 +2,5 @@
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||||
"port": 4321,
|
"port": 4321,
|
||||||
"https": true,
|
"https": true,
|
||||||
"initialPage": "https://localhost:5432/workbench",
|
"initialPage": "https://enter-your-SharePoint-site/_layouts/workbench.aspx"
|
||||||
"api": {
|
|
||||||
"port": 5432,
|
|
||||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,50 +6,13 @@ const gulp = require('gulp');
|
||||||
const build = require('@microsoft/sp-build-web');
|
const build = require('@microsoft/sp-build-web');
|
||||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||||
|
|
||||||
// This section is inspired by Stefan Bauer's article at https://n8d.at/how-to-version-new-sharepoint-framework-projects/
|
var getTasks = build.rig.getTasks;
|
||||||
// Stefan rocks!
|
build.rig.getTasks = function () {
|
||||||
let syncVersionsSubtask = build.subTask('version-sync', function (gulp, buildOptions, done) {
|
var result = getTasks.call(build.rig);
|
||||||
this.log('Synching versions');
|
|
||||||
|
|
||||||
// import gulp utilits to write error messages
|
|
||||||
const gutil = require('gulp-util');
|
|
||||||
|
|
||||||
// import file system utilities form nodeJS
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
// read package.json
|
|
||||||
var pkgConfig = require('./package.json');
|
|
||||||
|
|
||||||
// read configuration of web part solution file
|
|
||||||
var pkgSolution = require('./config/package-solution.json');
|
|
||||||
|
|
||||||
// log old version
|
|
||||||
this.log('package-solution.json version:\t' + pkgSolution.solution.version);
|
|
||||||
|
|
||||||
// Generate new MS compliant version number
|
|
||||||
var newVersionNumber = pkgConfig.version.split('-')[0] + '.0';
|
|
||||||
|
|
||||||
if (pkgSolution.solution.version !== newVersionNumber) {
|
|
||||||
// assign newly generated version number to web part version
|
|
||||||
pkgSolution.solution.version = newVersionNumber;
|
|
||||||
|
|
||||||
// log new version
|
|
||||||
this.log('New package-solution.json version:\t' + pkgSolution.solution.version);
|
|
||||||
|
|
||||||
fs.writeFile('./config/package-solution.json', JSON.stringify(pkgSolution, null, 4), function (err, result) {
|
|
||||||
if (err) this.log('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.log('package-solution.json version is up-to-date');
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
let syncVersionTask = build.task('version-sync', syncVersionsSubtask);
|
|
||||||
build.rig.addPreBuildTask(syncVersionTask);
|
|
||||||
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
build.initialize(gulp);
|
build.initialize(gulp);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,53 +1,39 @@
|
||||||
{
|
{
|
||||||
"name": "react-kanban-board",
|
"name": "react-kanban-board",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": "undefined",
|
||||||
"node": ">=0.10.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp bundle",
|
"build": "gulp bundle",
|
||||||
"clean": "gulp clean",
|
"clean": "gulp clean",
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.10.0",
|
"@microsoft/sp-core-library": "1.13.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.10.0",
|
"@microsoft/sp-lodash-subset": "1.13.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.10.0",
|
"@microsoft/sp-office-ui-fabric-core": "1.13.0",
|
||||||
"@microsoft/sp-property-pane": "1.10.0",
|
"@microsoft/sp-property-pane": "1.13.0",
|
||||||
"@microsoft/sp-webpart-base": "1.10.0",
|
"@microsoft/sp-webpart-base": "1.13.0",
|
||||||
"@pnp/common": "^1.3.3",
|
"@pnp/sp": "2.10.0",
|
||||||
"@pnp/logging": "^1.3.3",
|
"@pnp/spfx-controls-react": "^3.5.0-beta.2d993b2",
|
||||||
"@pnp/odata": "^1.3.3",
|
"@pnp/spfx-property-controls": "^3.3.0-beta.d48002e",
|
||||||
"@pnp/polyfill-ie11": "^2.0.2",
|
"office-ui-fabric-react": "7.174.1",
|
||||||
"@pnp/sp": "^1.3.3",
|
"react": "16.13.1",
|
||||||
"@pnp/spfx-controls-react": "1.19.0",
|
"react-dom": "16.13.1"
|
||||||
"@pnp/spfx-property-controls": "1.19.0",
|
|
||||||
"@types/es6-promise": "0.0.33",
|
|
||||||
"@types/react": "16.8.8",
|
|
||||||
"@types/react-dom": "16.8.3",
|
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"classnames": "^2.2.6",
|
|
||||||
"office-ui-fabric-react": "6.214.0",
|
|
||||||
"react": "16.8.5",
|
|
||||||
"react-dom": "16.8.5"
|
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"@types/react": "16.8.8"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/rush-stack-compiler-2.9": "0.7.7",
|
"@microsoft/rush-stack-compiler-3.7": "0.2.3",
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.3.5",
|
"@microsoft/rush-stack-compiler-3.9": "0.4.47",
|
||||||
"@microsoft/sp-build-web": "1.10.0",
|
"@microsoft/sp-build-web": "1.13.0",
|
||||||
"@microsoft/sp-module-interfaces": "1.10.0",
|
"@microsoft/sp-module-interfaces": "1.13.0",
|
||||||
"@microsoft/sp-tslint-rules": "1.10.0",
|
"@microsoft/sp-tslint-rules": "1.13.0",
|
||||||
"@microsoft/sp-webpart-workbench": "1.10.0",
|
"@types/react": "16.9.51",
|
||||||
"@types/chai": "3.4.34",
|
"@types/react-dom": "16.9.8",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/webpack-env": "1.13.1",
|
||||||
"ajv": "~5.2.2",
|
"ajv": "~5.2.2",
|
||||||
"autoprefixer": "^9.8.4",
|
"autoprefixer": "^9.8.4",
|
||||||
"gulp": "~3.9.1",
|
"gulp": "4.0.2",
|
||||||
"react-html-parser": "^2.0.2"
|
"react-html-parser": "^2.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,6 +331,7 @@ const hasprocessIndicator = buckets.filter((b)=> b.showPercentageHeadline).lengt
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDragStart(event, taskId: string, bucket: string): void {
|
private onDragStart(event, taskId: string, bucket: string): void {
|
||||||
|
console.log('onDragStart');
|
||||||
const taskitem = this.props.tasks.filter(p => p.taskId === taskId);
|
const taskitem = this.props.tasks.filter(p => p.taskId === taskId);
|
||||||
if (taskitem.length === 1) {
|
if (taskitem.length === 1) {
|
||||||
event.dataTransfer.setData("text", taskId);
|
event.dataTransfer.setData("text", taskId);
|
||||||
|
@ -353,6 +354,7 @@ const hasprocessIndicator = buckets.filter((b)=> b.showPercentageHeadline).lengt
|
||||||
|
|
||||||
private onDragOver(event, targetbucket: string): void {
|
private onDragOver(event, targetbucket: string): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
console.log('onDragOver');
|
||||||
|
|
||||||
if (this.dragelement.bucket !== targetbucket) {
|
if (this.dragelement.bucket !== targetbucket) {
|
||||||
const index = findIndex(this.props.buckets, element => element.bucket == targetbucket);
|
const index = findIndex(this.props.buckets, element => element.bucket == targetbucket);
|
||||||
|
|
|
@ -67,10 +67,8 @@ export default class KanbanTaskManagedProp extends React.Component<IKanbanTaskMa
|
||||||
size={PersonaSize.size32}
|
size={PersonaSize.size32}
|
||||||
hidePersonaDetails={false}
|
hidePersonaDetails={false}
|
||||||
/>))
|
/>))
|
||||||
)
|
))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</span>);
|
</span>);
|
||||||
break;
|
break;
|
||||||
case KanbanTaskMamagedPropertyType.complex:
|
case KanbanTaskMamagedPropertyType.complex:
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { cloneDeep } from '@microsoft/sp-lodash-subset';
|
||||||
import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
|
import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
|
||||||
import { PropertyFieldOrder } from '@pnp/spfx-property-controls/lib/PropertyFieldOrder';
|
import { PropertyFieldOrder } from '@pnp/spfx-property-controls/lib/PropertyFieldOrder';
|
||||||
import * as strings from 'KanbanBoardWebPartStrings';
|
import * as strings from 'KanbanBoardWebPartStrings';
|
||||||
import "@pnp/polyfill-ie11";
|
|
||||||
import { sp } from '@pnp/sp';
|
import { sp } from '@pnp/sp';
|
||||||
|
|
||||||
import PropertyPaneBucketConfigComponent from './components/PropertyPaneBucketConfig';
|
import PropertyPaneBucketConfigComponent from './components/PropertyPaneBucketConfig';
|
||||||
|
@ -113,7 +112,7 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
|
||||||
onListsRetrieved: (lists) => {
|
onListsRetrieved: (lists) => {
|
||||||
//TODO Check from TS Definition it should be a string but i get a number
|
//TODO Check from TS Definition it should be a string but i get a number
|
||||||
// with Typesafe equal it fails
|
// with Typesafe equal it fails
|
||||||
if (Environment.type == EnvironmentType.Local || Environment.type == EnvironmentType.Test) {
|
if (Environment.type == EnvironmentType.Test) {
|
||||||
return lists;
|
return lists;
|
||||||
} else {
|
} else {
|
||||||
const alists = lists.filter((l: any) => {
|
const alists = lists.filter((l: any) => {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import { ISPKanbanService } from "./ISPKanbanService";
|
import { ISPKanbanService } from "./ISPKanbanService";
|
||||||
import "@pnp/polyfill-ie11";
|
|
||||||
import { sp } from '@pnp/sp';
|
|
||||||
import { IKanbanTask, KanbanTaskMamagedPropertyType } from "../../../kanban";
|
import { IKanbanTask, KanbanTaskMamagedPropertyType } from "../../../kanban";
|
||||||
import * as strings from 'KanbanBoardWebPartStrings';
|
import * as strings from 'KanbanBoardWebPartStrings';
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
import { ISPKanbanService } from "./ISPKanbanService";
|
import { ISPKanbanService } from "./ISPKanbanService";
|
||||||
import "@pnp/polyfill-ie11";
|
|
||||||
import { sp } from '@pnp/sp';
|
import { sp } from '@pnp/sp';
|
||||||
|
import '@pnp/sp/webs';
|
||||||
|
import '@pnp/sp/lists';
|
||||||
|
import '@pnp/sp/items';
|
||||||
|
import '@pnp/sp/fields';
|
||||||
import { IKanbanTask, KanbanTaskMamagedPropertyType } from "../../../kanban";
|
import { IKanbanTask, KanbanTaskMamagedPropertyType } from "../../../kanban";
|
||||||
import * as strings from 'KanbanBoardWebPartStrings';
|
import * as strings from 'KanbanBoardWebPartStrings';
|
||||||
|
import { IFieldInfo } from "@pnp/sp/fields";
|
||||||
|
|
||||||
|
interface IFieldChoiceInfo extends IFieldInfo {
|
||||||
|
Choices: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export default class SPKanbanService implements ISPKanbanService {
|
export default class SPKanbanService implements ISPKanbanService {
|
||||||
|
|
||||||
|
@ -50,7 +58,7 @@ export default class SPKanbanService implements ISPKanbanService {
|
||||||
}
|
}
|
||||||
public getBuckets(listId: string, ): Promise<string[]> {
|
public getBuckets(listId: string, ): Promise<string[]> {
|
||||||
return sp.web.lists.getById(listId).fields.getByInternalNameOrTitle("Status").get()
|
return sp.web.lists.getById(listId).fields.getByInternalNameOrTitle("Status").get()
|
||||||
.then(status => status.Choices.map((val, index) => {
|
.then((status: IFieldChoiceInfo) => status.Choices.map((val, index) => {
|
||||||
return val;
|
return val;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"extends": "node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.9/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
@ -19,20 +19,18 @@
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"es6-promise",
|
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es5",
|
"es5",
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts", "src/webparts/kanbanBoard/components/bucketOrder.tsx"
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": []
|
||||||
"node_modules",
|
|
||||||
"lib"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
"rules": {
|
"rules": {
|
||||||
"class-name": false,
|
"class-name": false,
|
||||||
"export-name": false,
|
"export-name": false,
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
"no-switch-case-fall-through": true,
|
"no-switch-case-fall-through": true,
|
||||||
"no-unnecessary-semicolons": true,
|
"no-unnecessary-semicolons": true,
|
||||||
"no-unused-expression": true,
|
"no-unused-expression": true,
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-with-statement": true,
|
"no-with-statement": true,
|
||||||
"semicolon": true,
|
"semicolon": true,
|
||||||
"trailing-comma": false,
|
"trailing-comma": false,
|
||||||
|
|
|
@ -12,6 +12,7 @@ lib
|
||||||
release
|
release
|
||||||
solution
|
solution
|
||||||
temp
|
temp
|
||||||
|
release
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
|
|
|
@ -56,7 +56,8 @@ Version|Date|Comments
|
||||||
1.0.0|November 20, 2020|Initial release
|
1.0.0|November 20, 2020|Initial release
|
||||||
1.0.1|February 18, 2021|Added support for metadata columns
|
1.0.1|February 18, 2021|Added support for metadata columns
|
||||||
1.0.2|February 21, 2021|Fixed `gulp build` issues
|
1.0.2|February 21, 2021|Fixed `gulp build` issues
|
||||||
1.0.3|October 31🦇, 2021|Upgraded to SPFx 1.13
|
1.0.3|October 25, 2021|Fixed bug support for metadata columns and Lookup fields
|
||||||
|
1.0.4|October 31🦇, 2021|Upgraded to SPFx 1.13
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,14 @@
|
||||||
{
|
{
|
||||||
"key": "SPFX-TEAMSPERSONALAPP",
|
"key": "SPFX-TEAMSPERSONALAPP",
|
||||||
"value": "true"
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "PNPCONTROLS",
|
||||||
|
"value": "PropertyFieldListPicker, PropertyFieldMessage, PropertyFieldSpinner"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "REACT-HOOKS",
|
||||||
|
"value": "true"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-list-items-menu-client-side-solution",
|
"name": "react-list-items-menu-client-side-solution",
|
||||||
"id": "8b4a758d-a968-4e7c-a949-b42e7dd5ad14",
|
"id": "8b4a758d-a968-4e7c-a949-b42e7dd5ad14",
|
||||||
"version": "1.0.2.0",
|
"version": "1.0.3.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
|
|
|
@ -24269,6 +24269,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "2.25.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
|
||||||
|
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w=="
|
||||||
|
},
|
||||||
"dateformat": {
|
"dateformat": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-list-items-menu",
|
"name": "react-list-items-menu",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
"@pnp/spfx-property-controls": "1.19.0",
|
"@pnp/spfx-property-controls": "1.19.0",
|
||||||
"@types/jquery": "^3.5.0",
|
"@types/jquery": "^3.5.0",
|
||||||
"@uifabric/file-type-icons": "^7.6.11",
|
"@uifabric/file-type-icons": "^7.6.11",
|
||||||
|
"date-fns": "^2.25.0",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"jsstore": "^3.10.3",
|
"jsstore": "^3.10.3",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
|
|
@ -158,3 +158,11 @@ export const convertTimeTo24h = (
|
||||||
resolve(hourInTimeFormat);
|
resolve(hourInTimeFormat);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Check if string is valid date */
|
||||||
|
export const checkIfValidDate = (str:string):boolean => {
|
||||||
|
// Regular expression to check if string is valid date
|
||||||
|
const regexExp = /(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})/gi;
|
||||||
|
|
||||||
|
return regexExp.test(str);
|
||||||
|
};
|
||||||
|
|
|
@ -69,7 +69,86 @@ export const ListItemsMenu: React.FunctionComponent<IListItemsMenuProps> = (
|
||||||
|
|
||||||
const stateRef = React.useRef(state); // Use to access state on eventListenners
|
const stateRef = React.useRef(state); // Use to access state on eventListenners
|
||||||
|
|
||||||
// On component did mount only if listId or Field Change
|
React.useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
if (!props.listId || !props.fieldName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let _navLinksGroups: INavLinkGroup[] = [];
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
isLoading: true,
|
||||||
|
navLinkGroups: _navLinksGroups,
|
||||||
|
};
|
||||||
|
setState(stateRef.current);
|
||||||
|
const _groupHeaders = await getGroupHeaders(props.listId, props.fieldName, props.listBaseTemplate);
|
||||||
|
const { fieldName } = props;
|
||||||
|
const _field: any = await getField(props.listId, props.fieldName);
|
||||||
|
|
||||||
|
for (const groupHeader of _groupHeaders) {
|
||||||
|
let _name: any;
|
||||||
|
switch (_field.fieldType) {
|
||||||
|
case "TaxonomyFieldType":
|
||||||
|
_name = groupHeader[fieldName]?.Label ?? "Unassigned";
|
||||||
|
break;
|
||||||
|
case "TaxonomyFieldTypeMulti":
|
||||||
|
_name = groupHeader[fieldName][0]?.Label ?? "Unassigned";
|
||||||
|
break;
|
||||||
|
case "User":
|
||||||
|
if (_name != "Unassigned") {
|
||||||
|
_name = groupHeader[fieldName][0]?.title;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Lookup":
|
||||||
|
_name =
|
||||||
|
groupHeader[props.fieldName] !== "" &&
|
||||||
|
groupHeader[props.fieldName] !== undefined &&
|
||||||
|
groupHeader[props.fieldName][0].lookupValue !== ""
|
||||||
|
? groupHeader[props.fieldName][0]?.lookupValue
|
||||||
|
: "Unassigned";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_name =
|
||||||
|
groupHeader[props.fieldName] !== "" && groupHeader[props.fieldName] !== undefined
|
||||||
|
? groupHeader[props.fieldName]
|
||||||
|
: "Unassigned";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_navLinksGroups.push({
|
||||||
|
name: _name,
|
||||||
|
groupData: _name,
|
||||||
|
collapseByDefault: true,
|
||||||
|
onHeaderClick: _onGroupHeaderClick,
|
||||||
|
links: [],
|
||||||
|
});
|
||||||
|
// Ensure the groups name are unique!
|
||||||
|
_navLinksGroups = uniqBy(_navLinksGroups, "name");
|
||||||
|
}
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
hasError: false,
|
||||||
|
errorMessage: "",
|
||||||
|
isLoading: false,
|
||||||
|
listName: _field.fieldScope,
|
||||||
|
navLinkGroups: _navLinksGroups,
|
||||||
|
};
|
||||||
|
|
||||||
|
setState(stateRef.current);
|
||||||
|
} catch (error) {
|
||||||
|
stateRef.current = {
|
||||||
|
...stateRef.current,
|
||||||
|
hasError: true,
|
||||||
|
errorMessage: error.message,
|
||||||
|
};
|
||||||
|
setState(stateRef.current);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, [props.listId, props.fieldName]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* // On component did mount only if listId or Field Change
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!props.listId || !props.fieldName) {
|
if (!props.listId || !props.fieldName) {
|
||||||
|
@ -142,7 +221,7 @@ export const ListItemsMenu: React.FunctionComponent<IListItemsMenuProps> = (
|
||||||
setState(stateRef.current);
|
setState(stateRef.current);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, [props.listId, props.fieldName]);
|
}, [props.listId, props.fieldName]); */
|
||||||
|
|
||||||
// On Header click get Items for the header
|
// On Header click get Items for the header
|
||||||
const _onGroupHeaderClick = async (
|
const _onGroupHeaderClick = async (
|
||||||
|
|
|
@ -9,7 +9,8 @@ import moment from "moment";
|
||||||
import { sp } from "@pnp/sp";
|
import { sp } from "@pnp/sp";
|
||||||
import { IFieldInfo } from "@pnp/sp/fields";
|
import { IFieldInfo } from "@pnp/sp/fields";
|
||||||
import { IListInfo } from "@pnp/sp/lists";
|
import { IListInfo } from "@pnp/sp/lists";
|
||||||
|
import { checkIfValidDate } from "../Utils/Utils";
|
||||||
|
import {format , parseISO} from 'date-fns';
|
||||||
export const useList = () => {
|
export const useList = () => {
|
||||||
// Run on useList hook
|
// Run on useList hook
|
||||||
(async () => {})();
|
(async () => {})();
|
||||||
|
@ -71,12 +72,14 @@ export const useList = () => {
|
||||||
): Promise<any[]> => {
|
): Promise<any[]> => {
|
||||||
const _field: any = await getField(listId, groupByField);
|
const _field: any = await getField(listId, groupByField);
|
||||||
|
|
||||||
|
if (checkIfValidDate(groupFieldValue)) {
|
||||||
|
groupFieldValue = format(new Date(groupFieldValue), "yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
|
||||||
switch (_field.fieldType) {
|
switch (_field.fieldType) {
|
||||||
case "DateTime":
|
case "DateTime":
|
||||||
groupFieldValue =
|
groupFieldValue =
|
||||||
groupFieldValue != "Unassigned"
|
groupFieldValue != "Unassigned" ? format(parseISO(groupFieldValue), "yyyy-MM-dd") : "Unassigned";
|
||||||
? moment(groupFieldValue).format("YYYY-MM-DD")
|
|
||||||
: "Unassigned";
|
|
||||||
break;
|
break;
|
||||||
case "AllDayEvent":
|
case "AllDayEvent":
|
||||||
groupFieldValue = groupFieldValue === "No" ? "0" : "1";
|
groupFieldValue = groupFieldValue === "No" ? "0" : "1";
|
||||||
|
@ -84,7 +87,6 @@ export const useList = () => {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _viewXml = `<View Scope='Recursive'>
|
let _viewXml = `<View Scope='Recursive'>
|
||||||
<Query>
|
<Query>
|
||||||
<OrderBy>
|
<OrderBy>
|
||||||
|
|
|
@ -47,9 +47,17 @@ Current Data Functions:
|
||||||
|
|
||||||
Built with SharePoint Framework GA, Office Graph, React and Chart.JS
|
Built with SharePoint Framework GA, Office Graph, React and Chart.JS
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
|
||||||
|
|
||||||
![version](https://img.shields.io/badge/version-1.10.0-green.svg)
|
## Compatibility
|
||||||
|
|
||||||
|
![SPFx 1.10](https://img.shields.io/badge/SPFx-1.10.0-green.svg)
|
||||||
|
![Node.js LSTS 8 | LTS 10](https://img.shields.io/badge/Node.js-LTS%208%20%7C%20LTS%20v10-green.svg)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Compatible](https://img.shields.io/badge/Local%20Workbench-Compatible-green.svg)
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -60,24 +68,20 @@ Built with SharePoint Framework GA, Office Graph, React and Chart.JS
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-modern-charts|Jeremy Coleman (MCP, PC Professional, Inc.)
|
react-modern-charts|[Jeremy Coleman](https://github.com/jcoleman-pcprofessional) (MCP, PC Professional, Inc.)
|
||||||
react-modern-charts|Peter Paul Kirschner ([@petkir_at](https://twitter.com/petkir_at))
|
react-modern-charts|[Peter Paul Kirschner](https://github.com/petkir) ([@petkir_at](https://twitter.com/petkir_at))
|
||||||
|
react-modern-charts|[Abderahman Moujahid](https://github.com/Abderahman88)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
|
1.0.0.4|October 19, 2021| Fix values of managed metadata fields
|
||||||
1.0.0.3|July 30, 2020| Support for Managed Metadata Field(Single) as Label
|
1.0.0.3|July 30, 2020| Support for Managed Metadata Field(Single) as Label
|
||||||
1.0.0.2|February 09, 2020| Upgrade to SPFx 1.10.0
|
1.0.0.2|February 09, 2020| Upgrade to SPFx 1.10.0
|
||||||
1.0.0.1|April 25, 2018|Update to SPFx 1.4.1
|
1.0.0.1|April 25, 2018|Update to SPFx 1.4.1
|
||||||
1.0.0.0|February 11, 2017|Initial release
|
1.0.0.0|February 11, 2017|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.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- SharePoint Online tenant with Office Graph content-enabled
|
- SharePoint Online tenant with Office Graph content-enabled
|
||||||
|
@ -99,4 +103,18 @@ Sample Web Parts in this solution illustrate the following concepts on top of th
|
||||||
- passing Web Part properties to React components
|
- passing Web Part properties to React components
|
||||||
- building dynamic web part properties
|
- building dynamic web part properties
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-modern-charts&authors=@jcoleman-pcprofessional%20@petkir%20@Abderahman88&title=react-modern-charts%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-modern-charts&authors=@jcoleman-pcprofessional%20@petkir%20@Abderahman88&title=react-modern-charts%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-modern-charts&authors=@jcoleman-pcprofessional%20@petkir%20@Abderahman88&title=react-modern-charts%20-%20).
|
||||||
|
|
||||||
![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-modern-charts)
|
![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-modern-charts)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This web part uses the Chart.js library to visualize SharePoint list data."
|
"This web part uses the Chart.js library to visualize SharePoint list data."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2020-07-30",
|
"creationDateTime": "2020-07-30",
|
||||||
"updateDateTime": "2020-07-30",
|
"updateDateTime": "2021-10-19",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "modern-charts-client-side-solution",
|
"name": "modern-charts-client-side-solution",
|
||||||
"id": "f8a78a9a-a93e-4843-89e5-7b871d9b9fa2",
|
"id": "f8a78a9a-a93e-4843-89e5-7b871d9b9fa2",
|
||||||
"version": "1.0.0.3",
|
"version": "1.0.0.4",
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
"includeClientSideAssets": true
|
"includeClientSideAssets": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -208,8 +208,11 @@ export default class ModernChartsWebPart extends BaseClientSideWebPart<IModernCh
|
||||||
private getUnique(data: Array<Object>, config: ChartConfiguration): Object {
|
private getUnique(data: Array<Object>, config: ChartConfiguration): Object {
|
||||||
const chLabels: Object = { unique: [], labels: [] };
|
const chLabels: Object = { unique: [], labels: [] };
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
if (chLabels['unique'].indexOf(item[config.unique]) == -1 && item[config.unique] != null && item[config.unique] != "") {
|
var uniqueItem = item[config.unique];
|
||||||
chLabels['unique'].push(item[config.unique]);
|
var isTaxonomyField = item[config.unique].hasOwnProperty('TermGuid');
|
||||||
|
|
||||||
|
if ((isTaxonomyField ? !chLabels['unique'].some(field => field['TermGuid'] === uniqueItem['TermGuid']) : chLabels['unique'].indexOf(uniqueItem) == -1) && uniqueItem != null && uniqueItem != "") {
|
||||||
|
chLabels['unique'].push(uniqueItem);
|
||||||
//if term use VAlue
|
//if term use VAlue
|
||||||
chLabels['labels'].push(this.getLabel(item, config.col1));
|
chLabels['labels'].push(this.getLabel(item, config.col1));
|
||||||
}
|
}
|
||||||
|
@ -234,14 +237,13 @@ export default class ModernChartsWebPart extends BaseClientSideWebPart<IModernCh
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValues(data: Array<Object>, unique: Array<string>, config: ChartConfiguration): Array<Array<any>> {
|
private getValues(data: Array<Object>, unique: Array<string>, config: ChartConfiguration): Array<Array<any>> {
|
||||||
|
|
||||||
const values: Object = {};
|
const values: Object = {};
|
||||||
const vals: Array<Array<any>> = [[]];
|
const vals: Array<Array<any>> = [[]];
|
||||||
unique.forEach((col, i) => {
|
unique.forEach((col, i) => {
|
||||||
values[col] = [];
|
values[col] = [];
|
||||||
vals[i] = [];
|
vals[i] = [];
|
||||||
data.forEach((item, _i) => {
|
data.forEach((item, _i) => {
|
||||||
if (item[config.unique] == col) {
|
if (item[config.unique].hasOwnProperty('TermGuid') ? item[config.unique]["TermGuid"] == col["TermGuid"] : item[config.unique] == col) {
|
||||||
vals[i].push(item[config.col2]);
|
vals[i].push(item[config.col2]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,72 +1,96 @@
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import styles from './ModernCharts.module.scss';
|
import styles from "./ModernCharts.module.scss";
|
||||||
import { IModernChartsProps } from '../IModernChartsWebPartProps';
|
import { IModernChartsProps } from "../IModernChartsWebPartProps";
|
||||||
import { MChart } from '../IModernChartsWebPartProps';
|
import { MChart } from "../IModernChartsWebPartProps";
|
||||||
import 'chart.js';
|
import "chart.js";
|
||||||
import { Doughnut } from 'react-chartjs-2';
|
import { Doughnut } from "react-chartjs-2";
|
||||||
import { Line } from 'react-chartjs-2';
|
import { Line } from "react-chartjs-2";
|
||||||
import { Pie } from 'react-chartjs-2';
|
import { Pie } from "react-chartjs-2";
|
||||||
import { Bar } from 'react-chartjs-2';
|
import { Bar } from "react-chartjs-2";
|
||||||
import { HorizontalBar } from 'react-chartjs-2';
|
import { HorizontalBar } from "react-chartjs-2";
|
||||||
import { Radar } from 'react-chartjs-2';
|
import { Radar } from "react-chartjs-2";
|
||||||
import { Polar } from 'react-chartjs-2';
|
import { Polar } from "react-chartjs-2";
|
||||||
import ChartOptions from '../ChartOptions';
|
import ChartOptions from "../ChartOptions";
|
||||||
import {
|
import {
|
||||||
DocumentCard,
|
DocumentCard,
|
||||||
DocumentCardTitle,
|
DocumentCardTitle,
|
||||||
DocumentCardLocation,
|
DocumentCardLocation,
|
||||||
DocumentCardPreview,
|
DocumentCardPreview,
|
||||||
IDocumentCardPreviewProps
|
IDocumentCardPreviewProps,
|
||||||
} from 'office-ui-fabric-react/lib/DocumentCard';
|
} from "office-ui-fabric-react/lib/DocumentCard";
|
||||||
|
|
||||||
export default class ModernCharts extends React.Component<IModernChartsProps, {}> {
|
|
||||||
|
|
||||||
|
export default class ModernCharts extends React.Component<
|
||||||
|
IModernChartsProps,
|
||||||
|
{}
|
||||||
|
> {
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
const charts: JSX.Element[] = this.props.charts.map((chart: MChart, i: number) => {
|
const charts: JSX.Element[] = this.props.charts.map(
|
||||||
|
(chart: MChart, i: number) => {
|
||||||
return (
|
return (
|
||||||
<DocumentCard onClickHref='#' className={styles.docContainer + ' ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg' + chart.config.size} key={chart.key}>
|
<DocumentCard
|
||||||
|
onClickHref="#"
|
||||||
|
className={
|
||||||
|
styles.docContainer +
|
||||||
|
" ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg" +
|
||||||
|
chart.config.size
|
||||||
|
}
|
||||||
|
key={chart.key}
|
||||||
|
>
|
||||||
<div className={styles.chartCard}>
|
<div className={styles.chartCard}>
|
||||||
{this.chart(ChartOptions.Data(chart), ChartOptions.Options(), chart.config.type)}
|
{this.chart(
|
||||||
|
ChartOptions.Data(chart),
|
||||||
|
ChartOptions.Options(),
|
||||||
|
chart.config.type
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<DocumentCardLocation location={chart.config.description} />
|
<DocumentCardLocation location={chart.config.description} />
|
||||||
<DocumentCardTitle title={chart.config.title} />
|
<DocumentCardTitle title={chart.config.title} />
|
||||||
</DocumentCard>
|
</DocumentCard>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.chartjs + ' ms-Grid'}>
|
|
||||||
<div className={'ms-Grid-row'}>
|
|
||||||
{charts}
|
|
||||||
</div>
|
|
||||||
<div style={{ clear: 'both' }} />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.chartjs + " ms-Grid"}>
|
||||||
|
<div className={"ms-Grid-row"}>{charts}</div>
|
||||||
|
<div style={{ clear: "both" }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public chart(data: Object, options: Object, type: string) {
|
public chart(data: Object, options: Object, type: string) {
|
||||||
var tChart: any;
|
var tChart: any;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'doughnut':
|
case "doughnut":
|
||||||
tChart = <Doughnut data={data} options={options} />;
|
tChart = <Doughnut data={data} options={options} />;
|
||||||
return tChart;
|
return tChart;
|
||||||
case 'line':
|
case "line":
|
||||||
debugger;
|
return (
|
||||||
return <Line data={data} options={options} legend={{ display: false }} />;
|
<Line data={data} options={options} legend={{ display: false }} />
|
||||||
case 'pie':
|
);
|
||||||
|
case "pie":
|
||||||
tChart = <Pie data={data} options={options} />;
|
tChart = <Pie data={data} options={options} />;
|
||||||
return tChart;
|
return tChart;
|
||||||
case 'bar':
|
case "bar":
|
||||||
tChart = <Bar data={data} options={options} legend={{ display: false }} />;
|
tChart = (
|
||||||
|
<Bar data={data} options={options} legend={{ display: false }} />
|
||||||
|
);
|
||||||
return tChart;
|
return tChart;
|
||||||
case 'horizontalbar':
|
case "horizontalbar":
|
||||||
tChart = <HorizontalBar data={data} options={options} legend={{ display: false }} />;
|
tChart = (
|
||||||
|
<HorizontalBar
|
||||||
|
data={data}
|
||||||
|
options={options}
|
||||||
|
legend={{ display: false }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
return tChart;
|
return tChart;
|
||||||
case 'radar':
|
case "radar":
|
||||||
tChart = <Radar data={data} options={options} legend={{ display: false }} />;
|
tChart = (
|
||||||
|
<Radar data={data} options={options} legend={{ display: false }} />
|
||||||
|
);
|
||||||
return tChart;
|
return tChart;
|
||||||
case 'polar':
|
case "polar":
|
||||||
tChart = <Polar data={data} options={options} />;
|
tChart = <Polar data={data} options={options} />;
|
||||||
return tChart;
|
return tChart;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-my-task",
|
"name": "react-my-task",
|
||||||
"version": "0.0.1",
|
"version": "1.0.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -60,6 +60,8 @@ This extension illustrates the following concepts:
|
||||||
|
|
||||||
We do not support samples, but we do use GitHub to track issues and constantly want to improve these samples.
|
We do not support samples, but we do use GitHub to track issues and constantly want to improve these samples.
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/labels/react-organization-chart)
|
||||||
|
|
||||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-organisation-chart&authors=@joaojmendes&title=react-organisation-chart%20-%20).
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-organisation-chart&authors=@joaojmendes&title=react-organisation-chart%20-%20).
|
||||||
|
|
||||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-organisation-chart&authors=@joaojmendes&title=react-organisation-chart%20-%20).
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-organisation-chart&authors=@joaojmendes&title=react-organisation-chart%20-%20).
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
# 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
|
|
|
@ -12,6 +12,7 @@ lib
|
||||||
solution
|
solution
|
||||||
temp
|
temp
|
||||||
*.sppkg
|
*.sppkg
|
||||||
|
release
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
"framework": "react",
|
"framework": "react",
|
||||||
"isCreatingSolution": true,
|
"isCreatingSolution": true,
|
||||||
"version": "1.9.1",
|
"version": "1.12.1",
|
||||||
"libraryName": "navigator",
|
"libraryName": "navigator",
|
||||||
"libraryId": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
"libraryId": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
|
|
@ -8,22 +8,29 @@ When added to a Vertical Section it can be used as a Contents table for the page
|
||||||
|
|
||||||
![Page Navigator](./assets/PageNavigator.gif)
|
![Page Navigator](./assets/PageNavigator.gif)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Compatibility
|
||||||
|
|
||||||
![version](https://img.shields.io/badge/version-1.9.1-green.svg)
|
![SPFx 1.12.1](https://img.shields.io/badge/SPFx-1.12.1-green.svg)
|
||||||
|
![Node.js LTS v14 | LTS v12 | LTS v10](https://img.shields.io/badge/Node.js-LTS%20v14%20%7C%20LTS%20v12%20%7C%20LTS%20v10-green.svg)
|
||||||
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to the page structure")
|
||||||
|
![Hosted Workbench Partially](https://img.shields.io/badge/Hosted%20Workbench-Partially-yellow.svg "The solution needs to run on a hosted page to work as intended")
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|September 5, 2019|Initial release
|
1.0|September 5, 2019|Initial release
|
||||||
|
1.1|October 20, 2021|SPFx Upgraded to 1.12.1 and code refactored
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- git clone the repo
|
- `git clone` the repo
|
||||||
- npm i
|
- `npm i`
|
||||||
- gulp bundle --ship
|
- `gulp bundle --ship`
|
||||||
- gulp package-solution --ship
|
- `gulp package-solution --ship`
|
||||||
- Add the app package to Site Collection App Catalog and Install the App
|
- Add the app package to Site Collection App Catalog and Install the App
|
||||||
- Add the web part to a page in the Site Collection
|
- Add the web part to a page in the Site Collection
|
||||||
|
|
||||||
|
@ -31,10 +38,20 @@ Version|Date|Comments
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-page-navigator|Aakash Bhardwaj
|
react-page-navigator|[Aakash Bhardwaj](https://github.com/aakashbhardwaj619)
|
||||||
|
|
||||||
## 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.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-page-navigator&authors=@aakashbhardwaj619&title=react-page-navigator%20-%20).
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-page-navigator" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-page-navigator" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This web part fetches all the automatically added Header anchor tags in a SharePoint page and displays them in a Navigation component."
|
"This web part fetches all the automatically added Header anchor tags in a SharePoint page and displays them in a Navigation component."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2019-09-05",
|
"creationDateTime": "2019-09-05",
|
||||||
"updateDateTime": "2019-09-05",
|
"updateDateTime": "2021-10-20",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.9.1"
|
"value": "1.12.1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||||
"deployCdnPath": "temp/deploy"
|
"deployCdnPath": "./release/assets/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||||
"workingDir": "./temp/deploy/",
|
"workingDir": "./release/assets/",
|
||||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||||
"container": "navigator",
|
"container": "navigator",
|
||||||
"accessKey": "<!-- ACCESS KEY -->"
|
"accessKey": "<!-- ACCESS KEY -->"
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||||
"solution": {
|
"solution": {
|
||||||
|
"developer": {
|
||||||
|
"name": "",
|
||||||
|
"privacyUrl": "",
|
||||||
|
"termsOfUseUrl": "",
|
||||||
|
"websiteUrl": "",
|
||||||
|
"mpnId": ""
|
||||||
|
},
|
||||||
"name": "react-page-navigator",
|
"name": "react-page-navigator",
|
||||||
"id": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
"id": "065ee566-e00d-4058-bbfd-356c8d9a8005",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,5 +25,12 @@ gulp.task('dev', gulpSequence('clean', 'bundle', 'package-solution'));
|
||||||
* Custom Framework Specific gulp tasks
|
* Custom Framework Specific gulp tasks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var getTasks = build.rig.getTasks;
|
||||||
|
build.rig.getTasks = function () {
|
||||||
|
var result = getTasks.call(build.rig);
|
||||||
|
|
||||||
|
result.set('serve', result.get('serve-deprecated'));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
build.initialize(gulp);
|
build.initialize(gulp);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,9 +3,6 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp bundle",
|
"build": "gulp bundle",
|
||||||
"clean": "gulp clean",
|
"clean": "gulp clean",
|
||||||
|
@ -15,36 +12,35 @@
|
||||||
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
|
"test:watch": "./node_modules/.bin/jest --config ./config/jest.config.json --watchAll"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "1.9.1",
|
"@microsoft/sp-core-library": "1.12.1",
|
||||||
"@microsoft/sp-lodash-subset": "1.9.1",
|
"@microsoft/sp-lodash-subset": "1.12.1",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.9.1",
|
"@microsoft/sp-office-ui-fabric-core": "1.12.1",
|
||||||
"@microsoft/sp-webpart-base": "1.9.1",
|
"@microsoft/sp-property-pane": "1.12.1",
|
||||||
|
"@microsoft/sp-webpart-base": "1.12.1",
|
||||||
"@pnp/pnpjs": "^1.3.5",
|
"@pnp/pnpjs": "^1.3.5",
|
||||||
"@pnp/spfx-controls-react": "1.14.0",
|
"@pnp/spfx-controls-react": "1.14.0",
|
||||||
"@pnp/spfx-property-controls": "1.16.0",
|
"@pnp/spfx-property-controls": "1.16.0",
|
||||||
"@types/es6-promise": "0.0.33",
|
"office-ui-fabric-react": "7.156.0",
|
||||||
"@types/react": "16.8.8",
|
"react": "16.9.0",
|
||||||
"@types/react-dom": "16.8.3",
|
"react-dom": "16.9.0"
|
||||||
"@types/webpack-env": "1.13.1",
|
|
||||||
"office-ui-fabric-react": "^6.182.0",
|
|
||||||
"react": "16.8.5",
|
|
||||||
"react-dom": "16.8.5"
|
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react": "16.8.8"
|
"@types/react": "16.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/rush-stack-compiler-3.3": "0.1.7",
|
"@microsoft/rush-stack-compiler-3.3": "0.1.7",
|
||||||
"@microsoft/sp-build-web": "1.9.1",
|
"@microsoft/rush-stack-compiler-3.7": "0.2.3",
|
||||||
"@microsoft/sp-module-interfaces": "1.9.1",
|
"@microsoft/sp-build-web": "1.12.1",
|
||||||
"@microsoft/sp-tslint-rules": "1.9.1",
|
"@microsoft/sp-module-interfaces": "1.12.1",
|
||||||
"@microsoft/sp-webpart-workbench": "1.9.1",
|
"@microsoft/sp-tslint-rules": "1.12.1",
|
||||||
"@types/chai": "3.4.34",
|
"@microsoft/sp-webpart-workbench": "1.12.1",
|
||||||
"@types/mocha": "2.2.38",
|
"@types/es6-promise": "0.0.33",
|
||||||
"@types/react": "^16.7.22",
|
"@types/react": "16.9.36",
|
||||||
|
"@types/react-dom": "16.9.8",
|
||||||
|
"@types/webpack-env": "1.13.1",
|
||||||
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
"@voitanos/jest-preset-spfx-react16": "^1.1.0",
|
||||||
"ajv": "~5.2.2",
|
"ajv": "~5.2.2",
|
||||||
"gulp": "~3.9.1",
|
"gulp": "4.0.2",
|
||||||
"gulp-sequence": "1.0.0",
|
"gulp-sequence": "1.0.0",
|
||||||
"jest": "^23.6.0"
|
"jest": "^23.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,49 @@ import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||||
import { SPHttpClient } from '@microsoft/sp-http';
|
import { SPHttpClient } from '@microsoft/sp-http';
|
||||||
|
|
||||||
export class SPService {
|
export class SPService {
|
||||||
|
/* Array to store all unique anchor URLs */
|
||||||
|
private static allUrls: string[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique Anchor URL for a heading
|
||||||
|
* @param headingValue The text value of the heading
|
||||||
|
* @returns anchorUrl
|
||||||
|
*/
|
||||||
|
private static GetAnchorUrl(headingValue: string): string {
|
||||||
|
let urlExists = true;
|
||||||
|
// .replace(/'|?|\|/| |&/g, "-") replaces any blanks and special characters (list is for sure not complete) with "-"
|
||||||
|
// .replace(/--+/g, "-") replaces any additional - with only one -; e.g. --- get replaced with -, -- get replaced with - etc.
|
||||||
|
let anchorUrl = `#${headingValue
|
||||||
|
.replace(/\'|\?|\\|\/| |\&/g, "-")
|
||||||
|
.replace(/--+/g, "-")}`.toLowerCase();
|
||||||
|
let urlSuffix = 1;
|
||||||
|
while (urlExists === true) {
|
||||||
|
urlExists = (this.allUrls.indexOf(anchorUrl) === -1) ? false : true;
|
||||||
|
if (urlExists) {
|
||||||
|
anchorUrl = anchorUrl + `-${urlSuffix}`;
|
||||||
|
urlSuffix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anchorUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Anchor Links for Nav element
|
||||||
|
* @param context Web part context
|
||||||
|
* @returns anchorLinks
|
||||||
|
*/
|
||||||
public static async GetAnchorLinks(context: WebPartContext) {
|
public static async GetAnchorLinks(context: WebPartContext) {
|
||||||
let anchorLinks: INavLink[] = [];
|
const anchorLinks: INavLink[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* Page ID on which the web part is added */
|
/* Page ID on which the web part is added */
|
||||||
let pageId = context.pageContext.listItem.id;
|
const pageId = context.pageContext.listItem.id;
|
||||||
|
|
||||||
/* Get the canvasContent1 data for the page which consists of all the HTML */
|
/* Get the canvasContent1 data for the page which consists of all the HTML */
|
||||||
let data = await context.spHttpClient.get(`${context.pageContext.web.absoluteUrl}/_api/sitepages/pages(${pageId})`, SPHttpClient.configurations.v1);
|
const data = await context.spHttpClient.get(`${context.pageContext.web.absoluteUrl}/_api/sitepages/pages(${pageId})`, SPHttpClient.configurations.v1);
|
||||||
let jsonData = await data.json();
|
const jsonData = await data.json();
|
||||||
let canvasContent1 = jsonData.CanvasContent1;
|
const canvasContent1 = jsonData.CanvasContent1;
|
||||||
let canvasContent1JSON: any[] = JSON.parse(canvasContent1);
|
const canvasContent1JSON: any[] = JSON.parse(canvasContent1);
|
||||||
|
|
||||||
/* Initialize variables to be used for sorting and adding the Navigation links */
|
/* Initialize variables to be used for sorting and adding the Navigation links */
|
||||||
let headingIndex = 0;
|
let headingIndex = 0;
|
||||||
|
@ -22,9 +53,6 @@ export class SPService {
|
||||||
let headingOrder = 0;
|
let headingOrder = 0;
|
||||||
let prevHeadingOrder = 0;
|
let prevHeadingOrder = 0;
|
||||||
|
|
||||||
/* Array to store all unique anchor URLs */
|
|
||||||
let allUrls: string[] = [];
|
|
||||||
|
|
||||||
/* Traverse through all the Text web parts in the page */
|
/* Traverse through all the Text web parts in the page */
|
||||||
canvasContent1JSON.map((webPart) => {
|
canvasContent1JSON.map((webPart) => {
|
||||||
if (webPart.innerHTML) {
|
if (webPart.innerHTML) {
|
||||||
|
@ -34,28 +62,14 @@ export class SPService {
|
||||||
/* The Header Text value */
|
/* The Header Text value */
|
||||||
// .replace(/<.+?>/gi, "") replaces in the headingValue any html tags like <strong> </strong>
|
// .replace(/<.+?>/gi, "") replaces in the headingValue any html tags like <strong> </strong>
|
||||||
// .replace(/&.+;/gi, "") replaces in the headingValue any &****; tags like
|
// .replace(/&.+;/gi, "") replaces in the headingValue any &****; tags like
|
||||||
let headingValue = HTMLString.substring(HTMLString.search(/<h[1-4]>/g) + 4, HTMLString.search(/<\/h[1-4]>/g))
|
const headingValue = HTMLString.substring(HTMLString.search(/<h[1-4]>/g) + 4, HTMLString.search(/<\/h[1-4]>/g))
|
||||||
.replace(/<.+?>/gi, "")
|
.replace(/<.+?>/gi, "")
|
||||||
.replace(/\&.+\;/gi, "");
|
.replace(/\&.+\;/gi, "");
|
||||||
|
|
||||||
headingOrder = parseInt(HTMLString.charAt(HTMLString.search(/<h[1-4]>/g) + 2));
|
headingOrder = parseInt(HTMLString.charAt(HTMLString.search(/<h[1-4]>/g) + 2));
|
||||||
|
|
||||||
/* Check if same anchorUrl already exists */
|
const anchorUrl = this.GetAnchorUrl(headingValue);
|
||||||
let urlExists = true;
|
this.allUrls.push(anchorUrl);
|
||||||
// .replace(/'|?|\|/| |&/g, "-") replaces any blanks and special characters (list is for sure not complete) with "-"
|
|
||||||
// .replace(/--+/g, "-") replaces any additional - with only one -; e.g. --- get replaced with -, -- get replaced with - etc.
|
|
||||||
let anchorUrl = `#${headingValue
|
|
||||||
.replace(/\'|\?|\\|\/| |\&/g, "-")
|
|
||||||
.replace(/--+/g, "-")}`.toLowerCase();
|
|
||||||
let urlSuffix = 1;
|
|
||||||
while (urlExists === true) {
|
|
||||||
urlExists = (allUrls.indexOf(anchorUrl) === -1) ? false : true;
|
|
||||||
if (urlExists) {
|
|
||||||
anchorUrl = anchorUrl + `-${urlSuffix}`;
|
|
||||||
urlSuffix++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allUrls.push(anchorUrl);
|
|
||||||
|
|
||||||
/* Add links to Nav element */
|
/* Add links to Nav element */
|
||||||
if (anchorLinks.length === 0) {
|
if (anchorLinks.length === 0) {
|
||||||
|
@ -63,33 +77,42 @@ export class SPService {
|
||||||
} else {
|
} else {
|
||||||
if (headingOrder <= prevHeadingOrder) {
|
if (headingOrder <= prevHeadingOrder) {
|
||||||
/* Adding or Promoting links */
|
/* Adding or Promoting links */
|
||||||
if (headingOrder === 2) {
|
switch (headingOrder) {
|
||||||
|
case 2:
|
||||||
anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
anchorLinks.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
headingIndex++;
|
headingIndex++;
|
||||||
subHeadingIndex = -1;
|
subHeadingIndex = -1;
|
||||||
} else {
|
break;
|
||||||
if (headingOrder === 4) {
|
case 4:
|
||||||
|
if (subHeadingIndex > -1) {
|
||||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
} else if (headingOrder === 3) {
|
} else {
|
||||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
subHeadingIndex++;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
|
subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Making sub links */
|
/* Making sub links */
|
||||||
if (headingOrder === 3) {
|
if (headingOrder === 3) {
|
||||||
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
subHeadingIndex++;
|
subHeadingIndex = anchorLinks[headingIndex].links.length - 1;
|
||||||
} else {
|
} else {
|
||||||
|
if (subHeadingIndex > -1) {
|
||||||
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
anchorLinks[headingIndex].links[subHeadingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
|
} else {
|
||||||
|
anchorLinks[headingIndex].links.push({ name: headingValue, key: anchorUrl, url: anchorUrl, links: [], isExpanded: true });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevHeadingOrder = headingOrder;
|
prevHeadingOrder = headingOrder;
|
||||||
|
|
||||||
/* Replace the added header links from the string so they don't get processed again */
|
/* Replace the added header links from the string so they don't get processed again */
|
||||||
HTMLString = HTMLString.replace(`<h${headingOrder}>`, '');
|
HTMLString = HTMLString.replace(`<h${headingOrder}>`, '').replace(`</h${headingOrder}>`, '');
|
||||||
HTMLString = HTMLString.replace(`</h${headingOrder}>`, '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -97,7 +120,7 @@ export class SPService {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(anchorLinks);
|
console.log('anchorLinks', anchorLinks);
|
||||||
return anchorLinks;
|
return anchorLinks;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +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 'PageNavigatorWebPartStrings';
|
import * as strings from 'PageNavigatorWebPartStrings';
|
||||||
import PageNavigator from './components/PageNavigator';
|
import PageNavigator from './components/PageNavigator';
|
||||||
import { IPageNavigatorProps } from './components/IPageNavigatorProps';
|
import { IPageNavigatorProps } from './components/IPageNavigatorProps';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
|
"extends": "./node_modules/@microsoft/rush-stack-compiler-3.7/includes/tsconfig-web.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
@ -19,20 +19,18 @@
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"es6-promise",
|
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es5",
|
"es5",
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection",
|
||||||
|
"es2015.promise"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": []
|
||||||
"node_modules",
|
|
||||||
"lib"
|
|
||||||
]
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
"extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
"rules": {
|
"rules": {
|
||||||
"class-name": false,
|
"class-name": false,
|
||||||
"export-name": false,
|
"export-name": false,
|
||||||
|
|
|
@ -16,7 +16,8 @@ This SPFx Outlook Add-In lets users save any email attachments to a OneDrive fol
|
||||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-yellow.svg "Designed to work in Outlook, but will display sample attachments while in workbench")
|
![Hosted Workbench Partially](https://img.shields.io/badge/Hosted%20Workbench-Partially-yellow.svg "Designed to work in Outlook, but will display sample attachments while in workbench")
|
||||||
|
![Outlook Compatible](https://img.shields.io/badge/Outlook-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
|
@ -165,7 +165,7 @@ In order to make it available to absolutely all sites you need apply the _Deploy
|
||||||
|
|
||||||
Solution|Author(s)
|
Solution|Author(s)
|
||||||
--------|---------
|
--------|---------
|
||||||
react-script-editor | Mikael Svenson ([@mikaelsvenson](http://www.twitter.com/mikaelsvenson), [techmikael.com](techmikael.com))
|
react-script-editor | [Mikael Svenson](https://github.com/wobba) ([@mikaelsvenson](http://www.twitter.com/mikaelsvenson), [techmikael.com](techmikael.com))
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
@ -190,11 +190,6 @@ Version|Date|Comments
|
||||||
1.0.0.16|April 1st, 2020|Improved how script tags are handled and cleaned up on smart page navigation.
|
1.0.0.16|April 1st, 2020|Improved how script tags are handled and cleaned up on smart page navigation.
|
||||||
1.0.17.0|January 29th, 2021|Changed versioning to 3 parts. Updated npm packages, restructured documentation, minor change to webpack analyzer setup.
|
1.0.17.0|January 29th, 2021|Changed versioning to 3 parts. Updated npm packages, restructured documentation, minor change to webpack analyzer setup.
|
||||||
|
|
||||||
## 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
|
## Minimal Path to Awesome
|
||||||
### Local testing
|
### Local testing
|
||||||
|
|
||||||
|
@ -204,10 +199,10 @@ Version|Date|Comments
|
||||||
- `gulp serve`
|
- `gulp serve`
|
||||||
|
|
||||||
### Deploy
|
### Deploy
|
||||||
* gulp clean
|
* `gulp clean`
|
||||||
* gulp bundle --ship
|
* `gulp bundle --ship`
|
||||||
* gulp package-solution --ship
|
* `gulp package-solution --ship`
|
||||||
* Upload .sppkg file from sharepoint\solution to your tenant App Catalog
|
* Upload `.sppkg` file from `sharepoint\solution` to your tenant App Catalog
|
||||||
* E.g.: https://<tenant>.sharepoint.com/sites/AppCatalog/AppCatalog
|
* E.g.: https://<tenant>.sharepoint.com/sites/AppCatalog/AppCatalog
|
||||||
* Add the web part to a site collection, and test it on a page
|
* Add the web part to a site collection, and test it on a page
|
||||||
## Features
|
## Features
|
||||||
|
@ -217,4 +212,24 @@ This web part illustrates the following concepts on top of the SharePoint Framew
|
||||||
- Office UI Fabric
|
- Office UI Fabric
|
||||||
- React
|
- React
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
|
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/labels/react-script-editor) to see if anybody else is having the same issues.
|
||||||
|
|
||||||
|
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=label%3Areact-script-editor) and see what the community is saying.
|
||||||
|
|
||||||
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-script-editor&authors=@wobba&title=react-script-editor%20-%20).
|
||||||
|
|
||||||
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-script-editor&authors=@wobba&title=react-script-editor%20-%20).
|
||||||
|
|
||||||
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-script-editor&authors=@wobba&title=react-script-editor%20-%20).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-script-editor" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-script-editor" />
|
||||||
|
|
|
@ -13,9 +13,11 @@ This is a rebuild of the awesome project created by @hugoabernier [https://githu
|
||||||
|
|
||||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
||||||
![Node.js LTS 10.x](https://img.shields.io/badge/Node.js-LTS%2010.x-green.svg)
|
![Node.js LTS 10.x](https://img.shields.io/badge/Node.js-LTS%2010.x-green.svg)
|
||||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
|
![Local Workbench Compatible](https://img.shields.io/badge/Local%20Workbench-Compatible-green.svg)
|
||||||
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||||
|
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
@ -37,14 +39,15 @@ react-tiles-v2 | [Omar El-Anis](https://github.com/omarelanis) @ SP Bytes www.sp
|
||||||
Version|Date|Comments
|
Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|July 14, 2021|Initial release
|
1.0|July 14, 2021|Initial release
|
||||||
|
1.1|October 14, 2021|Added sorting, static tile width and unique tile colour - [fthorild](https://github.com/fthorild)
|
||||||
|
|
||||||
## Minimal Path to Awesome
|
## Minimal Path to Awesome
|
||||||
|
|
||||||
- Clone this repository
|
- Clone this repository
|
||||||
- Ensure that you are at the solution folder
|
- Ensure that you are at the solution folder
|
||||||
- in the command-line run:
|
- in the command-line run:
|
||||||
- **npm install**
|
- `npm install`
|
||||||
- **gulp serve**
|
- `gulp serve`
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
@ -75,10 +78,10 @@ This extension illustrates the following concepts:
|
||||||
|
|
||||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||||
|
|
||||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-tiles-v2&authors=@omarelanis&title=react-tiles-v2%20-%20).
|
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=react-tiles-v2&authors=fthorild%20@fthorild&title=react-tiles-v2%20-%20).
|
||||||
|
|
||||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-tiles-v2&authors=@omarelanis&title=react-tiles-v2%20-%20).
|
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=react-tiles-v2&authors=fthorild%20@fthorild&title=react-tiles-v2%20-%20).
|
||||||
|
|
||||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-tiles-v2&authors=@omarelanis&title=react-tiles-v2%20-%20).
|
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=react-tiles-v2&authors=fthorild%20@fthorild&title=react-tiles-v2%20-%20).
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-tiles-v2" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-tiles-v2" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"This solution creates a customisable Tiles Web part, it uses a stored collection from the PnP `PropertyFieldCollectionData` control and allows the user to choose the colour scheme (theme or custom) and to set the size of the tiles. By default the tiles use a fluid flex layout to use the available screen area."
|
"This solution creates a customisable Tiles Web part, it uses a stored collection from the PnP `PropertyFieldCollectionData` control and allows the user to choose the colour scheme (theme or custom) and to set the size of the tiles. By default the tiles use a fluid flex layout to use the available screen area."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2021-07-14",
|
"creationDateTime": "2021-07-14",
|
||||||
"updateDateTime": "2021-07-14",
|
"updateDateTime": "2021-10-14",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint",
|
"SharePoint",
|
||||||
"Office"
|
"Office"
|
||||||
|
@ -22,6 +22,10 @@
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.11"
|
"value": "1.11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "PNPCONTROLS",
|
||||||
|
"value": "IconPicker, WebPartTitle, Placeholder, PropertyFieldCollectionData"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
@ -37,6 +41,12 @@
|
||||||
"gitHubAccount": "omarelanis",
|
"gitHubAccount": "omarelanis",
|
||||||
"pictureUrl": "https://github.com/omarelanis.png",
|
"pictureUrl": "https://github.com/omarelanis.png",
|
||||||
"name": "Omar El-Anis"
|
"name": "Omar El-Anis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gitHubAccount": "fthorild",
|
||||||
|
"name": "Fredrik Thorild",
|
||||||
|
"company": "Sogeti Sweden",
|
||||||
|
"pictureUrl": "https://github.com/fthorild.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "Tiles V2 Webpart - Modern",
|
"name": "Tiles V2 Webpart - Modern",
|
||||||
"id": "d56958d6-9eaf-4500-934b-b421c22a7d1f",
|
"id": "d56958d6-9eaf-4500-934b-b421c22a7d1f",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tiles",
|
"name": "tiles",
|
||||||
"version": "0.0.1",
|
"version": "1.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tiles",
|
"name": "tiles",
|
||||||
"version": "0.0.1",
|
"version": "1.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -4,20 +4,23 @@ import * as strings from 'TilesWebPartStrings';
|
||||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||||
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
|
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||||
import { IPropertyPaneConfiguration } from "@microsoft/sp-property-pane";
|
import { IPropertyPaneConfiguration } from "@microsoft/sp-property-pane";
|
||||||
import { PropertyPaneToggle,PropertyPaneSlider } from '@microsoft/sp-property-pane';
|
import { PropertyPaneToggle, PropertyPaneSlider, PropertyPaneDropdown } from '@microsoft/sp-property-pane';
|
||||||
import { Tiles, ITilesProps, ITileInfo, LinkTarget } from './components';
|
import { Tiles, ITilesProps, ITileInfo, LinkTarget } from './components';
|
||||||
import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker';
|
import { IconPicker } from '@pnp/spfx-controls-react/lib/IconPicker';
|
||||||
import { initializeIcons } from 'office-ui-fabric-react/lib';
|
import { ColorPicker, initializeIcons } from 'office-ui-fabric-react/lib';
|
||||||
|
import { SimpleColorPicker } from './components/colorpicker/SimpleColorPicker';
|
||||||
|
|
||||||
const ThemeColorsFromWindow: any = (window as any).__themeState__.theme;
|
const ThemeColorsFromWindow: any = (window as any).__themeState__.theme;
|
||||||
|
|
||||||
export interface ITilesWebPartProps {
|
export interface ITilesWebPartProps {
|
||||||
collectionData: ITileInfo[];
|
collectionData: ITileInfo[];
|
||||||
tileHeight: number;
|
tileHeight: number;
|
||||||
|
tileWidth: number;
|
||||||
tileColour: string;
|
tileColour: string;
|
||||||
tileFont: string;
|
tileFont: string;
|
||||||
title: string;
|
title: string;
|
||||||
customColour: boolean;
|
staticWidth: boolean;
|
||||||
|
colourMode: string;
|
||||||
themeVariant: IReadonlyTheme | undefined;
|
themeVariant: IReadonlyTheme | undefined;
|
||||||
ThemeColorsFromWindow: IReadonlyTheme | undefined;
|
ThemeColorsFromWindow: IReadonlyTheme | undefined;
|
||||||
}
|
}
|
||||||
|
@ -64,13 +67,15 @@ export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartPro
|
||||||
{
|
{
|
||||||
title: this.properties.title,
|
title: this.properties.title,
|
||||||
tileHeight: this.properties.tileHeight,
|
tileHeight: this.properties.tileHeight,
|
||||||
|
tileWidth: this.properties.tileWidth,
|
||||||
tileColour: this.properties.tileColour,
|
tileColour: this.properties.tileColour,
|
||||||
tileFont: this.properties.tileFont,
|
tileFont: this.properties.tileFont,
|
||||||
customColour: this.properties.customColour,
|
staticWidth: this.properties.staticWidth,
|
||||||
collectionData: this.properties.collectionData,
|
collectionData: this.properties.collectionData,
|
||||||
displayMode: this.displayMode,
|
displayMode: this.displayMode,
|
||||||
themeVariant: this._themeVariant,
|
themeVariant: this._themeVariant,
|
||||||
ThemeColorsFromWindow: ThemeColorsFromWindow,
|
ThemeColorsFromWindow: ThemeColorsFromWindow,
|
||||||
|
colourMode: this.properties.colourMode,
|
||||||
fUpdateProperty: (value: string) => {
|
fUpdateProperty: (value: string) => {
|
||||||
this.properties.title = value;
|
this.properties.title = value;
|
||||||
},
|
},
|
||||||
|
@ -107,7 +112,9 @@ export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartPro
|
||||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
let tileColourplaceholder: any = [];
|
let tileColourplaceholder: any = [];
|
||||||
let tileFontplaceholder: any = [];
|
let tileFontplaceholder: any = [];
|
||||||
if (this.properties.customColour) {
|
let tileStaticWidthplaceholder: any = [];
|
||||||
|
|
||||||
|
if (this.properties.colourMode === '2') {
|
||||||
tileColourplaceholder = this.propertyFieldColorPicker('tileColour', {
|
tileColourplaceholder = this.propertyFieldColorPicker('tileColour', {
|
||||||
key: "tileColour",
|
key: "tileColour",
|
||||||
label: strings.tileColour,
|
label: strings.tileColour,
|
||||||
|
@ -132,7 +139,20 @@ export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartPro
|
||||||
style: this.propertyFieldColorPickerStyle.Full,
|
style: this.propertyFieldColorPickerStyle.Full,
|
||||||
iconName: 'Precipitation'
|
iconName: 'Precipitation'
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.properties.staticWidth) {
|
||||||
|
tileStaticWidthplaceholder = PropertyPaneSlider('tileWidth', {
|
||||||
|
label: strings.widthStaticSet,
|
||||||
|
max: 1000,
|
||||||
|
min: 10,
|
||||||
|
step: 1,
|
||||||
|
showValue: true,
|
||||||
|
value: this.properties.tileHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
|
@ -169,15 +189,53 @@ export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartPro
|
||||||
type: this.customCollectionFieldType.string,
|
type: this.customCollectionFieldType.string,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "sortOrder",
|
||||||
|
title: strings.sortOrder,
|
||||||
|
type: this.customCollectionFieldType.number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "background",
|
||||||
|
title: strings.colorSetUniqueBg,
|
||||||
|
type: this.customCollectionFieldType.custom,
|
||||||
|
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
|
||||||
|
return (
|
||||||
|
React.createElement(SimpleColorPicker, {
|
||||||
|
key: itemId,
|
||||||
|
onChange: (colour: string) => {
|
||||||
|
onUpdate(field.id, colour);
|
||||||
|
return Event;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "foreground",
|
||||||
|
title: strings.colorSetUniqueFg,
|
||||||
|
type: this.customCollectionFieldType.custom,
|
||||||
|
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
|
||||||
|
return (
|
||||||
|
React.createElement(SimpleColorPicker, {
|
||||||
|
key: itemId,
|
||||||
|
onChange: (colour: string) => {
|
||||||
|
onUpdate(field.id, colour);
|
||||||
|
return Event;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "icon",
|
id: "icon",
|
||||||
title: "Select Icon",
|
title: strings.iconField,
|
||||||
type: this.customCollectionFieldType.custom,
|
type: this.customCollectionFieldType.custom,
|
||||||
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
|
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
|
||||||
return (
|
return (
|
||||||
React.createElement(IconPicker, {
|
React.createElement(IconPicker, {
|
||||||
key: itemId,
|
key: itemId,
|
||||||
buttonLabel:"Select File",
|
buttonLabel: strings.iconSelectFile,
|
||||||
onChange: (iconName: string) => {
|
onChange: (iconName: string) => {
|
||||||
onUpdate(field.id, iconName);
|
onUpdate(field.id, iconName);
|
||||||
return Event;
|
return Event;
|
||||||
|
@ -207,24 +265,35 @@ export default class TilesWebPart extends BaseClientSideWebPart<ITilesWebPartPro
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
]},
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
groupName: "Tile Settings",
|
groupName: "Tile Settings",
|
||||||
groupFields: [
|
groupFields: [
|
||||||
PropertyPaneSlider('tileHeight', {
|
PropertyPaneSlider('tileHeight', {
|
||||||
label: 'Tile Height',
|
label: strings.tilesHeight,
|
||||||
max: 300,
|
max: 300,
|
||||||
min: 120,
|
min: 120,
|
||||||
step: 1,
|
step: 1,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
value: this.properties.tileHeight
|
value: this.properties.tileHeight
|
||||||
}),
|
}),
|
||||||
PropertyPaneToggle('customColour', {
|
PropertyPaneToggle('staticWidth', {
|
||||||
key: 'customColourID',
|
key: 'staticWidthID',
|
||||||
label: 'Theme or Custom colours',
|
label: strings.widthAutomaticOrStatic,
|
||||||
onText: 'Custom Colours',
|
onText: strings.widthStatic,
|
||||||
offText: 'Theme Colours',
|
offText: strings.widthAutomatic,
|
||||||
checked: this.properties.customColour
|
checked: this.properties.staticWidth
|
||||||
|
}),
|
||||||
|
tileStaticWidthplaceholder,
|
||||||
|
PropertyPaneDropdown('colourMode', {
|
||||||
|
label: strings.colourMode,
|
||||||
|
options: [
|
||||||
|
{ key: '1', text: strings.colourModeTheme },
|
||||||
|
{ key: '2', text: strings.colourModeUniform },
|
||||||
|
{ key: '3', text: strings.colourModeUnique }
|
||||||
|
],
|
||||||
|
selectedKey: '1',
|
||||||
}),
|
}),
|
||||||
tileColourplaceholder,
|
tileColourplaceholder,
|
||||||
tileFontplaceholder
|
tileFontplaceholder
|
||||||
|
|
|
@ -4,6 +4,9 @@ export interface ITileInfo {
|
||||||
url: string;
|
url: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
target: LinkTarget;
|
target: LinkTarget;
|
||||||
|
sortOrder: string;
|
||||||
|
foreground: string;
|
||||||
|
background: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LinkTarget {
|
export enum LinkTarget {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as strings from 'TilesWebPartStrings';
|
import * as strings from 'TilesWebPartStrings';
|
||||||
import styles from './Tiles.module.scss';
|
import styles from './Tiles.module.scss';
|
||||||
import { ITilesProps } from '.';
|
import { ITileInfo, ITilesProps } from '.';
|
||||||
import { Tile } from './tile';
|
import { Tile } from './tile';
|
||||||
import { WebPartTitle } from '@pnp/spfx-controls-react/lib/WebPartTitle';
|
import { WebPartTitle } from '@pnp/spfx-controls-react/lib/WebPartTitle';
|
||||||
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
||||||
|
@ -15,23 +15,32 @@ export class Tiles extends React.Component<ITilesProps, {}> {
|
||||||
*/
|
*/
|
||||||
public render(): React.ReactElement<ITilesProps> {
|
public render(): React.ReactElement<ITilesProps> {
|
||||||
const CustomStyles = createstyles(this.props.themeVariant);
|
const CustomStyles = createstyles(this.props.themeVariant);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css(styles.tiles, CustomStyles.root)}>
|
<div className={css(styles.tiles, CustomStyles.root)
|
||||||
|
}>
|
||||||
<WebPartTitle displayMode={this.props.displayMode}
|
<WebPartTitle displayMode={this.props.displayMode}
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
updateProperty={this.props.fUpdateProperty} />
|
updateProperty={this.props.fUpdateProperty} />
|
||||||
|
|
||||||
{
|
{
|
||||||
this.props.collectionData && this.props.collectionData.length > 0 ? (
|
this.props.collectionData && this.props.collectionData.length > 0 ? (
|
||||||
|
|
||||||
<div className={styles.tilesList}>
|
<div className={styles.tilesList}>
|
||||||
{
|
{
|
||||||
this.props.collectionData.map((tile, idx) =>
|
this.props.collectionData
|
||||||
|
.sort((a: ITileInfo, b: ITileInfo) =>
|
||||||
|
parseInt(a.sortOrder) > parseInt(b.sortOrder) ?
|
||||||
|
1 : ((parseInt(b.sortOrder) > parseInt(a.sortOrder) ? -1 : 0)))
|
||||||
|
.map((tile, idx) =>
|
||||||
<Tile key={idx}
|
<Tile key={idx}
|
||||||
item={tile}
|
item={tile}
|
||||||
tileHeight={this.props.tileHeight}
|
tileHeight={this.props.tileHeight}
|
||||||
|
tileWidth={this.props.tileWidth}
|
||||||
tileColour={this.props.tileColour}
|
tileColour={this.props.tileColour}
|
||||||
tileFont={this.props.tileFont}
|
tileFont={this.props.tileFont}
|
||||||
customColour={this.props.customColour}
|
staticWidth={this.props.staticWidth}
|
||||||
|
colourMode={this.props.colourMode}
|
||||||
themeVariant={this.props.themeVariant}
|
themeVariant={this.props.themeVariant}
|
||||||
ThemeColorsFromWindow={this.props.ThemeColorsFromWindow} />)
|
ThemeColorsFromWindow={this.props.ThemeColorsFromWindow} />)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface ISimpleColorPickerProps {
|
||||||
|
onChange(iconName: any): void;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface ISimpleColorPickerState {
|
||||||
|
val: string;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { ISimpleColorPickerProps } from './ISimpleColorPickerProps';
|
||||||
|
import { ISimpleColorPickerState } from './ISimpleColorPickerState';
|
||||||
|
|
||||||
|
export class SimpleColorPicker extends React.Component<ISimpleColorPickerProps, ISimpleColorPickerState> {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { val: '#efefef' };
|
||||||
|
}
|
||||||
|
private handleChange = event => {
|
||||||
|
const value = event.target.value;
|
||||||
|
(async () => {
|
||||||
|
await this.setState({ val: value });
|
||||||
|
this.props.onChange(this.state.val);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
public render(): React.ReactElement<ISimpleColorPickerProps> {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
onChange={this.handleChange}
|
||||||
|
type='color'
|
||||||
|
value={this.state.val}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue