Merge pull request #1560 from Abderahman88/UpdateBigCalendar

This commit is contained in:
Hugo Bernier 2020-10-21 21:56:41 -04:00 committed by GitHub
commit f2f0679c43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 442 additions and 106 deletions

View File

@ -16,6 +16,7 @@
"localizedResources": {
"CalendarWebPartStrings": "lib/webparts/calendar/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",
"CalendarToolbar": "lib/webparts/calendar/components/Toolbar.jsx"
}
}

View File

@ -3,7 +3,7 @@
"solution": {
"name": "react-calendar-client-side-solution",
"id": "3a13208b-3874-4036-9262-4edd22e88187",
"version": "1.0.4.0",
"version": "1.0.5.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true,
"isDomainIsolated": false

View File

@ -152,17 +152,17 @@
"dev": true
},
"@babel/runtime": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz",
"integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==",
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz",
"integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==",
"requires": {
"regenerator-runtime": "^0.13.2"
"regenerator-runtime": "^0.13.4"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.13.2",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
"integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
}
}
},
@ -5786,6 +5786,15 @@
"integrity": "sha512-NsEzBVa5aMgn/n79piyJtpUQFzJ97tB2R2r8PSJlLnMA6LJmchKuv7ATN+/nZH/3QRd/+uFXEq07/i/ajsqVGQ==",
"dev": true
},
"@restart/hooks": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.25.tgz",
"integrity": "sha512-m2v3N5pxTsIiSH74/sb1yW8D9RxkJidGW+5Mfwn/lHb2QzhZNlaU1su7abSyT9EGf0xS/0waLjrf7/XxQHUk7w==",
"requires": {
"lodash": "^4.17.15",
"lodash-es": "^4.17.15"
}
},
"@types/adal-angular": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/adal-angular/-/adal-angular-1.0.1.tgz",
@ -6094,9 +6103,9 @@
}
},
"@types/react-big-calendar": {
"version": "0.20.13",
"resolved": "https://registry.npmjs.org/@types/react-big-calendar/-/react-big-calendar-0.20.13.tgz",
"integrity": "sha512-aFaICwmv8De+PiXAlSxqQpNoe1/tUHIFrM9F/6JcF9OouQmzYOy0/EBGbN7I/uL5sdivHGyaLrg4oKqDldJNVA==",
"version": "0.24.6",
"resolved": "https://registry.npmjs.org/@types/react-big-calendar/-/react-big-calendar-0.24.6.tgz",
"integrity": "sha512-np1isJTczysxHBUHsdh1a/oI0SH0Cm1qzulHeItmtde/3qU42OX7pNjAHixBBaOCkLSuQS1b2N3drZarjbxM3A==",
"requires": {
"@types/prop-types": "*",
"@types/react": "*"
@ -9073,6 +9082,11 @@
"integrity": "sha1-l1+HwTLymdJKA3W59jyj+4j3Kzo=",
"dev": true
},
"clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -9974,9 +9988,9 @@
}
},
"date-arithmetic": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/date-arithmetic/-/date-arithmetic-3.1.0.tgz",
"integrity": "sha1-H80D29UEudvuK5B4yFpfHH08wtM="
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-arithmetic/-/date-arithmetic-4.1.0.tgz",
"integrity": "sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg=="
},
"dateformat": {
"version": "2.2.0",
@ -10287,11 +10301,19 @@
"dev": true
},
"dom-helpers": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz",
"integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==",
"requires": {
"@babel/runtime": "^7.1.2"
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
},
"dependencies": {
"csstype": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
}
}
},
"dom-serializer": {
@ -16244,6 +16266,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"lodash-es": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
},
"lodash._basecopy": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
@ -16634,9 +16661,9 @@
}
},
"memoize-one": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.0.3.tgz",
"integrity": "sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw=="
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
"integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
},
"memory-fs": {
"version": "0.4.1",
@ -18275,6 +18302,11 @@
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
"dev": true
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -19245,25 +19277,6 @@
"reflect.ownkeys": "^0.2.0"
}
},
"prop-types-extra": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz",
"integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==",
"requires": {
"react-is": "^16.3.2",
"warning": "^3.0.0"
},
"dependencies": {
"warning": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
"requires": {
"loose-envify": "^1.0.0"
}
}
}
},
"proxy-addr": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
@ -19496,29 +19509,21 @@
}
},
"react-big-calendar": {
"version": "0.20.4",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-0.20.4.tgz",
"integrity": "sha512-HABwo8jZCvKsbUOH5U8fgO6msSsl6dHgSDH//T5OCtvX+S0onFZg9kDbU82x2AtF7lx5s2vAJxGmEA3uPQr0Xg==",
"version": "0.24.6",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-0.24.6.tgz",
"integrity": "sha512-3t+FSqmaNQr3sAvOcIue+VmNjBV7PNOiGLUidwG0mN6LRPuprO8+poZBq3QM6OqZPu69HY50tCZN8P3BslRUbw==",
"requires": {
"@babel/runtime": "^7.1.5",
"classnames": "^2.2.6",
"date-arithmetic": "^3.0.0",
"dom-helpers": "^3.4.0",
"clsx": "^1.0.4",
"date-arithmetic": "^4.0.1",
"dom-helpers": "^5.1.0",
"invariant": "^2.2.4",
"lodash": "^4.17.11",
"memoize-one": "^4.0.3",
"lodash-es": "^4.17.11",
"memoize-one": "^5.1.1",
"prop-types": "^15.6.2",
"prop-types-extra": "^1.1.0",
"react-overlays": "^0.8.3",
"uncontrollable": "^6.0.0",
"warning": "^4.0.2"
},
"dependencies": {
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}
"react-overlays": "^2.0.0-0",
"uncontrollable": "^7.0.0"
}
},
"react-dom": {
@ -19555,26 +19560,17 @@
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-overlays": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz",
"integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-2.1.1.tgz",
"integrity": "sha512-gaQJwmb8Ij2IGVt4D1HmLtl4A0mDVYxlsv/8i0dHWK7Mw0kNat6ORelbbEWzaXTK1TqMeQtJw/jraL3WOADz3w==",
"requires": {
"classnames": "^2.2.5",
"dom-helpers": "^3.2.1",
"prop-types": "^15.5.10",
"prop-types-extra": "^1.0.1",
"react-transition-group": "^2.2.0",
"warning": "^3.0.0"
},
"dependencies": {
"warning": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
"requires": {
"loose-envify": "^1.0.0"
}
}
"@babel/runtime": "^7.4.5",
"@restart/hooks": "^0.3.12",
"dom-helpers": "^5.1.0",
"popper.js": "^1.15.0",
"prop-types": "^15.7.2",
"uncontrollable": "^7.0.0",
"warning": "^4.0.3"
}
},
"react-test-renderer": {
@ -19601,17 +19597,6 @@
}
}
},
"react-transition-group": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
"requires": {
"dom-helpers": "^3.4.0",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2",
"react-lifecycles-compat": "^3.0.4"
}
},
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
@ -22772,11 +22757,30 @@
"dev": true
},
"uncontrollable": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.1.0.tgz",
"integrity": "sha512-2TzEm0pLKauMBZfAZXsgQvLpZHEp95891frCZdGDrSG7dWYaIQhedwLAzi0X8pR8KHNqlmuYEb2cEgbQzr050A==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
"integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
"requires": {
"invariant": "^2.2.4"
"@babel/runtime": "^7.6.3",
"@types/react": "^16.9.11",
"invariant": "^2.2.4",
"react-lifecycles-compat": "^3.0.4"
},
"dependencies": {
"@types/react": {
"version": "16.9.53",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.53.tgz",
"integrity": "sha512-4nW60Sd4L7+WMXH1D6jCdVftuW7j4Za6zdp6tJ33Rqv0nk1ZAmQKML9ZLD4H0dehA3FZxXR/GM8gXplf82oNGw==",
"requires": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"csstype": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
}
}
},
"underscore": {

View File

@ -28,7 +28,7 @@
"@types/globalize": "0.0.34",
"@types/jquery": "^3.3.29",
"@types/react": "16.8.8",
"@types/react-big-calendar": "^0.20.13",
"@types/react-big-calendar": "^0.24.6",
"@types/react-dom": "16.8.3",
"@types/webpack-env": "1.13.1",
"@uifabric/fluent-theme": "^0.16.7",
@ -42,7 +42,7 @@
"moment": "^2.24.0",
"office-ui-fabric-react": "6.189.2",
"react": "16.8.5",
"react-big-calendar": "^0.20.4",
"react-big-calendar": "^0.24.6",
"react-dom": "16.8.5",
"react-draft-wysiwyg": "^1.13.2",
"spfx-uifabric-themes": "^0.6.0",

View File

@ -3,12 +3,16 @@ import styles from './Calendar.module.scss';
import { ICalendarProps } from './ICalendarProps';
import { ICalendarState } from './ICalendarState';
import { escape } from '@microsoft/sp-lodash-subset';
import BigCalendar from 'react-big-calendar';
//import BigCalendar from 'react-big-calendar';
import * as moment from 'moment';
import * as strings from 'CalendarWebPartStrings';
import 'react-big-calendar/lib/css/react-big-calendar.css';
require('./calendar.css');
import { CommunicationColors , FluentCustomizations, FluentTheme } from '@uifabric/fluent-theme';
//import CalendarToolbar from './CustomToolbar';
import Year from './Year';
import { Calendar as MyCalendar, momentLocalizer } from 'react-big-calendar';
import {
Customizer,
@ -52,9 +56,8 @@ import { IEventData } from './../../../services/IEventData';
import { IUserPermissions } from './../../../services/IUserPermissions';
const localizer = BigCalendar.momentLocalizer(moment);
//const localizer = BigCalendar.momentLocalizer(moment);
const localizer = momentLocalizer(moment);
/**
* @export
* @class Calendar
@ -311,7 +314,6 @@ export default class Calendar extends React.Component<ICalendarProps, ICalendarS
* @memberof Calendar
*/
public render(): React.ReactElement<ICalendarProps> {
return (
<Customizer {...FluentCustomizations}>
@ -340,7 +342,7 @@ export default class Calendar extends React.Component<ICalendarProps, ICalendarS
<div>
{this.state.isloading ? <Spinner size={SpinnerSize.large} label={strings.LoadingEventsLabel} /> :
<div className={styles.container}>
<BigCalendar
<MyCalendar
dayPropGetter = {this.dayPropGetter}
localizer={localizer}
selectable
@ -351,10 +353,16 @@ export default class Calendar extends React.Component<ICalendarProps, ICalendarS
onSelectSlot={this.onSelectSlot}
components={{
event: this.renderEvent
}}
onSelectEvent={this.onSelectEvent}
defaultDate={moment().startOf('day').toDate()}
views={{
day: true,
week: true,
month: true,
agenda: true,
work_week: Year
}}
messages={
{
'today': strings.todayLabel,
@ -363,7 +371,8 @@ export default class Calendar extends React.Component<ICalendarProps, ICalendarS
'month': strings.monthLabel,
'week': strings.weekLabel,
'day': strings.dayLable,
'showMore': total => `+${total} ${strings.showMore}`
'showMore': total => `+${total} ${strings.showMore}`,
'work_week': strings.yearHeaderLabel
}
}
/>

View File

@ -0,0 +1,68 @@
import * as React from 'react';
import { css } from 'office-ui-fabric-react';
import PropTypes from 'prop-types';
import { View, Views, Navigate, Messages } from "react-big-calendar";
import * as strings from 'CalendarWebPartStrings';
export interface ICustomToolbarProps {
date: Date;
view: View;
views: Views;
label: string;
localizer: { messages: Messages };
onNavigate: (navigate: Navigate, date?: Date) => void;
onView: (view: View) => void;
children?: React.ReactNode;
}
export interface ICustomToolbarState {
activeView: string;
}
export default class CalendarToolbar extends React.Component<ICustomToolbarProps, ICustomToolbarState> {
public constructor(props) {
super(props);
this.state = {
activeView: 'month'
};
}
public componentDidMount() {
const view = this.props.view;
console.log(view);
}
private navigate = (action) => {
this.props.onNavigate(action);
}
private view = (view) => {
this.props.onView(view);
this.setState({activeView: view});
}
public render() {
const {activeView} = this.state;
return (
<div className="rbc-toolbar">
<div className="rbc-btn-group">
<button type="button" onClick={() => this.navigate('TODAY')}>{strings.todayLabel}</button>
<button type="button" onClick={() => this.navigate('PREV')}>{strings.previousLabel}</button>
<button type="button" onClick={() => this.navigate('NEXT')}>{strings.nextLabel}</button>
</div>
<span className="rbc-toolbar-label">{this.props.label}</span>
<div className="rbc-btn-group">
<button type="button" className={css({ 'rbc-active': activeView === "month" })} onClick={() => this.view('month')}>{strings.monthLabel}</button>
<button type="button" className={css({ 'rbc-active': activeView === "week" })} onClick={() => this.view('week')}>{strings.weekLabel}</button>
<button type="button" className={css({ 'rbc-active': activeView === "day" })} onClick={() => this.view('day')}>{strings.dayLable}</button>
<button type="button" className={css({ 'rbc-active': activeView === "year" })} onClick={() => this.view('year')}>{strings.yearHeaderLabel}</button>
<button type="button" className={css({ 'rbc-active': activeView === "agenda" })} onClick={() => this.view('agenda')}>{strings.agenda}</button>
</div>
</div>
);
}
}

View File

@ -22,10 +22,10 @@ export default class CalendarToolbar extends Toolbar {
<button type="button" onClick={this.view.bind(null, 'month')}>{strings.monthLabel}</button>
<button type="button" onClick={this.view.bind(null, 'week')}>{strings.weekLabel}</button>
<button type="button" onClick={this.view.bind(null, 'day')}>{strings.dayLable}</button>
<button type="button" onClick={this.view.bind(null, 'year')}>{strings.yearHeaderlabel}</button>
<button type="button" onClick={this.view.bind(null, 'agenda')}>{strings.agenda}</button>
</div>
</div>
);
}
}
module.export = CalendarToolbar;

View File

@ -0,0 +1,49 @@
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
.year {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.month {
margin: 5px 5px 15px 5px;
}
.monthName {
color: $ms-color-themeDark;
font-weight: bold;
}
.day {
display: inline-block;
width: 30px;
height: 30px;
text-align: center;
line-height: 30px;
}
.date {
width: 30px;
height: 30px;
background: white;
border-radius: 50px;
border: none;
outline: none;
}
.date.inMonth:hover {
cursor: pointer;
background: $ms-color-themeDark;
color: white;
font-weight: bold;
}
.today {
background: $ms-color-themeDark;
}
.date.prevMonth,
.date.nextMonth {
color: grey;
}

View File

@ -0,0 +1,201 @@
import React from 'react';
import moment from 'moment';
import * as dates from 'date-arithmetic';
import styles from './Year.module.scss';
import { navigate } from 'react-big-calendar/lib/utils/constants';
import { css } from 'office-ui-fabric-react';
function createCalendar(currentDate) {
if (!currentDate) {
currentDate = moment();
} else {
currentDate = moment(currentDate);
}
const first = currentDate.clone().startOf('month');
const last = currentDate.clone().endOf('month');
const weeksCount = Math.ceil((first.day() + last.date()) / 7);
let calendar:any = [];
calendar.currentDate = currentDate;
calendar.last = last;
calendar.first = first;
for (let weekNumber = 0; weekNumber < weeksCount; weekNumber++) {
const week = [];
calendar.push(week);
calendar.year = currentDate.year();
calendar.month = currentDate.month();
for (let day = 7 * weekNumber; day < 7 * (weekNumber + 1); day++) {
const date = currentDate.clone().set('date', day + 1 - first.day());
date.calendar = calendar;
week.push(date);
}
}
return calendar;
}
function CalendarDate(props) {
const { dateToRender, dateOfMonth } = props;
const today =
dateToRender.format('YYYY-MM-DD') === moment().format('YYYY-MM-DD')
? 'today'
: '';
if (dateToRender.month() < dateOfMonth.month()) {
return (
<button disabled={true} className={css(styles.date, styles["prevMonth"])}>
{dateToRender.date()}
</button>
);
}
if (dateToRender.month() > dateOfMonth.month()) {
return (
<button disabled={true} className={css(styles.date, styles["nextMonth"])}>
{dateToRender.date()}
</button>
);
}
return (
<button
className={`${css(styles.date, styles.inMonth)} ${today}`}
onClick={(e) => props.onClick(e, dateToRender)}>
{dateToRender.date()}
</button>
);
}
export interface IYearCalendarProps {
date: Date;
onDrillDown: (date: any, view?: string) => void;
}
export interface IYearCalendarState {
calendar: any;
}
export interface ICalendar {
currentDate: any;
first: any;
last: any;
year: any;
month: any;
}
class YearCalendar extends React.Component<IYearCalendarProps, IYearCalendarState> {
public constructor(props) {
super(props);
this.state = {
calendar: undefined
};
this.openView = this.openView.bind(this);
}
public componentDidMount() {
this.setState({ calendar: createCalendar(this.props.date) });
}
public componentDidUpdate(prevProps) {
if (this.props.date !== prevProps.date) {
this.setState({ calendar: createCalendar(this.props.date) });
}
}
public render() {
if (!this.state.calendar) {
return null;
}
return (
<div className={styles.month}>
<div className={styles.monthName}>
{this.state.calendar.currentDate.format('MMMM').toUpperCase()}
</div>
{['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((day, index) => (
<span key={index} className={styles.day}>
{day}
</span>
))}
{this.state.calendar.map((week, index) => (
<div key={index}>
{week.map(date => (
<CalendarDate
key={date.date()}
dateToRender={date}
dateOfMonth={this.state.calendar.currentDate}
onClick={(e,obj) => {
this.openView(obj.toDate(), "day", e); //open day-view
}
}
/>
))}
</div>
))}
</div>
);
}
private openView = (date, view, e) => {
e.preventDefault();
this.props.onDrillDown(date, view);
}
}
export interface IYearProps {
date: string;
onDrillDown: (date: any, view?: string) => void;
}
class Year extends React.Component<IYearProps> {
private range = date => {
return [dates.startOf(date, 'year')];
}
public static navigate = (date, action) => {
switch (action) {
case navigate.PREVIOUS:
return dates.add(date, -1, 'year');
case navigate.NEXT:
return dates.add(date, 1, 'year');
default:
return date;
}
}
public static title = (date, calendar ) => {
return calendar.localizer.format(date, "YYYY");
}
private handleHeadingClick = (date, view) => {
this.props.onDrillDown(date, view);
}
public render() {
let { date, ...props } = this.props;
let range = this.range(date);
const months = [];
const firstMonth = dates.startOf(date, 'year');
for (let i = 0; i < 12; i++) {
months.push(
<YearCalendar
key={i + 1}
date={dates.add(firstMonth, i, 'month')}
onDrillDown={this.handleHeadingClick}
/>
);
}
return <div className={styles.year}>{months.map(month => month)}</div>;
}
}
export default Year;

View File

@ -108,6 +108,7 @@ define([], function () {
dayLable: "Day",
agenda: "Agenda",
monthLabel: "Month",
yearHeaderLabel: "Year",
todayLabel: "Today",
previousLabel: "Previous",
nextLabel: "Next",

View File

@ -104,6 +104,7 @@ declare interface ICalendarWebPartStrings {
DescriptionFieldLabel: string;
SiteUrlFieldLabel: string;
ListFieldLabel: string;
yearHeaderLabel: string;
monthLabel: string;
weekLabel: string;
dayLable: string;

View File

@ -14,6 +14,7 @@
"inlineSources": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"allowSyntheticDefaultImports":true,
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
@ -29,7 +30,8 @@
]
},
"include": [
"src/**/*.ts"
"src/**/*.ts",
"src/**/*.jsx"
],
"exclude": [
"node_modules",