New Sample Added, Modern Calendar (#140)
* Initial Commit * Update README.md * Updated README
This commit is contained in:
parent
b6fd85de83
commit
6020d00821
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 jcoleman-pcprofessional
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,56 @@
|
|||
# Modern Calendar
|
||||
|
||||
## Summary
|
||||
This is a modern webpart built on the GA version of the [SharePoint Framework](https://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview). The ready to deploy SharePoint Add-in package is available under the sharepoint/solution folder.
|
||||
|
||||
![SS1](https://cloud.githubusercontent.com/assets/13068139/23584809/14c4333e-0121-11e7-9bf1-3117651222d3.png)
|
||||
![SS2](https://cloud.githubusercontent.com/assets/13068139/23584808/14c3ec26-0121-11e7-8be8-65fbcca32b62.png)
|
||||
![SS3](https://cloud.githubusercontent.com/assets/13068139/23584807/14b88f34-0121-11e7-8c91-56ecff9343e1.png)
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/version-GA-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
* [SharePoint Framework](https://blogs.office.com/2017/02/23/sharepoint-framework-reaches-general-availability-build-and-deploy-engaging-web-parts-today/)
|
||||
* [Office 365 tenant](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment)
|
||||
|
||||
> Update accordingly as needed.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
> Any special pre-requisites?
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
folder name | Author details
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.1|September 2, 2025|Update comment
|
||||
1.0|August 29, 2025|Initial release
|
||||
|
||||
## Disclaimer
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
---
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository
|
||||
- in the command line run:
|
||||
- `npm install`
|
||||
- `gulp serve`
|
||||
|
||||
> Include any additional steps as needed.
|
||||
|
||||
## Features
|
||||
Renders a calendar from any list available on the selected site. Site, List, Start, End, Event Title,Event Details and Calendar Theme are user-definable in the web part properties.
|
||||
|
||||
![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-modern-calendar)
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/js-modern-calendar“ />
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"entries": [
|
||||
{
|
||||
"entry": "./lib/webparts/modernCalendar/ModernCalendarWebPart.js",
|
||||
"manifest": "./src/webparts/modernCalendar/ModernCalendarWebPart.manifest.json",
|
||||
"outputPath": "./dist/modern-calendar.bundle.js"
|
||||
}
|
||||
],
|
||||
"externals": {
|
||||
},
|
||||
"localizedResources": {
|
||||
"modernCalendarStrings": "webparts/modernCalendar/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "document-card-web-part",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"solution": {
|
||||
"name": "spFX Modern Calendar",
|
||||
"id": "3d593a2f-73f1-486f-9dae-555c6f6b584d",
|
||||
"version": "1.0.0.1"
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/modern-calendar.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"port": 4321,
|
||||
"initialPage": "https://localhost:5432/workbench",
|
||||
"https": true,
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
// Display errors as warnings
|
||||
"displayAsWarning": true,
|
||||
// The TSLint task may have been configured with several custom lint rules
|
||||
// before this config file is read (for example lint rules from the tslint-microsoft-contrib
|
||||
// project). If true, this flag will deactivate any of these rules.
|
||||
"removeExistingRules": true,
|
||||
// When true, the TSLint task is configured with some default TSLint "rules.":
|
||||
"useDefaultConfigAsBase": false,
|
||||
// Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
|
||||
// which are active, other than the list of rules below.
|
||||
"lintConfig": {
|
||||
// Opt-in to Lint rules which help to eliminate bugs in JavaScript
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"export-name": false,
|
||||
"forin": false,
|
||||
"label-position": false,
|
||||
"member-access": true,
|
||||
"no-arg": false,
|
||||
"no-console": false,
|
||||
"no-construct": false,
|
||||
"no-duplicate-case": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-eval": false,
|
||||
"no-function-expression": true,
|
||||
"no-internal-module": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-unnecessary-semicolons": true,
|
||||
"no-unused-expression": true,
|
||||
"no-unused-imports": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"valid-typeof": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false,
|
||||
"prefer-const": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cdnBasePath": "https://publiccdn.sharepointonline.com/pcpro365.sharepoint.com/163800463de5f9285ad4f6f9cc0a97985b96b057e062d4733849cc0fc90eeffbd6d72bb8/calendar/"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.initialize(gulp);
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "modern-calendar",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-client-base": "~1.0.0",
|
||||
"@microsoft/sp-core-library": "~1.0.0",
|
||||
"@microsoft/sp-webpart-base": "~1.0.0",
|
||||
"@types/fullcalendar": "^2.7.38",
|
||||
"@types/moment": "^2.13.0",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
||||
"fullcalendar": "^3.2.0",
|
||||
"sweetalert2": "^6.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.0.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.0.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.0.0",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
.EmptyCalendar {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
max-width: 715px;
|
||||
margin: 5px auto 5px auto;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: #0078d7;
|
||||
border-color: #0078d7;
|
||||
color: #ffffff;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
import {
|
||||
IPropertyPaneDropdownOption
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
import styles from './CalendarTemplate.module.scss';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
|
||||
export interface ISPLists {
|
||||
value: ISPList[];
|
||||
}
|
||||
|
||||
export interface ISPList {
|
||||
Title: string;
|
||||
Id: string;
|
||||
}
|
||||
export default class CalendarTemplate {
|
||||
public static templateHtml: string = `
|
||||
<div class='spfxcalendar'></div>
|
||||
`;
|
||||
|
||||
public static emptyHtml(title: string): string {
|
||||
return `<div class="${styles.EmptyCalendar}">
|
||||
<div class="${styles.container}">
|
||||
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
|
||||
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
|
||||
<span class="ms-font-xl ms-fontColor-white">${title}</span>
|
||||
<p class="ms-font-l ms-fontColor-white">Edit this web part to continue</p>
|
||||
<a href="https://aka.ms/spfx" class="${styles.button}">
|
||||
<span class="${styles.label}">View More Modern Web Parts</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public static themeBase: string = `https://publiccdn.sharepointonline.com/pcpro365.sharepoint.com/163800463de5f9285ad4f6f9cc0a97985b96b057e062d4733849cc0fc90eeffbd6d72bb8/calendar/themes/`;
|
||||
|
||||
public static themeNames: Array<string> = [
|
||||
'default',
|
||||
'black-tie',
|
||||
'blitzer',
|
||||
'cupertino',
|
||||
'dark-hive',
|
||||
'dot-luv',
|
||||
'eggplant',
|
||||
'excite-bike',
|
||||
'flick',
|
||||
'hot-sneaks',
|
||||
'humanity',
|
||||
'le-frog',
|
||||
'mint-choc',
|
||||
'overcast',
|
||||
'pcpro',
|
||||
'pepper-grinder',
|
||||
'redmond',
|
||||
'smoothness',
|
||||
'south-street',
|
||||
'start',
|
||||
'sunny',
|
||||
'swanky-purse',
|
||||
'trontastic',
|
||||
'ui-darkness',
|
||||
'ui-lightness',
|
||||
'vader'
|
||||
]
|
||||
|
||||
public static theme(): IPropertyPaneDropdownOption[] {
|
||||
var themes: IPropertyPaneDropdownOption[] = [];
|
||||
CalendarTemplate.themeNames.forEach(function(name,index) {
|
||||
themes.push({key: CalendarTemplate.themeBase + name + '/jquery-ui.min.css', text: name.toLocaleUpperCase()})
|
||||
});
|
||||
return themes;
|
||||
}
|
||||
|
||||
public static themes: IPropertyPaneDropdownOption[] = [
|
||||
{ key: CalendarTemplate.themeBase + 'jquery-ui.theme.min.css', text: 'Default' },
|
||||
{ key: CalendarTemplate.themeBase + 'ui-lightness/jquery-ui.min.css', text: 'Light' },
|
||||
{ key: '//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/redmond/jquery-ui.min.css', text: 'Redmond' },
|
||||
{ key: '//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/overcast/jquery-ui.min.css', text: 'Overcast' }
|
||||
];
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
export interface IModernCalendarWebPartProps {
|
||||
description: string;
|
||||
site: string;
|
||||
siteOther: string;
|
||||
other: boolean;
|
||||
listTitle: string;
|
||||
theme: string;
|
||||
start: string;
|
||||
end: string;
|
||||
title: string;
|
||||
detail: string;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
.helloWorld {
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 0px auto;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
max-width: 715px;
|
||||
margin: 5px auto 5px auto;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: #0078d7;
|
||||
border-color: #0078d7;
|
||||
color: #ffffff;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[aria-label='hide-col'] {
|
||||
display:none;
|
||||
}
|
||||
|
||||
#spPropertyPaneContainer input[aria-label='hide-col'] {
|
||||
display:none;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
||||
|
||||
"id": "c2a397d3-8c8f-47ab-b731-897178313c15",
|
||||
"alias": "ModernCalendarWebPart",
|
||||
"componentType": "WebPart",
|
||||
"version": "0.0.1",
|
||||
"manifestVersion": 2,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "c2a397d3-8c8f-47ab-b731-897178313c15",
|
||||
"group": { "default": "Modern Web Parts" },
|
||||
"title": { "default": "ModernCalendar" },
|
||||
"description": { "default": "SFPx Modern Calendar" },
|
||||
"officeFabricIconFontName": "Calendar",
|
||||
"properties": {
|
||||
"description": "SPFx Modern Calendar",
|
||||
"other": false
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,376 @@
|
|||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
IPropertyPaneDropdownOption,
|
||||
IPropertyPaneTextFieldProps,
|
||||
IWebPartContext,
|
||||
PropertyPaneTextField,
|
||||
PropertyPaneDropdown,
|
||||
IPropertyPaneDropdownProps
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
import styles from './ModernCalendar.module.scss';
|
||||
import * as strings from 'modernCalendarStrings';
|
||||
import { IModernCalendarWebPartProps } from './IModernCalendarWebPartProps';
|
||||
import CalendarTemplate from './CalendarTemplate';
|
||||
import * as jQuery from 'jquery';
|
||||
import 'fullcalendar';
|
||||
import * as moment from 'moment';
|
||||
import * as swal2 from 'sweetalert2';
|
||||
import { SPComponentLoader } from '@microsoft/sp-loader';
|
||||
import {
|
||||
SPHttpClient
|
||||
} from '@microsoft/sp-http';
|
||||
import {
|
||||
Environment,
|
||||
EnvironmentType
|
||||
} from '@microsoft/sp-core-library';
|
||||
|
||||
export interface ISPLists {
|
||||
value: ISPList[];
|
||||
}
|
||||
|
||||
export interface ISPList {
|
||||
Title: string;
|
||||
Id: string;
|
||||
}
|
||||
|
||||
export interface EventObjects {
|
||||
value: FC.EventObject[];
|
||||
}
|
||||
|
||||
export default class ModernCalendarWebPart extends BaseClientSideWebPart<IModernCalendarWebPartProps> {
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
//Modify with your a CDN or local path
|
||||
SPComponentLoader.loadCss('//publiccdn.sharepointonline.com/pcpro365.sharepoint.com/163800463de5f9285ad4f6f9cc0a97985b96b057e062d4733849cc0fc90eeffbd6d72bb8/calendar/sweetalert2.min.css');
|
||||
SPComponentLoader.loadCss('//publiccdn.sharepointonline.com/pcpro365.sharepoint.com/163800463de5f9285ad4f6f9cc0a97985b96b057e062d4733849cc0fc90eeffbd6d72bb8/calendar/fullcalendar.min.css');
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
|
||||
if (this.properties.theme != null){
|
||||
SPComponentLoader.loadCss(this.properties.theme);
|
||||
}
|
||||
|
||||
if (!this.properties.other){
|
||||
jQuery('input[aria-label=hide-col]').parent().hide();
|
||||
}
|
||||
//Check required properties before rendering list
|
||||
if (this.properties.listTitle == null || this.properties.start == null || this.properties.end == null || this.properties.title == null || this.properties.detail == null) {
|
||||
this.domElement.innerHTML = CalendarTemplate.emptyHtml(this.properties.description);
|
||||
} else {
|
||||
this.domElement.innerHTML = CalendarTemplate.templateHtml;
|
||||
this._renderListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected onPropertyPaneConfigurationStart(): void {
|
||||
//Set a default theme
|
||||
|
||||
if (this.properties.theme == null){
|
||||
this.properties.theme = CalendarTemplate.theme()[0].key.toString();
|
||||
}
|
||||
if (this.properties.site){
|
||||
this.listDisabled = false;
|
||||
}
|
||||
if (this.properties.listTitle && (!this.properties.start || !this.properties.end || !this.properties.title || !this.properties.detail)){
|
||||
//this._getColumnsAsync();
|
||||
}
|
||||
|
||||
if (!this.properties.other){
|
||||
jQuery('input[aria-label=hide-col]').parent().hide();
|
||||
}
|
||||
|
||||
if (this.properties.site && this.properties.listTitle && this.properties.start && this.properties.start && this.properties.end && this.properties.title && this.properties.detail){
|
||||
this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'Configuration');
|
||||
this._getSiteRootWeb()
|
||||
.then((response0) => {
|
||||
this._getSites(response0['Url'])
|
||||
.then((response) => {
|
||||
var sites: IPropertyPaneDropdownOption[] = [];
|
||||
sites.push({key:this.context.pageContext.web.absoluteUrl, text:'This Site'});
|
||||
sites.push({key:'other', text:'Other Site (Specify Url)'});
|
||||
for (var _key in response.value) {
|
||||
if (this.context.pageContext.web.absoluteUrl != response.value[_key]['Url']){
|
||||
sites.push({key: response.value[_key]['Url'], text: response.value[_key]['Title']});
|
||||
}
|
||||
}
|
||||
this._siteOptions = sites;
|
||||
if (this.properties.site){
|
||||
this._getListTitles(this.properties.site)
|
||||
.then((response2) => {
|
||||
this._dropdownOptions = response2.value.map((list: ISPList) => {
|
||||
return {
|
||||
key: list.Title,
|
||||
text: list.Title
|
||||
};
|
||||
});
|
||||
this._getListColumns(this.properties.listTitle,this.properties.site)
|
||||
.then((response3) => {
|
||||
var col: IPropertyPaneDropdownOption[] = [];
|
||||
for (var _key in response3.value) {
|
||||
col.push({key: response3.value[_key]['InternalName'], text: response3.value[_key]['Title']});
|
||||
}
|
||||
this._columnOptions = col;
|
||||
this.colsDisabled = false;
|
||||
this.listDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
this.render();
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this._getSitesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
|
||||
if (newValue == 'other' ){
|
||||
this.properties.other = true;
|
||||
this.properties.listTitle = null;
|
||||
jQuery('input[aria-label=hide-col]').parent().show();
|
||||
} else if (oldValue === 'other' && newValue != 'other') {
|
||||
this.properties.other = false;
|
||||
this.properties.siteOther = null;
|
||||
this.properties.listTitle = null;
|
||||
jQuery('input[aria-label=hide-col]').parent().hide();
|
||||
}
|
||||
this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'Configuration');
|
||||
if ((propertyPath === 'site' || propertyPath === 'siteOther') && newValue) {
|
||||
this.colsDisabled = true;
|
||||
this.listDisabled = true;
|
||||
var siteUrl = newValue;
|
||||
if (this.properties.other) { siteUrl = this.properties.siteOther; } else { jQuery('input[aria-label=hide-col]').parent().hide(); }
|
||||
if ((this.properties.other && this.properties.siteOther.length > 25) || !this.properties.other){
|
||||
this._getListTitles(siteUrl)
|
||||
.then((response) => {
|
||||
this._dropdownOptions = response.value.map((list: ISPList) => {
|
||||
return {
|
||||
key: list.Title,
|
||||
text: list.Title
|
||||
};
|
||||
});
|
||||
this.listDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
} else if (propertyPath === 'listTitle' && newValue) {
|
||||
var siteUrl = newValue;
|
||||
if (this.properties.other) { siteUrl = this.properties.siteOther; }
|
||||
this._getListColumns(newValue,siteUrl)
|
||||
.then((response) => {
|
||||
var col: IPropertyPaneDropdownOption[] = [];
|
||||
for (var _key in response.value) {
|
||||
col.push({key: response.value[_key]['InternalName'], text: response.value[_key]['Title']});
|
||||
}
|
||||
this._columnOptions = col;
|
||||
this.colsDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
this.render();
|
||||
});
|
||||
} else {
|
||||
//Handle other fields here
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
private colsDisabled: boolean = true;
|
||||
private listDisabled: boolean = true;
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
var otherSiteAria = 'hide-col';
|
||||
if (this.properties.other) { otherSiteAria = ''; }
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('description', {
|
||||
label: strings.DescriptionFieldLabel
|
||||
}),
|
||||
PropertyPaneDropdown('theme', {
|
||||
label: 'Theme',
|
||||
options: CalendarTemplate.theme()
|
||||
}),
|
||||
PropertyPaneDropdown('site', {
|
||||
label: 'Site',
|
||||
options: this._siteOptions
|
||||
}),
|
||||
PropertyPaneTextField('siteOther', {
|
||||
label: 'Other Site Url (i.e. https://contoso.sharepoint.com/path)',
|
||||
ariaLabel: otherSiteAria
|
||||
}),
|
||||
PropertyPaneDropdown('listTitle', {
|
||||
label: 'List Title',
|
||||
options: this._dropdownOptions,
|
||||
disabled: this.listDisabled
|
||||
}),
|
||||
PropertyPaneDropdown('start', {
|
||||
label: 'Start Date Field',
|
||||
options: this._columnOptions,
|
||||
disabled: this.colsDisabled
|
||||
}),
|
||||
PropertyPaneDropdown('end', {
|
||||
label: 'End Date Field',
|
||||
options: this._columnOptions,
|
||||
disabled: this.colsDisabled
|
||||
}),
|
||||
PropertyPaneDropdown('title', {
|
||||
label: 'Event Title Field',
|
||||
options: this._columnOptions,
|
||||
disabled: this.colsDisabled
|
||||
}),
|
||||
PropertyPaneDropdown('detail', {
|
||||
label: 'Event Details',
|
||||
options: this._columnOptions,
|
||||
disabled: this.colsDisabled
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private _siteOptions: IPropertyPaneDropdownOption[] = [];
|
||||
private _dropdownOptions: IPropertyPaneDropdownOption[] = [];
|
||||
private _columnOptions: IPropertyPaneDropdownOption[] = [];
|
||||
|
||||
public onInit<T>(): Promise<T> {
|
||||
//this._siteOptions.push({key:this.context.pageContext.web.absoluteUrl, text:'This Site'});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private _getSiteRootWeb(): Promise<ISPLists> {
|
||||
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + `/_api/Site/RootWeb?$select=Title,Url`, SPHttpClient.configurations.v1)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
private _getSites(rootWebUrl: string): Promise<ISPLists> {
|
||||
return this.context.spHttpClient.get(rootWebUrl + `/_api/web/webs?$select=Title,Url`, SPHttpClient.configurations.v1)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
private _getListTitles(site: string): Promise<ISPLists> {
|
||||
return this.context.spHttpClient.get(site + `/_api/web/lists?$filter=Hidden eq false and BaseType eq 0`, SPHttpClient.configurations.v1)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
private _getListColumns(listNameColumns: string,listsite: string): Promise<any> {
|
||||
return this.context.spHttpClient.get(listsite + `/_api/web/lists/GetByTitle('${listNameColumns}')/Fields?$filter=Hidden eq false and ReadOnlyField eq false`, SPHttpClient.configurations.v1)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
private _getListData(listName: string, site: string): Promise<any> {
|
||||
return this.context.spHttpClient.get(site + `/_api/web/lists/GetByTitle('${listName}')/items?$select=${encodeURIComponent(this.properties.title)},${encodeURIComponent(this.properties.start)},${encodeURIComponent(this.properties.end)},${encodeURIComponent(this.properties.detail)},Created,Author/ID,Author/Title&$expand=Author/ID,Author/Title&$orderby=Id desc&$limit=500`,SPHttpClient.configurations.v1)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
private _renderList(items: any[]): void {
|
||||
var calItems: FC.EventObject[] = items.map((list: any) => {
|
||||
return {
|
||||
title: list[this.properties.title],
|
||||
start: list[this.properties.start],
|
||||
end: list[this.properties.end],
|
||||
id: list['Id'],
|
||||
detail: list[this.properties.detail]
|
||||
};
|
||||
});
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
const calendarOptions:FC.Options = {
|
||||
theme: true,
|
||||
events: calItems,
|
||||
eventClick: function(_event) {
|
||||
var eventDetail = moment(_event['start']).format('MM/DD/YYYY hh:mm') + ' - ' + moment(_event['end']).format('MM/DD/YYYY hh:mm') + '<br>' + _event['detail'];
|
||||
swal2.default(_event.title,eventDetail,'info');
|
||||
}
|
||||
};
|
||||
jQuery('.spfxcalendar', this.domElement).fullCalendar(calendarOptions);
|
||||
}
|
||||
|
||||
private _getSitesAsync(): void {
|
||||
this._getSiteRootWeb()
|
||||
.then((response) => {
|
||||
this._getSites(response['Url'])
|
||||
.then((response1) => {
|
||||
var sites: IPropertyPaneDropdownOption[] = [];
|
||||
sites.push({key:this.context.pageContext.web.absoluteUrl, text:'This Site'});
|
||||
sites.push({key:'other', text:'Other Site (Specify Url)'});
|
||||
for (var _key in response1.value) {
|
||||
sites.push({key: response1.value[_key]['Url'], text: response1.value[_key]['Title']});
|
||||
}
|
||||
this._siteOptions = sites;
|
||||
this.context.propertyPane.refresh();
|
||||
var siteUrl = this.properties.site;
|
||||
if (this.properties.other) { siteUrl = this.properties.siteOther; }
|
||||
this._getListTitles(siteUrl)
|
||||
.then((response2) => {
|
||||
this._dropdownOptions = response2.value.map((list: ISPList) => {
|
||||
return {
|
||||
key: list.Title,
|
||||
text: list.Title
|
||||
};
|
||||
});
|
||||
this.context.propertyPane.refresh();
|
||||
if (this.properties.listTitle) {
|
||||
this._getListColumns(this.properties.listTitle,this.properties.site)
|
||||
.then((response3) => {
|
||||
var col: IPropertyPaneDropdownOption[] = [];
|
||||
for (var _key in response3.value) {
|
||||
col.push({key: response3.value[_key]['InternalName'], text: response3.value[_key]['Title']});
|
||||
}
|
||||
this._columnOptions = col;
|
||||
this.colsDisabled = false;
|
||||
this.listDisabled = false;
|
||||
this.context.propertyPane.refresh();
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
this.render();
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private _renderListAsync(): void {
|
||||
var siteUrl = this.properties.site;
|
||||
if (this.properties.other) { siteUrl = this.properties.siteOther; }
|
||||
this._getListData(this.properties.listTitle, siteUrl).then((response) => {
|
||||
this._renderList(response.value);
|
||||
}).catch((err) => {
|
||||
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
|
||||
this.context.statusRenderer.renderError(this.domElement,"There was an error loading your list, please verify the selected list has Calendar Events or choose a new list.");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
declare interface IModernCalendarStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'modernCalendarStrings' {
|
||||
const strings: IModernCalendarStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/// <reference types="mocha" />
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
describe('ModernCalendarWebPart', () => {
|
||||
it('should do something', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// Type definitions for Microsoft ODSP projects
|
||||
// Project: ODSP
|
||||
|
||||
/* Global definition for UNIT_TEST builds
|
||||
Code that is wrapped inside an if(UNIT_TEST) {...}
|
||||
block will not be included in the final bundle when the
|
||||
--ship flag is specified */
|
||||
declare const UNIT_TEST: boolean;
|
|
@ -0,0 +1 @@
|
|||
/// <reference path="@ms/odsp.d.ts" />
|
Loading…
Reference in New Issue