Upgraded to SPFx1.7 (#678)
This commit is contained in:
parent
f1359c18cc
commit
2782b8ca98
|
@ -1,2 +0,0 @@
|
||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
|
@ -1,11 +1,12 @@
|
||||||
{
|
{
|
||||||
"@microsoft/generator-sharepoint": {
|
"@microsoft/generator-sharepoint": {
|
||||||
"version": "1.5.0",
|
"isCreatingSolution": true,
|
||||||
|
"environment": "spo",
|
||||||
|
"version": "1.7.0",
|
||||||
"libraryName": "react-calendar-feed",
|
"libraryName": "react-calendar-feed",
|
||||||
"libraryId": "dd42aa00-b07d-48a2-8896-cc2f8c0d3fae",
|
"libraryId": "dd42aa00-b07d-48a2-8896-cc2f8c0d3fae",
|
||||||
"environment": "spo",
|
|
||||||
"isCreatingSolution": true,
|
|
||||||
"packageManager": "npm",
|
"packageManager": "npm",
|
||||||
|
"isDomainIsolated": false,
|
||||||
"componentType": "webpart"
|
"componentType": "webpart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ For more information about how this solution was built, including some design de
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![SPFx v1.5](https://img.shields.io/badge/SPFx-1.5-green.svg)
|
![SPFx v1.7](https://img.shields.io/badge/SPFx-1.7-green.svg)
|
||||||
|
|
||||||
## Applies to
|
## Applies to
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|May 15, 2018|Initial release
|
1.0|May 15, 2018|Initial release
|
||||||
2.0|June 25, 2018|Converted to SPFx 1.5 and added Exchange Public Calendar support
|
2.0|June 25, 2018|Converted to SPFx 1.5 and added Exchange Public Calendar support
|
||||||
|
3.0|November 9, 2018|Converted to SPFx 1.7; Added SharePoint Calendar feed
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ Version|Date|Comments
|
||||||
- Insert the web part on a page
|
- Insert the web part on a page
|
||||||
- When prompted to configure the web part, select **Configure** to launch the web part property pane.
|
- When prompted to configure the web part, select **Configure** to launch the web part property pane.
|
||||||
- Select a feed type (RSS, iCal, WordPress, or Mock if using the debug solution)
|
- Select a feed type (RSS, iCal, WordPress, or Mock if using the debug solution)
|
||||||
- Provide the feed's URL. If using _Mock_, provide any valid URL.
|
- Provide the feed's URL. If using _Mock_, provide any valid URL (value will be ignored). If you wish to use a SharePoint calendar feed, provide the URL to the list (e.g.: https://yourtenant.sharepoint.com/sites/sitename/lists/eventlistname)
|
||||||
- Specify a date range (one week, two weeks, one month, one quarter, one year)
|
- Specify a date range (one week, two weeks, one month, one quarter, one year)
|
||||||
- Specify a maximum number of events to retrieve
|
- Specify a maximum number of events to retrieve
|
||||||
- If necessary, specify to use a proxy. Use this option if you encounter issues where your feed provider does not accept your tenant URL as a CORS origin.
|
- If necessary, specify to use a proxy. Use this option if you encounter issues where your feed provider does not accept your tenant URL as a CORS origin.
|
||||||
|
@ -81,5 +82,6 @@ This Web Part illustrates the following concepts on top of the SharePoint Framew
|
||||||
- Creating shared components and services
|
- Creating shared components and services
|
||||||
- Creating extensible services
|
- Creating extensible services
|
||||||
- Using a proxy to resolve CORS issues
|
- Using a proxy to resolve CORS issues
|
||||||
|
- Retrieving SharePoint events from a list with a filter
|
||||||
|
|
||||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-calendar-feed" />
|
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-calendar-feed" />
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
|
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
|
||||||
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js"
|
"PropertyControlStrings": "node_modules/@pnp/spfx-property-controls/lib/loc/{locale}.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://dev.office.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": "temp/deploy"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-calendar-feed-client-side-solution",
|
"name": "react-calendar-feed-client-side-solution",
|
||||||
"id": "dd42aa00-b07d-48a2-8896-cc2f8c0d3fae",
|
"id": "dd42aa00-b07d-48a2-8896-cc2f8c0d3fae",
|
||||||
"version": "1.0.1.2",
|
"version": "3.0.0.0",
|
||||||
"includeClientSideAssets": true
|
"includeClientSideAssets": true,
|
||||||
|
"isDomainIsolated": false,
|
||||||
|
"iconPath": "images/appicon.png"
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
"zippedPackage": "solution/react-calendar-feed.sppkg"
|
"zippedPackage": "solution/react-calendar-feed.sppkg"
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/tslint.schema.json",
|
|
||||||
// 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-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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-calendar-feed",
|
"name": "react-calendar-feed",
|
||||||
"version": "1.1.0",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
|
@ -11,34 +11,35 @@
|
||||||
"test": "gulp test"
|
"test": "gulp test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/sp-core-library": "~1.4.1",
|
"@microsoft/sp-core-library": "1.7.0",
|
||||||
"@microsoft/sp-lodash-subset": "~1.4.1",
|
"@microsoft/sp-lodash-subset": "1.7.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "~1.4.1",
|
"@microsoft/sp-office-ui-fabric-core": "1.7.0",
|
||||||
"@microsoft/sp-webpart-base": "~1.4.1",
|
"@microsoft/sp-webpart-base": "1.7.0",
|
||||||
"@pnp/spfx-controls-react": "^1.3.0",
|
"@pnp/pnpjs": "^1.2.5",
|
||||||
"@pnp/spfx-property-controls": "^1.6.0",
|
"@pnp/spfx-controls-react": "^1.10.0",
|
||||||
|
"@pnp/spfx-property-controls": "^1.11.0",
|
||||||
"@types/es6-promise": "0.0.33",
|
"@types/es6-promise": "0.0.33",
|
||||||
"@types/react": "15.6.6",
|
"@types/react": "16.4.2",
|
||||||
"@types/react-dom": "15.5.6",
|
"@types/react-dom": "16.0.5",
|
||||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
"@types/webpack-env": "1.13.1",
|
||||||
"ical.js": "^1.2.2",
|
"ical.js": "^1.3.0",
|
||||||
"ics-js": "^0.10.2",
|
"ics-js": "^0.10.2",
|
||||||
"jquery": "^3.3.1",
|
"moment": "^2.22.2",
|
||||||
"moment": "^2.22.1",
|
"react": "16.3.2",
|
||||||
"react": "15.6.2",
|
"react-dom": "16.3.2",
|
||||||
"react-dom": "15.6.2",
|
"react-slick": "^0.23.2",
|
||||||
"react-slick": "^0.23.1",
|
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"xml-js": "^1.6.2",
|
"xml-js": "^1.6.8",
|
||||||
"xml2js": "^0.4.19"
|
"xml2js": "^0.4.19"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/sp-build-web": "~1.4.1",
|
"@microsoft/sp-build-web": "1.7.0",
|
||||||
"@microsoft/sp-module-interfaces": "~1.4.1",
|
"@microsoft/sp-tslint-rules": "1.7.0",
|
||||||
"@microsoft/sp-webpart-workbench": "~1.4.1",
|
"@microsoft/sp-module-interfaces": "1.7.0",
|
||||||
"@types/chai": ">=3.4.34 <3.6.0",
|
"@microsoft/sp-webpart-workbench": "1.7.0",
|
||||||
"@types/mocha": ">=2.2.33 <2.6.0",
|
"gulp": "~3.9.1",
|
||||||
"ajv": "~5.2.2",
|
"@types/chai": "3.4.34",
|
||||||
"gulp": "~3.9.1"
|
"@types/mocha": "2.2.38",
|
||||||
|
"ajv": "~5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -1,82 +1,88 @@
|
||||||
import { css } from '@uifabric/utilities/lib/css';
|
import { css } from "@uifabric/utilities/lib/css";
|
||||||
import { IconButton } from 'office-ui-fabric-react/lib/Button';
|
import { IconButton } from "office-ui-fabric-react/lib/Button";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import Slider from 'react-slick';
|
import Slider from "react-slick";
|
||||||
import { ICarouselContainerProps, ICarouselContainerState } from '.';
|
import { ICarouselContainerProps, ICarouselContainerState } from ".";
|
||||||
import styles from './CarouselContainer.module.scss';
|
import styles from "./CarouselContainer.module.scss";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Carousel container
|
* Carousel container
|
||||||
* Presents the child compoments as a slick slide
|
* Presents the child compoments as a slick slide
|
||||||
*/
|
*/
|
||||||
export class CarouselContainer extends React.Component<ICarouselContainerProps, ICarouselContainerState> {
|
export class CarouselContainer extends React.Component<
|
||||||
// the slick slider used in normal views
|
ICarouselContainerProps,
|
||||||
private _slider: Slider;
|
ICarouselContainerState
|
||||||
|
> {
|
||||||
|
// the slick slider used in normal views
|
||||||
|
private _slider: Slider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a slick switch, a slide for each child, and next/previous arrows
|
* Renders a slick switch, a slide for each child, and next/previous arrows
|
||||||
*/
|
*/
|
||||||
public render(): React.ReactElement<ICarouselContainerProps> {
|
public render(): React.ReactElement<ICarouselContainerProps> {
|
||||||
var settings: any = {
|
// slick seems to have an issue with having "infinite" mode set to true and having less items than the number of slides per page
|
||||||
accessibility: true,
|
// set infinite to true only if there are more than 3 children
|
||||||
arrows: false,
|
var isInfinite: boolean = React.Children.count(this.props.children) > 3;
|
||||||
autoplaySpeed: 5000,
|
var settings: any = {
|
||||||
dots: true,
|
accessibility: true,
|
||||||
infinite: true,
|
arrows: false,
|
||||||
slidesToShow: 4,
|
autoplaySpeed: 5000,
|
||||||
slidesToScroll: 4,
|
dots: true,
|
||||||
speed: 500,
|
infinite: isInfinite,
|
||||||
centerPadding: "50px",
|
slidesToShow: 4,
|
||||||
pauseOnHover: true,
|
slidesToScroll: 4,
|
||||||
variableWidth: false,
|
speed: 500,
|
||||||
useCSS: true,
|
centerPadding: "50px",
|
||||||
rows: 1,
|
pauseOnHover: true,
|
||||||
respondTo: 'slider',
|
variableWidth: false,
|
||||||
responsive: [
|
useCSS: true,
|
||||||
|
rows: 1,
|
||||||
{
|
respondTo: "slider",
|
||||||
breakpoint: 2560,
|
responsive: [
|
||||||
settings: {
|
{
|
||||||
slidesToShow: 3,
|
breakpoint: 2560,
|
||||||
slidesToScroll: 3,
|
settings: {
|
||||||
}
|
slidesToShow: 3,
|
||||||
},
|
slidesToScroll: 3
|
||||||
{
|
}
|
||||||
breakpoint: 801,
|
},
|
||||||
settings: {
|
{
|
||||||
slidesToShow: 2,
|
breakpoint: 801,
|
||||||
slidesToScroll: 2,
|
settings: {
|
||||||
}
|
slidesToShow: 2,
|
||||||
},
|
slidesToScroll: 2
|
||||||
// there is no 1 slide option, as it converts to narrow view
|
}
|
||||||
]
|
}
|
||||||
};
|
// there is no 1 slide option, as it converts to narrow view
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css(styles.carouselContainer, styles.filmStrip)}>
|
<div className={css(styles.carouselContainer, styles.filmStrip)}>
|
||||||
<Slider ref={c => (this._slider = c)}
|
<Slider ref={c => (this._slider = c)} {...settings}>
|
||||||
{...settings}>
|
{this.props.children}
|
||||||
{this.props.children}
|
</Slider>
|
||||||
</Slider>
|
<div
|
||||||
<div
|
className={css(styles.indexButtonContainer, styles.sliderButtons)}
|
||||||
className={css(styles.indexButtonContainer, styles.sliderButtons)}
|
style={{ left: "10px" }}
|
||||||
style={{ "left": "10px" }}
|
onClick={() => this._slider.slickPrev()}
|
||||||
onClick={() => this._slider.slickPrev()}
|
>
|
||||||
>
|
<IconButton
|
||||||
<IconButton className={css(styles.indexButton, styles.leftPositioned)}
|
className={css(styles.indexButton, styles.leftPositioned)}
|
||||||
iconProps={{ iconName: "ChevronLeft" }}
|
iconProps={{ iconName: "ChevronLeft" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={css(styles.indexButtonContainer, styles.sliderButtons)}
|
className={css(styles.indexButtonContainer, styles.sliderButtons)}
|
||||||
style={{ "right": "10px" }}
|
style={{ right: "10px" }}
|
||||||
onClick={() => this._slider.slickNext()}
|
onClick={() => this._slider.slickNext()}
|
||||||
>
|
>
|
||||||
<IconButton className={css(styles.indexButton, styles.rightPositioned)}
|
<IconButton
|
||||||
iconProps={{ iconName: "ChevronRight" }}
|
className={css(styles.indexButton, styles.rightPositioned)}
|
||||||
/>
|
iconProps={{ iconName: "ChevronRight" }}
|
||||||
</div>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './CarouselContainer';
|
export * from "./CarouselContainer";
|
||||||
export * from './CarouselContainer.types';
|
export * from "./CarouselContainer.types";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
import { css } from 'office-ui-fabric-react/lib/Utilities';
|
import { css } from "office-ui-fabric-react/lib/Utilities";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import styles from './DateBox.module.scss';
|
import styles from "./DateBox.module.scss";
|
||||||
import { DateBoxSize, IDateBoxProps, IDateBoxState } from './DateBox.types';
|
import { DateBoxSize, IDateBoxProps, IDateBoxState } from "./DateBox.types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a date in a SharePoint-looking date
|
* Shows a date in a SharePoint-looking date
|
||||||
|
@ -50,4 +50,4 @@ export class DateBox extends React.Component<IDateBoxProps, IDateBoxState> {
|
||||||
<div className={styles.date} data-automation-id="multipleDayEndDateContainer">{endMoment.format("MMM D").toUpperCase()}</div>
|
<div className={styles.date} data-automation-id="multipleDayEndDateContainer">{endMoment.format("MMM D").toUpperCase()}</div>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './DateBox';
|
export * from "./DateBox";
|
||||||
export * from './DateBox.types';
|
export * from "./DateBox.types";
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import { Guid } from '@microsoft/sp-core-library';
|
import { Guid } from "@microsoft/sp-core-library";
|
||||||
import * as strings from 'CalendarFeedSummaryWebPartStrings';
|
import * as strings from "CalendarFeedSummaryWebPartStrings";
|
||||||
import * as ICS from 'ics-js';
|
import * as ICS from "ics-js";
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
import { ActionButton, DocumentCard, DocumentCardType, FocusZone, css } from 'office-ui-fabric-react';
|
import { ActionButton, DocumentCard, DocumentCardType, FocusZone, css } from "office-ui-fabric-react";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import { IEventCardProps, IEventCardState } from '.';
|
import { IEventCardProps, IEventCardState } from ".";
|
||||||
import { DateBox, DateBoxSize } from '../DateBox';
|
import { DateBox, DateBoxSize } from "../DateBox";
|
||||||
import styles from './EventCard.module.scss';
|
import styles from "./EventCard.module.scss";
|
||||||
const AllDayFormat: string = 'dddd, MMMM Do YYYY';
|
import { Text } from "@microsoft/sp-core-library";
|
||||||
const LocalizedTimeFormat: string = 'llll';
|
|
||||||
import { Text } from '@microsoft/sp-core-library';
|
|
||||||
/**
|
/**
|
||||||
* Shows an event in a document card
|
* Shows an event in a document card
|
||||||
*/
|
*/
|
||||||
|
@ -31,10 +29,10 @@ export class EventCard extends React.Component<IEventCardProps, IEventCardState>
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
category,
|
category,
|
||||||
description,
|
// description,
|
||||||
location } = this.props.event;
|
location } = this.props.event;
|
||||||
const eventDate: moment.Moment = moment(start);
|
const eventDate: moment.Moment = moment(start);
|
||||||
const dateString: string = allDay ? eventDate.format(AllDayFormat) : eventDate.format(LocalizedTimeFormat);
|
const dateString: string = allDay ? eventDate.format(strings.AllDayDateFormat) : eventDate.format(strings.LocalizedTimeFormat);
|
||||||
const { isEditMode } = this.props;
|
const { isEditMode } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -87,10 +85,11 @@ export class EventCard extends React.Component<IEventCardProps, IEventCardState>
|
||||||
allDay,
|
allDay,
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
category,
|
// category,
|
||||||
location } = this.props.event;
|
// location
|
||||||
|
} = this.props.event;
|
||||||
const eventDate: moment.Moment = moment.utc(start);
|
const eventDate: moment.Moment = moment.utc(start);
|
||||||
const dateString: string = allDay ? eventDate.format(AllDayFormat) : eventDate.format(LocalizedTimeFormat);
|
const dateString: string = allDay ? eventDate.format(strings.AllDayDateFormat) : eventDate.format(strings.LocalizedTimeFormat);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ICalendarEvent } from '../../../../lib/shared/services/CalendarService';
|
import { ICalendarEvent } from "../../../shared/services/CalendarService";
|
||||||
|
|
||||||
export interface IEventCardProps {
|
export interface IEventCardProps {
|
||||||
isEditMode: boolean;
|
isEditMode: boolean;
|
||||||
|
@ -6,4 +6,4 @@ export interface IEventCardProps {
|
||||||
isNarrow: boolean;
|
isNarrow: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEventCardState {}
|
export interface IEventCardState {}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './EventCard';
|
export * from "./EventCard";
|
||||||
export * from './EventCard.types';
|
export * from "./EventCard.types";
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { ActionButton, IButtonProps } from 'office-ui-fabric-react/lib/Button';
|
import { ActionButton, IButtonProps } from "office-ui-fabric-react/lib/Button";
|
||||||
import { Icon } from 'office-ui-fabric-react/lib/Icon';
|
import { Icon } from "office-ui-fabric-react/lib/Icon";
|
||||||
import { css } from 'office-ui-fabric-react/lib/Utilities';
|
import { css } from "office-ui-fabric-react/lib/Utilities";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import { IPagingProps, IPagingState } from '.';
|
import { IPagingProps, IPagingState } from ".";
|
||||||
import styles from './Paging.module.scss';
|
import styles from "./Paging.module.scss";
|
||||||
import * as strings from 'CalendarFeedSummaryWebPartStrings';
|
import * as strings from "CalendarFeedSummaryWebPartStrings";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom pagination control designed to look & feel like Office UI Fabric
|
* A custom pagination control designed to look & feel like Office UI Fabric
|
||||||
|
@ -12,7 +12,7 @@ import * as strings from 'CalendarFeedSummaryWebPartStrings';
|
||||||
export class Paging extends React.Component<IPagingProps, IPagingState> {
|
export class Paging extends React.Component<IPagingProps, IPagingState> {
|
||||||
public render(): React.ReactElement<IPagingProps> {
|
public render(): React.ReactElement<IPagingProps> {
|
||||||
|
|
||||||
const { totalItems, itemsCountPerPage, currentPage } = this.props;
|
const { currentPage } = this.props;
|
||||||
|
|
||||||
// calculate the page situation
|
// calculate the page situation
|
||||||
const numberOfPages: number = this._getNumberOfPages();
|
const numberOfPages: number = this._getNumberOfPages();
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './Paging';
|
export * from "./Paging";
|
||||||
export * from './Paging.types';
|
export * from "./Paging.types";
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { HttpClient, HttpClientResponse } from '@microsoft/sp-http';
|
import { HttpClient, HttpClientResponse } from "@microsoft/sp-http";
|
||||||
import { IWebPartContext } from '@microsoft/sp-webpart-base';
|
import { IWebPartContext } from "@microsoft/sp-webpart-base";
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
import { CalendarEventRange } from '.';
|
import { CalendarEventRange } from ".";
|
||||||
import { ICalendarEvent } from './ICalendarEvent';
|
import { ICalendarEvent } from "./ICalendarEvent";
|
||||||
import { ICalendarService } from './ICalendarService';
|
import { ICalendarService } from "./ICalendarService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Calendar Service
|
* Base Calendar Service
|
||||||
|
@ -60,7 +60,6 @@ export abstract class BaseCalendarService implements ICalendarService {
|
||||||
*/
|
*/
|
||||||
protected replaceTokens(feedUrl: string, dateRange: CalendarEventRange): string {
|
protected replaceTokens(feedUrl: string, dateRange: CalendarEventRange): string {
|
||||||
const startMoment: moment.Moment = moment(dateRange.Start);
|
const startMoment: moment.Moment = moment(dateRange.Start);
|
||||||
const endMoment: moment.Moment = moment(dateRange.End);
|
|
||||||
const startDate: string = startMoment.format("YYYY-MM-DD");
|
const startDate: string = startMoment.format("YYYY-MM-DD");
|
||||||
const endDate: string = startMoment.format("YYYY-MM-DD");
|
const endDate: string = startMoment.format("YYYY-MM-DD");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
|
|
||||||
export enum DateRange {
|
export enum DateRange {
|
||||||
OneWeek,
|
OneWeek,
|
||||||
|
|
|
@ -1,53 +1,61 @@
|
||||||
import { MockCalendarService } from './MockCalendarService';
|
import { MockCalendarService } from "./MockCalendarService";
|
||||||
import { RSSCalendarService } from './RSSCalendarService';
|
import { RSSCalendarService } from "./RSSCalendarService";
|
||||||
import { WordPressFullCalendarService } from './WordPressFullCalendarService';
|
import { WordPressFullCalendarService } from "./WordPressFullCalendarService";
|
||||||
import { iCalCalendarService } from './iCalCalendarService';
|
import { iCalCalendarService } from "./iCalCalendarService";
|
||||||
import { ExchangePublicCalendarService } from './ExchangePublicCalendarService';
|
import { ExchangePublicCalendarService } from "./ExchangePublicCalendarService";
|
||||||
|
import { SharePointCalendarService } from "./SharePointCalendarService";
|
||||||
|
|
||||||
export class CalendarServiceProviderList {
|
export class CalendarServiceProviderList {
|
||||||
public static getProviders(): any[] {
|
public static getProviders(): any[] {
|
||||||
const providers: any[] = [];
|
const providers: any[] = [];
|
||||||
|
|
||||||
// only include the Mock service provider in DEBUG
|
// only include the Mock service provider in DEBUG
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
providers.push({
|
providers.push({
|
||||||
label: "Mock",
|
label: "Mock",
|
||||||
key: "mock",
|
key: "mock",
|
||||||
initialize: () => new MockCalendarService()
|
initialize: () => new MockCalendarService()
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
providers.push({
|
|
||||||
label: "Exchange Public Calendar",
|
|
||||||
key: "exchange",
|
|
||||||
initialize: () => new ExchangePublicCalendarService()
|
|
||||||
});
|
|
||||||
|
|
||||||
providers.push({
|
|
||||||
label: "WordPress",
|
|
||||||
key: "wordpress",
|
|
||||||
initialize: () => new WordPressFullCalendarService()
|
|
||||||
});
|
|
||||||
|
|
||||||
providers.push({
|
|
||||||
label: "iCal",
|
|
||||||
key: "ical",
|
|
||||||
initialize: () => new iCalCalendarService()
|
|
||||||
});
|
|
||||||
|
|
||||||
providers.push({
|
|
||||||
label: "RSS",
|
|
||||||
key: "RSS",
|
|
||||||
initialize: () => new RSSCalendarService()
|
|
||||||
});
|
|
||||||
|
|
||||||
return providers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
providers.push({
|
||||||
|
label: "SharePoint Calendar",
|
||||||
|
key: "sharepoint",
|
||||||
|
initialize: () => new SharePointCalendarService()
|
||||||
|
});
|
||||||
|
|
||||||
|
providers.push({
|
||||||
|
label: "Exchange Public Calendar",
|
||||||
|
key: "exchange",
|
||||||
|
initialize: () => new ExchangePublicCalendarService()
|
||||||
|
});
|
||||||
|
|
||||||
|
providers.push({
|
||||||
|
label: "WordPress",
|
||||||
|
key: "wordpress",
|
||||||
|
initialize: () => new WordPressFullCalendarService()
|
||||||
|
});
|
||||||
|
|
||||||
|
providers.push({
|
||||||
|
label: "iCal",
|
||||||
|
key: "ical",
|
||||||
|
initialize: () => new iCalCalendarService()
|
||||||
|
});
|
||||||
|
|
||||||
|
providers.push({
|
||||||
|
label: "RSS",
|
||||||
|
key: "RSS",
|
||||||
|
initialize: () => new RSSCalendarService()
|
||||||
|
});
|
||||||
|
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CalendarServiceProviderType {
|
export enum CalendarServiceProviderType {
|
||||||
WordPress = "WordPress",
|
SharePoint = "SharePoint",
|
||||||
iCal = "iCal",
|
WordPress = "WordPress",
|
||||||
RSS = "RSS",
|
iCal = "iCal",
|
||||||
Mock = "Mock"
|
RSS = "RSS",
|
||||||
}
|
Mock = "Mock"
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Exchange Public Calendar Service
|
* Exchange Public Calendar Service
|
||||||
*/
|
*/
|
||||||
import { ICalendarService } from '..';
|
import { ICalendarService } from "..";
|
||||||
import { ICalendarEvent } from '../ICalendarEvent';
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
import { iCalCalendarService } from '../iCalCalendarService';
|
import { iCalCalendarService } from "../iCalCalendarService";
|
||||||
|
|
||||||
// tslint:disable-next-line:class-name
|
// tslint:disable-next-line:class-name
|
||||||
export class ExchangePublicCalendarService extends iCalCalendarService implements ICalendarService {
|
export class ExchangePublicCalendarService extends iCalCalendarService implements ICalendarService {
|
||||||
|
@ -13,8 +13,8 @@ export class ExchangePublicCalendarService extends iCalCalendarService implement
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEvents = (): Promise<ICalendarEvent[]> => {
|
public getEvents = (): Promise<ICalendarEvent[]> => {
|
||||||
// Exchange public calendar shares are really ICS calendars.
|
// exchange public calendar shares are really ICS calendars.
|
||||||
// we allow users to pass either the .html URL or
|
// we allow users to pass either the .html URL or
|
||||||
// the .ics, but we really need the .ics file
|
// the .ics, but we really need the .ics file
|
||||||
|
|
||||||
const htmlExtension:string = ".html";
|
const htmlExtension:string = ".html";
|
||||||
|
@ -25,15 +25,5 @@ export class ExchangePublicCalendarService extends iCalCalendarService implement
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getEvents();
|
return this.getEvents();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private changeExtensionToIcs(url: string): string {
|
|
||||||
const htmlExtension:string = ".html";
|
|
||||||
if (url.indexOf(htmlExtension, url.length - htmlExtension.length) >= 0) {
|
|
||||||
// the url ends with .html. Replace it with .ics
|
|
||||||
const root: string = url.substring(0, url.length - htmlExtension.length);
|
|
||||||
return `${root}.ics`;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * from './ExchangePublicCalendarService';
|
export * from "./ExchangePublicCalendarService";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { IWebPartContext } from '@microsoft/sp-webpart-base';
|
import { IWebPartContext } from "@microsoft/sp-webpart-base";
|
||||||
import { CalendarEventRange, ICalendarEvent } from '.';
|
import { CalendarEventRange, ICalendarEvent } from ".";
|
||||||
|
|
||||||
export interface ICalendarService {
|
export interface ICalendarService {
|
||||||
Context: IWebPartContext;
|
Context: IWebPartContext;
|
||||||
|
@ -9,4 +9,4 @@ export interface ICalendarService {
|
||||||
CacheDuration: number;
|
CacheDuration: number;
|
||||||
Name: string;
|
Name: string;
|
||||||
getEvents: () => Promise<ICalendarEvent[]>;
|
getEvents: () => Promise<ICalendarEvent[]>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
* This provider will NOT be listed in the list of available providers when this solution is packaged with --ship.
|
* This provider will NOT be listed in the list of available providers when this solution is packaged with --ship.
|
||||||
* Don't freak out, it didn't just disappear.
|
* Don't freak out, it didn't just disappear.
|
||||||
*/
|
*/
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
import { BaseCalendarService } from '../BaseCalendarService';
|
import { BaseCalendarService } from "../BaseCalendarService";
|
||||||
import { ICalendarEvent } from '../ICalendarEvent';
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
import { ICalendarService } from '../ICalendarService';
|
import { ICalendarService } from "../ICalendarService";
|
||||||
|
|
||||||
const today: Date = new Date();
|
|
||||||
const sampleEvents: ICalendarEvent[] = [
|
const sampleEvents: ICalendarEvent[] = [
|
||||||
{
|
{
|
||||||
"title": "This event will be tomorrow",
|
"title": "This event will be tomorrow",
|
||||||
|
@ -155,4 +154,4 @@ export class MockCalendarService extends BaseCalendarService implements ICalenda
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * from './MockCalendarService';
|
export * from "./MockCalendarService";
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
* every one I could find on NPM and GitHub and found that they did not meet my needs.
|
* every one I could find on NPM and GitHub and found that they did not meet my needs.
|
||||||
* I'm open to suggestions, though, if you have a library that you think would work better.
|
* I'm open to suggestions, though, if you have a library that you think would work better.
|
||||||
*/
|
*/
|
||||||
import { HttpClientResponse } from '@microsoft/sp-http';
|
import { HttpClientResponse } from "@microsoft/sp-http";
|
||||||
import * as convert from 'xml-js';
|
import * as convert from "xml-js";
|
||||||
import { ICalendarService } from '..';
|
import { ICalendarService } from "..";
|
||||||
import { BaseCalendarService } from '../BaseCalendarService';
|
import { BaseCalendarService } from "../BaseCalendarService";
|
||||||
import { ICalendarEvent } from '../ICalendarEvent';
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
import { escape, unescape } from '@microsoft/sp-lodash-subset';
|
import { unescape } from "@microsoft/sp-lodash-subset";
|
||||||
|
|
||||||
export class RSSCalendarService extends BaseCalendarService implements ICalendarService {
|
export class RSSCalendarService extends BaseCalendarService implements ICalendarService {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -51,7 +51,6 @@ export class RSSCalendarService extends BaseCalendarService implements ICalendar
|
||||||
let title: string = this._getElementValue(item, "title");
|
let title: string = this._getElementValue(item, "title");
|
||||||
let link: string = this._getElementValue(item, "link");
|
let link: string = this._getElementValue(item, "link");
|
||||||
let pubDate: Date = new Date(this._getElementValue(item, "pubDate"));
|
let pubDate: Date = new Date(this._getElementValue(item, "pubDate"));
|
||||||
let category: string = this._getElementValue(item, "category");
|
|
||||||
let description: string = this._getElementValue(item, "description");
|
let description: string = this._getElementValue(item, "description");
|
||||||
return {
|
return {
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -100,4 +99,4 @@ export class RSSCalendarService extends BaseCalendarService implements ICalendar
|
||||||
console.log("Found an RSS field type I didn't know", firstElement.type);
|
console.log("Found an RSS field type I didn't know", firstElement.type);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * from './RSSCalendarService';
|
export * from "./RSSCalendarService";
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* ExtensionService
|
||||||
|
*/
|
||||||
|
import { HttpClientResponse } from "@microsoft/sp-http";
|
||||||
|
import { ICalendarService } from "..";
|
||||||
|
import { BaseCalendarService } from "../BaseCalendarService";
|
||||||
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
|
import { Web, sp } from "@pnp/sp";
|
||||||
|
import { combine } from "@pnp/common";
|
||||||
|
|
||||||
|
export class SharePointCalendarService extends BaseCalendarService
|
||||||
|
implements ICalendarService {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.Name = "SharePoint";
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEvents = (): Promise<ICalendarEvent[]> => {
|
||||||
|
const parameterizedFeedUrl: string = this.replaceTokens(
|
||||||
|
this.FeedUrl,
|
||||||
|
this.EventRange
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the URL
|
||||||
|
let webUrl = this.FeedUrl.toLowerCase();
|
||||||
|
|
||||||
|
// Break the URL into parts
|
||||||
|
let urlParts = webUrl.split("/");
|
||||||
|
|
||||||
|
// Get the web root
|
||||||
|
let webRoot = urlParts[0] + "/" + urlParts[1] + "/" + urlParts[2];
|
||||||
|
|
||||||
|
// Get the list URL
|
||||||
|
let listUrl = webUrl.substring(webRoot.length);
|
||||||
|
|
||||||
|
// Find the "lists" portion of the URL to get the site URL
|
||||||
|
let webLocation = listUrl.substr(0, listUrl.indexOf("lists/"));
|
||||||
|
let siteUrl = webRoot + webLocation;
|
||||||
|
|
||||||
|
// Open the web associated to the site
|
||||||
|
let web = new Web(siteUrl);
|
||||||
|
|
||||||
|
// Get the web
|
||||||
|
return web.get().then(() => {
|
||||||
|
// Build a filter so that we don't retrieve every single thing unless necesssary
|
||||||
|
let dateFilter:string = "EventDate ge datetime'"+this.EventRange.Start.toISOString()+"' and EndDate lt datetime'"+this.EventRange.End.toISOString()+"'";
|
||||||
|
|
||||||
|
// When we receive the web, get the list
|
||||||
|
return web
|
||||||
|
.getList(listUrl)
|
||||||
|
.items.select("Id,Title,Description,EventDate,EndDate,fAllDayEvent,Category,Location")
|
||||||
|
.filter(dateFilter)
|
||||||
|
.getAll()
|
||||||
|
.then((items: any[]) => {
|
||||||
|
// Once we get the list, convert to calendar events
|
||||||
|
let events: ICalendarEvent[] = items.map((item: any) => {
|
||||||
|
let eventUrl:string = combine(webUrl, "DispForm.aspx?ID="+item.Id);
|
||||||
|
return {
|
||||||
|
title: item.Title,
|
||||||
|
start: item.EventDate,
|
||||||
|
end: item.EndDate,
|
||||||
|
url: eventUrl,
|
||||||
|
allDay: item.fAllDayEvent,
|
||||||
|
category: item.Category,
|
||||||
|
description: item.Description,
|
||||||
|
location: item.Location
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the calendar items
|
||||||
|
return events;
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
console.log(
|
||||||
|
"Exception caught by catch in SharePoint provider",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./SharePointCalendarService";
|
|
@ -1,10 +1,10 @@
|
||||||
/**
|
/**
|
||||||
* ExtensionService
|
* ExtensionService
|
||||||
*/
|
*/
|
||||||
import { ICalendarService } from '..';
|
import { ICalendarService } from "..";
|
||||||
import { BaseCalendarService } from '../BaseCalendarService';
|
import { BaseCalendarService } from "../BaseCalendarService";
|
||||||
import { ICalendarEvent } from '../ICalendarEvent';
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
import { IWordPressFullCalendarEventResponse } from './IWordPressFullCalendarEventResponse';
|
import { IWordPressFullCalendarEventResponse } from "./IWordPressFullCalendarEventResponse";
|
||||||
|
|
||||||
export class WordPressFullCalendarService extends BaseCalendarService implements ICalendarService {
|
export class WordPressFullCalendarService extends BaseCalendarService implements ICalendarService {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -39,4 +39,4 @@ export class WordPressFullCalendarService extends BaseCalendarService implements
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './IWordPressFullCalendarEventResponse';
|
export * from "./IWordPressFullCalendarEventResponse";
|
||||||
export * from './WordPressFullCalendarService';
|
export * from "./WordPressFullCalendarService";
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* ExtensionService
|
* ExtensionService
|
||||||
*/
|
*/
|
||||||
import { HttpClientResponse } from '@microsoft/sp-http';
|
import { HttpClientResponse } from "@microsoft/sp-http";
|
||||||
import * as ICAL from 'ical.js';
|
import * as ICAL from "ical.js";
|
||||||
import { ICalendarService } from '..';
|
import { ICalendarService } from "..";
|
||||||
import { BaseCalendarService } from '../BaseCalendarService';
|
import { BaseCalendarService } from "../BaseCalendarService";
|
||||||
import { ICalendarEvent } from '../ICalendarEvent';
|
import { ICalendarEvent } from "../ICalendarEvent";
|
||||||
|
|
||||||
// tslint:disable-next-line:class-name
|
// tslint:disable-next-line:class-name
|
||||||
export class iCalCalendarService extends BaseCalendarService implements ICalendarService {
|
export class iCalCalendarService extends BaseCalendarService implements ICalendarService {
|
||||||
|
@ -47,4 +47,4 @@ export class iCalCalendarService extends BaseCalendarService implements ICalenda
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * from './iCalCalendarService';
|
export * from "./iCalCalendarService";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export * from './ICalendarEvent';
|
export * from "./ICalendarEvent";
|
||||||
export * from './ICalendarService';
|
export * from "./ICalendarService";
|
||||||
export * from './CalendarEventRange';
|
export * from "./CalendarEventRange";
|
||||||
export * from './CalendarServiceProviderList';
|
export * from "./CalendarServiceProviderList";
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -1,20 +1,15 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||||
"id": "b83bb343-bc5e-460c-9efd-52de06d32ffa",
|
"id": "0459b501-da31-43c7-9a9a-d5c59cc2d667",
|
||||||
"alias": "CalendarFeedSummaryWebPart",
|
"alias": "CalendarFeedSummaryWebPart",
|
||||||
"componentType": "WebPart",
|
"componentType": "WebPart",
|
||||||
|
|
||||||
// The "*" signifies that the version should be taken from the package.json
|
|
||||||
"version": "*",
|
"version": "*",
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
|
|
||||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
|
||||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
|
||||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
|
||||||
"requiresCustomScript": false,
|
"requiresCustomScript": false,
|
||||||
"preconfiguredEntries": [
|
|
||||||
{
|
"preconfiguredEntries": [{
|
||||||
"groupId": "cf066440-0614-43d6-98ae-0b31cf14c7c3", // Text, media and content
|
"groupId": "cf066440-0614-43d6-98ae-0b31cf14c7c3",
|
||||||
"group": {
|
"group": {
|
||||||
"default": "Text, media and content"
|
"default": "Text, media and content"
|
||||||
},
|
},
|
||||||
|
@ -24,16 +19,13 @@
|
||||||
"description": {
|
"description": {
|
||||||
"default": "Shows a summary view of a list of calendar events retrieved from an external feed."
|
"default": "Shows a summary view of a list of calendar events retrieved from an external feed."
|
||||||
},
|
},
|
||||||
// commented out because of bug with base64 icons
|
|
||||||
// "iconImageUrl": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MCIgaGVpZ2h0PSIyOCIgdmlld0JveD0iMCAwIDEwLjU4IDcuNDEiPjxwYXRoIGQ9Ik0yLjQ4LS4wMVYuNUgxLjJ2Ni4xNWg1LjcyVjYuM0gxLjU0VjIuMmg2LjR2Mi44OGguMjVWLjVINi45MVYwaC0uMzZWLjVIMi44MlYwaC0uMTN6bS0uOTQuODVoLjk0di40M2guMzRWLjg0aDMuNzN2LjQzaC4zNlYuODRoMS4wM3YuOTRoLTYuNHYtLjQ3eiIvPjxwYXRoIGQ9Ik03LjIyIDUuNjh2LS40M2EyLjE2IDIuMTYgMCAwIDEgMi4xNyAyLjE3bC0uNDUtLjAxYy4wMi0uNy0uNDktMS43LTEuNzItMS43M3ptMCAuNzJ2LS40M2MuOTIuMDUgMS40My43IDEuNDQgMS40NWgtLjQzYy0uMDEtLjY2LS40NS0xLTEuMDEtMS4wMnptLjYuN2EuMy4zIDAgMCAxLS4zLjMuMy4zIDAgMCAxLS4zMS0uMy4zLjMgMCAwIDEgLjMtLjI5LjMuMyAwIDAgMSAuMy4zeiIvPjxwYXRoIGQ9Ik0yLjQ4LS4wMVYuNUgxLjJsLjAzIDIuMjMtLjAzIDMuOTJoNS43MlY2LjNIMS41NFYyLjJoNi40djIuODhoLjI1Vi41SDYuOTFWMGgtLjM2Vi41SDIuODJWMGgtLjEzem0tLjk0Ljg1aC45NHYuNDNoLjM0Vi44NGgzLjczdi40M2guMzZWLjg0aDEuMDN2Ljk0aC02LjR2LS40N3oiLz48cGF0aCBkPSJNMi41IDIuNzNoMS42OHYuMzZIMi41em00LjA3LjM2aC4zNHYyLjI4aC0uMzR6bS0xLjM3IDBoLjM1djIuMjhINS4yem0wIDIuMjhoMS43MXYuMzZoLTEuN3ptMC0yLjY0aDEuNzF2LjM2aC0xLjd6Ii8+PHBhdGggZD0iTTMuODYgMy4xaC4zNHYyLjI3aC0uMzR6bS0xLjM2IDBoLjM0djIuMjdIMi41em0wIDIuMjdoMS43di4zNkgyLjV6bTAtMi42NGgxLjd2LjM2SDIuNXoiLz48L3N2Zz4=",
|
|
||||||
"officeFabricIconFontName": "Calendar",
|
"officeFabricIconFontName": "Calendar",
|
||||||
"properties": {
|
"properties": {
|
||||||
"title": "Upcoming Events",
|
"title": "Upcoming Events",
|
||||||
"dateRange": 4, /* Year */
|
"dateRange": 4,
|
||||||
"maxEvents": 4,
|
"maxEvents": 4,
|
||||||
"useCORS": false,
|
"useCORS": false,
|
||||||
"cacheDuration": 15 /* 15 minutes */
|
"cacheDuration": 15
|
||||||
}
|
}
|
||||||
}
|
}]
|
||||||
]
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
import { Version } from '@microsoft/sp-core-library';
|
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
import { BaseClientSideWebPart, IPropertyPaneConfiguration, IPropertyPaneDropdownOption, PropertyPaneDropdown } from '@microsoft/sp-webpart-base';
|
import { BaseClientSideWebPart, IPropertyPaneConfiguration, IPropertyPaneDropdownOption, PropertyPaneDropdown } from "@microsoft/sp-webpart-base";
|
||||||
import { CalloutTriggers } from '@pnp/spfx-property-controls/lib/PropertyFieldHeader';
|
import { CalloutTriggers } from "@pnp/spfx-property-controls/lib/PropertyFieldHeader";
|
||||||
import { PropertyFieldNumber } from '@pnp/spfx-property-controls/lib/PropertyFieldNumber';
|
import { PropertyFieldNumber } from "@pnp/spfx-property-controls/lib/PropertyFieldNumber";
|
||||||
import { PropertyFieldSliderWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldSliderWithCallout';
|
import { PropertyFieldSliderWithCallout } from "@pnp/spfx-property-controls/lib/PropertyFieldSliderWithCallout";
|
||||||
import { PropertyFieldTextWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldTextWithCallout';
|
import { PropertyFieldTextWithCallout } from "@pnp/spfx-property-controls/lib/PropertyFieldTextWithCallout";
|
||||||
import { PropertyFieldToggleWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldToggleWithCallout';
|
import { PropertyFieldToggleWithCallout } from "@pnp/spfx-property-controls/lib/PropertyFieldToggleWithCallout";
|
||||||
import * as strings from 'CalendarFeedSummaryWebPartStrings';
|
import * as strings from "CalendarFeedSummaryWebPartStrings";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from "react-dom";
|
||||||
import { CalendarEventRange, DateRange, ICalendarService } from '../../shared/services/CalendarService';
|
import { CalendarEventRange, DateRange, ICalendarService } from "../../shared/services/CalendarService";
|
||||||
import { CalendarServiceProviderList } from '../../shared/services/CalendarService/CalendarServiceProviderList';
|
import { CalendarServiceProviderList } from "../../shared/services/CalendarService/CalendarServiceProviderList";
|
||||||
import { ICalendarFeedSummaryWebPartProps } from './CalendarFeedSummaryWebPart.types';
|
import { ICalendarFeedSummaryWebPartProps } from "./CalendarFeedSummaryWebPart.types";
|
||||||
import CalendarFeedSummary from './components/CalendarFeedSummary';
|
import CalendarFeedSummary from "./components/CalendarFeedSummary";
|
||||||
import { ICalendarFeedSummaryProps } from './components/CalendarFeedSummary.types';
|
import { ICalendarFeedSummaryProps } from "./components/CalendarFeedSummary.types";
|
||||||
|
|
||||||
// this is the same width that the SharePoint events web parts use to render as narrow
|
// this is the same width that the SharePoint events web parts use to render as narrow
|
||||||
const MaxMobileWidth: number = 480;
|
const MaxMobileWidth: number = 480;
|
||||||
|
@ -39,7 +38,7 @@ export default class CalendarFeedSummaryWebPart extends BaseClientSideWebPart<IC
|
||||||
*/
|
*/
|
||||||
public render(): void {
|
public render(): void {
|
||||||
// see if we need to render a mobile view
|
// see if we need to render a mobile view
|
||||||
const isNarrow: boolean = this.width <= MaxMobileWidth;
|
const isNarrow: boolean = this.domElement.clientWidth <= MaxMobileWidth;
|
||||||
|
|
||||||
// display the summary (or the configuration screen)
|
// display the summary (or the configuration screen)
|
||||||
const element: React.ReactElement<ICalendarFeedSummaryProps> = React.createElement(
|
const element: React.ReactElement<ICalendarFeedSummaryProps> = React.createElement(
|
||||||
|
@ -61,14 +60,6 @@ export default class CalendarFeedSummaryWebPart extends BaseClientSideWebPart<IC
|
||||||
ReactDom.render(element, this.domElement);
|
ReactDom.render(element, this.domElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* We store our configure in version 1.0. If we ever change how we store our configuration information,
|
|
||||||
* we'll update the version number here.
|
|
||||||
*/
|
|
||||||
protected get dataVersion(): Version {
|
|
||||||
return Version.parse("1.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We're disabling reactive property panes here because we don't want the web part to try to update events as
|
* We're disabling reactive property panes here because we don't want the web part to try to update events as
|
||||||
* people are typing in the feed URL.
|
* people are typing in the feed URL.
|
||||||
|
@ -231,7 +222,6 @@ export default class CalendarFeedSummaryWebPart extends BaseClientSideWebPart<IC
|
||||||
*/
|
*/
|
||||||
private _getDataProvider(): ICalendarService {
|
private _getDataProvider(): ICalendarService {
|
||||||
const {
|
const {
|
||||||
feedType,
|
|
||||||
feedUrl,
|
feedUrl,
|
||||||
useCORS,
|
useCORS,
|
||||||
cacheDuration
|
cacheDuration
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { DateRange } from '../../shared/services/CalendarService';
|
import { DateRange } from "../../shared/services/CalendarService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web part properties stored in web part configuration
|
* Web part properties stored in web part configuration
|
||||||
|
@ -11,4 +11,4 @@ export interface ICalendarFeedSummaryWebPartProps {
|
||||||
dateRange: DateRange; // date range to retrieve events
|
dateRange: DateRange; // date range to retrieve events
|
||||||
useCORS: boolean; // use CORS proxy when retrieving events
|
useCORS: boolean; // use CORS proxy when retrieving events
|
||||||
cacheDuration: number; // how long to cache events for
|
cacheDuration: number; // how long to cache events for
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
import { DisplayMode } from "@microsoft/sp-core-library";
|
||||||
import { SPComponentLoader } from '@microsoft/sp-loader';
|
import { SPComponentLoader } from "@microsoft/sp-loader";
|
||||||
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
|
||||||
import { WebPartTitle } from '@pnp/spfx-controls-react/lib/WebPartTitle';
|
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
|
||||||
import * as strings from 'CalendarFeedSummaryWebPartStrings';
|
import * as strings from "CalendarFeedSummaryWebPartStrings";
|
||||||
import * as moment from 'moment';
|
import * as moment from "moment";
|
||||||
import { FocusZone, FocusZoneDirection, List, Spinner, css } from 'office-ui-fabric-react';
|
import { FocusZone, FocusZoneDirection, List, Spinner, css } from "office-ui-fabric-react";
|
||||||
import * as React from 'react';
|
import * as React from "react";
|
||||||
import { CarouselContainer } from '../../../shared/components/CarouselContainer';
|
import { CarouselContainer } from "../../../shared/components/CarouselContainer";
|
||||||
import { EventCard } from '../../../shared/components/EventCard';
|
import { EventCard } from "../../../shared/components/EventCard";
|
||||||
import { Paging } from '../../../shared/components/Paging';
|
import { Paging } from "../../../shared/components/Paging";
|
||||||
import { CalendarServiceProviderType, ICalendarEvent, ICalendarService } from '../../../shared/services/CalendarService';
|
import { CalendarServiceProviderType, ICalendarEvent, ICalendarService } from "../../../shared/services/CalendarService";
|
||||||
import styles from './CalendarFeedSummary.module.scss';
|
import styles from "./CalendarFeedSummary.module.scss";
|
||||||
import { ICalendarFeedSummaryProps, ICalendarFeedSummaryState, IFeedCache } from './CalendarFeedSummary.types';
|
import { ICalendarFeedSummaryProps, ICalendarFeedSummaryState, IFeedCache } from "./CalendarFeedSummary.types";
|
||||||
|
|
||||||
// the key used when caching events
|
// the key used when caching events
|
||||||
const CacheKey: string = "calendarFeedSummary";
|
const CacheKey: string = "calendarFeedSummary";
|
||||||
|
@ -30,8 +30,8 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
};
|
};
|
||||||
|
|
||||||
// needed for the slick slider in normal mode
|
// needed for the slick slider in normal mode
|
||||||
SPComponentLoader.loadCss("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css");
|
SPComponentLoader.loadCss("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css");
|
||||||
SPComponentLoader.loadCss("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css");
|
SPComponentLoader.loadCss("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,8 +69,10 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsHaveChanged: boolean = prevProvider.CacheDuration !== currProvider.CacheDuration ||
|
const settingsHaveChanged: boolean = prevProvider.CacheDuration !== currProvider.CacheDuration ||
|
||||||
|
prevProvider.Name !== currProvider.Name ||
|
||||||
prevProvider.FeedUrl !== currProvider.FeedUrl ||
|
prevProvider.FeedUrl !== currProvider.FeedUrl ||
|
||||||
prevProvider.Name !== currProvider.Name ||
|
prevProvider.Name !== currProvider.Name ||
|
||||||
|
prevProvider.EventRange.DateRange !== currProvider.EventRange.DateRange ||
|
||||||
prevProvider.UseCORS !== currProvider.UseCORS;
|
prevProvider.UseCORS !== currProvider.UseCORS;
|
||||||
|
|
||||||
if (settingsHaveChanged) {
|
if (settingsHaveChanged) {
|
||||||
|
@ -88,13 +90,7 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
public render(): React.ReactElement<ICalendarFeedSummaryProps> {
|
public render(): React.ReactElement<ICalendarFeedSummaryProps> {
|
||||||
const {
|
const {
|
||||||
isConfigured,
|
isConfigured,
|
||||||
isNarrow,
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
|
||||||
events,
|
|
||||||
isLoading,
|
|
||||||
error
|
|
||||||
} = this.state;
|
|
||||||
|
|
||||||
// if we're not configured, show the placeholder
|
// if we're not configured, show the placeholder
|
||||||
if (!isConfigured) {
|
if (!isConfigured) {
|
||||||
|
@ -230,7 +226,6 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
*/
|
*/
|
||||||
private _renderNarrowList(): JSX.Element {
|
private _renderNarrowList(): JSX.Element {
|
||||||
const {
|
const {
|
||||||
isLoading,
|
|
||||||
events,
|
events,
|
||||||
currentPage
|
currentPage
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
@ -288,10 +283,10 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
*/
|
*/
|
||||||
private _renderNormalList(): JSX.Element {
|
private _renderNormalList(): JSX.Element {
|
||||||
const {
|
const {
|
||||||
events,
|
events } = this.state;
|
||||||
isLoading } = this.state;
|
|
||||||
const isEditMode: boolean = this.props.displayMode === DisplayMode.Edit;
|
const isEditMode: boolean = this.props.displayMode === DisplayMode.Edit;
|
||||||
|
|
||||||
|
console.log("EVENTS", events);
|
||||||
return (<div>
|
return (<div>
|
||||||
<div>
|
<div>
|
||||||
<div role="application">
|
<div role="application">
|
||||||
|
@ -364,30 +359,4 @@ export default class CalendarFeedSummary extends React.Component<ICalendarFeedSu
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Saves events in cache with an expiry date
|
|
||||||
* @param events an array of events to save in cache
|
|
||||||
*/
|
|
||||||
private _setCache(events: ICalendarEvent[]): void {
|
|
||||||
const { Name, FeedUrl, CacheDuration } = this.props.provider;
|
|
||||||
|
|
||||||
// don't cache if we haven't set a cache duration
|
|
||||||
if (CacheDuration === undefined || CacheDuration === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const expiry: moment.Moment = moment().add(CacheDuration, "minutes");
|
|
||||||
|
|
||||||
// we use minutes instead of milliseconds, it doesn't make sense that
|
|
||||||
// people want to cache a feed for milliseconds, or seconds
|
|
||||||
// but feel free to change it to suit your needs
|
|
||||||
const cache: IFeedCache = {
|
|
||||||
feedType: Name,
|
|
||||||
feedUrl: FeedUrl,
|
|
||||||
events: events,
|
|
||||||
expiry: expiry
|
|
||||||
};
|
|
||||||
localStorage.setItem(CacheKey, JSON.stringify(cache));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
* file because that's what the Office UI Fabric team does and
|
* file because that's what the Office UI Fabric team does and
|
||||||
* I kinda liked it.
|
* I kinda liked it.
|
||||||
*/
|
*/
|
||||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
import { DisplayMode } from "@microsoft/sp-core-library";
|
||||||
import { IWebPartContext } from '@microsoft/sp-webpart-base';
|
import { IWebPartContext } from "@microsoft/sp-webpart-base";
|
||||||
import { Moment } from 'moment';
|
import { Moment } from "moment";
|
||||||
import { ICalendarEvent, ICalendarService } from '../../../shared/services/CalendarService';
|
import { ICalendarEvent, ICalendarService } from "../../../shared/services/CalendarService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The props for the calendar feed summary component
|
* The props for the calendar feed summary component
|
||||||
|
@ -42,4 +42,4 @@ export interface IFeedCache {
|
||||||
expiry: Moment;
|
expiry: Moment;
|
||||||
feedType: string;
|
feedType: string;
|
||||||
feedUrl: string;
|
feedUrl: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ define([], function() {
|
||||||
"ErrorInvalidiCalFeed": "The URL you provided does not appear to be an iCal feed. Are you sure you selected the right feed type?",
|
"ErrorInvalidiCalFeed": "The URL you provided does not appear to be an iCal feed. Are you sure you selected the right feed type?",
|
||||||
"ErrorInvalidWordPressFeed": "The URL you provided does not appear to be a WordPress feed. Are you sure you selected the right feed type?",
|
"ErrorInvalidWordPressFeed": "The URL you provided does not appear to be a WordPress feed. Are you sure you selected the right feed type?",
|
||||||
"AddToCalendarAriaLabel": "Press enter to download the calendar file to your device.",
|
"AddToCalendarAriaLabel": "Press enter to download the calendar file to your device.",
|
||||||
"AddToCalendarButtonLabel": "Add to my calendar"
|
"AddToCalendarButtonLabel": "Add to my calendar",
|
||||||
|
"AllDayDateFormat": "dddd, MMMM Do YYYY",
|
||||||
|
"LocalizedTimeFormat": "llll"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,6 +50,8 @@ declare interface ICalendarFeedSummaryWebPartStrings {
|
||||||
ErrorInvalidWordPressFeed: string;
|
ErrorInvalidWordPressFeed: string;
|
||||||
AddToCalendarAriaLabel: string;
|
AddToCalendarAriaLabel: string;
|
||||||
AddToCalendarButtonLabel: string;
|
AddToCalendarButtonLabel: string;
|
||||||
|
AllDayDateFormat: string;
|
||||||
|
LocalizedTimeFormat: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'CalendarFeedSummaryWebPartStrings' {
|
declare module 'CalendarFeedSummaryWebPartStrings' {
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.2/MicrosoftTeams.schema.json",
|
||||||
|
"manifestVersion": "1.2",
|
||||||
|
"packageName": "CalendarFeedSummary",
|
||||||
|
"id": "0459b501-da31-43c7-9a9a-d5c59cc2d667",
|
||||||
|
"version": "0.1",
|
||||||
|
"developer": {
|
||||||
|
"name": "SPFx + Teams Dev",
|
||||||
|
"websiteUrl": "https://products.office.com/en-us/sharepoint/collaboration",
|
||||||
|
"privacyUrl": "https://privacy.microsoft.com/en-us/privacystatement",
|
||||||
|
"termsOfUseUrl": "https://www.microsoft.com/en-us/servicesagreement"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"short": "CalendarFeedSummary"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"short": "Shows a summary view of a list of calendar events retrieved from an external feed.",
|
||||||
|
"full": "Shows a summary view of a list of calendar events retrieved from an external feed."
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"outline": "tab20x20.png",
|
||||||
|
"color": "tab96x96.png"
|
||||||
|
},
|
||||||
|
"accentColor": "#004578",
|
||||||
|
"configurableTabs": [
|
||||||
|
{
|
||||||
|
"configurationUrl": "https://{teamSiteDomain}{teamSitePath}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx%3FopenPropertyPane=true%26teams%26componentId=0459b501-da31-43c7-9a9a-d5c59cc2d667",
|
||||||
|
"canUpdateConfiguration": false,
|
||||||
|
"scopes": [
|
||||||
|
"team"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validDomains": [
|
||||||
|
"*.login.microsoftonline.com",
|
||||||
|
"*.sharepoint.com",
|
||||||
|
"*.sharepoint-df.com",
|
||||||
|
"spoppe-a.akamaihd.net",
|
||||||
|
"spoprod-a.akamaihd.net",
|
||||||
|
"resourceseng.blob.core.windows.net",
|
||||||
|
"msft.spoppe.com"
|
||||||
|
],
|
||||||
|
"webApplicationInfo": {
|
||||||
|
"resource": "https://{teamSiteDomain}",
|
||||||
|
"id": "00000003-0000-0ff1-ce00-000000000000"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 933 B |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -1,14 +1,15 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"moduleResolution": "node",
|
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types",
|
"./node_modules/@types",
|
||||||
"./node_modules/@microsoft"
|
"./node_modules/@microsoft"
|
||||||
|
@ -22,5 +23,12 @@
|
||||||
"dom",
|
"dom",
|
||||||
"es2015.collection"
|
"es2015.collection"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"class-name": false,
|
||||||
|
"export-name": false,
|
||||||
|
"forin": false,
|
||||||
|
"label-position": false,
|
||||||
|
"member-access": true,
|
||||||
|
"no-arg": false,
|
||||||
|
"no-console": false,
|
||||||
|
"no-construct": false,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-eval": false,
|
||||||
|
"no-function-expression": true,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-unnecessary-semicolons": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"no-with-statement": true,
|
||||||
|
"semicolon": true,
|
||||||
|
"trailing-comma": false,
|
||||||
|
"typedef": false,
|
||||||
|
"typedef-whitespace": false,
|
||||||
|
"use-named-parameter": true,
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue