diff --git a/.eslintrc.yml b/.eslintrc.yml index 1b462c1..21fff04 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -22,20 +22,16 @@ rules: camelcase: warn consistent-return: warn guard-for-in: warn - import/no-unresolved: warn import/prefer-default-export: warn no-mixed-operators: warn no-param-reassign: warn no-restricted-globals: warn no-restricted-syntax: warn - no-underscore-dangle: [error, allow: [__REDUX_DEVTOOLS_EXTENSION_COMPOSE__]] no-use-before-define: warn prefer-destructuring: warn react/forbid-prop-types: warn - react/jsx-filename-extension: warn react/jsx-no-target-blank: warn react/no-multi-comp: warn - react/no-unused-prop-types: warn react/no-unused-state: warn react/prefer-stateless-function: warn react/require-default-props: warn @@ -44,6 +40,7 @@ rules: # Intentional Airbnb exceptions: no-alert: off # currently used in the UI no-plusplus: [error, allowForLoopAfterthoughts: true] + no-underscore-dangle: [error, allow: [__REDUX_DEVTOOLS_EXTENSION_COMPOSE__]] # TODO: #118 accessibility jsx-a11y/anchor-is-valid: off diff --git a/src/components/date-time-selector.jsx b/src/components/date-time-selector.jsx index 6ff3021..0c5ebdd 100644 --- a/src/components/date-time-selector.jsx +++ b/src/components/date-time-selector.jsx @@ -1,10 +1,9 @@ // This component allows the user to select a single date and time -import InputMoment from 'input-moment'; import moment from 'moment'; import PropTypes from 'prop-types'; import * as React from 'react'; -import ReactDOM from 'react-dom'; +import PickerPopup from './picker-popup'; export default class DateTimeSelector extends React.Component { constructor(props) { @@ -84,66 +83,3 @@ DateTimeSelector.defaultProps = { buttonPrefix: '', datetime: moment(), }; - -class PickerPopup extends React.Component { - constructor(props) { - super(props); - - this.finishedLoading = false; - } - - componentWillMount() { - // Add event listener for clicks - document.addEventListener('click', this.handleClick, false); - } - - componentWillUnmount() { - // Remove event listener for clicks - document.removeEventListener('click', this.handleClick, false); - } - - handleClick = (e) => { - // Check if the user clicked outside the calendar selector - if (this.props.visible) { - if (this.finishedLoading) { - // Don't process the click triggering the display of this component - const node = ReactDOM.findDOMNode(this); - if (node !== null && !node.contains(e.target)) { - this.props.lostFocus(); - this.finishedLoading = false; - } - } else { - this.finishedLoading = true; - } - } else { - this.finishedLoading = false; - } - }; - - render() { - return this.props.visible ? ( - - ) : null; - } -} - -// Define React prop types for type checking during development -PickerPopup.propTypes = { - visible: PropTypes.bool, - lostFocus: PropTypes.func.isRequired, - moment: PropTypes.instanceOf(moment), - onChange: PropTypes.func.isRequired, - onSave: PropTypes.func.isRequired, - show: PropTypes.oneOf(['both', 'date', 'time']), -}; - -// Define default prop values -PickerPopup.defaultProps = { - visible: false, - moment: moment(), - show: 'both', -}; diff --git a/src/components/picker-popup.jsx b/src/components/picker-popup.jsx new file mode 100644 index 0000000..9f3040a --- /dev/null +++ b/src/components/picker-popup.jsx @@ -0,0 +1,68 @@ +import InputMoment from 'input-moment'; +import moment from 'moment'; +import PropTypes from 'prop-types'; +import * as React from 'react'; +import ReactDOM from 'react-dom'; + +class PickerPopup extends React.Component { + constructor(props) { + super(props); + + this.finishedLoading = false; + } + + componentWillMount() { + // Add event listener for clicks + document.addEventListener('click', this.handleClick, false); + } + + componentWillUnmount() { + // Remove event listener for clicks + document.removeEventListener('click', this.handleClick, false); + } + + handleClick = (e) => { + // Check if the user clicked outside the calendar selector + if (this.props.visible) { + if (this.finishedLoading) { + // Don't process the click triggering the display of this component + const node = ReactDOM.findDOMNode(this); + if (node !== null && !node.contains(e.target)) { + this.props.lostFocus(); + this.finishedLoading = false; + } + } else { + this.finishedLoading = true; + } + } else { + this.finishedLoading = false; + } + }; + + render() { + return this.props.visible ? ( + + ) : null; + } +} + +// Define React prop types for type checking during development +PickerPopup.propTypes = { + visible: PropTypes.bool, + lostFocus: PropTypes.func.isRequired, + moment: PropTypes.instanceOf(moment), + onChange: PropTypes.func.isRequired, + onSave: PropTypes.func.isRequired, + show: PropTypes.oneOf(['both', 'date', 'time']), +}; + +// Define default prop values +PickerPopup.defaultProps = { + visible: false, + moment: moment(), + show: 'both', +}; diff --git a/src/pages/add-edit/add-edit-page.jsx b/src/pages/add-edit/add-edit-page.jsx index babdf5a..1d6272a 100644 --- a/src/pages/add-edit/add-edit-page.jsx +++ b/src/pages/add-edit/add-edit-page.jsx @@ -98,6 +98,17 @@ export default class AddEditEventPage extends React.Component { this.props.clearCurrentEvent(); } + setStart = (start) => { + const timeDelta = start.diff(this.state.eventData.start); + this.updateEventDatum({ + start, + // Shift the end time to maintain the same duration + end: moment(this.state.eventData.end).add(timeDelta, 'ms'), + }); + }; + + setEnd = end => this.updateEventDatum({ end }); + validateInput = () => { if (this.state.eventData.title.length === 0) { alert('Event Title is required'); @@ -180,17 +191,6 @@ export default class AddEditEventPage extends React.Component { allDayToggled = e => this.updateEventDatum({ allDay: e.currentTarget.checked }); - setStart = (start) => { - const timeDelta = start.diff(this.state.eventData.start); - this.updateEventDatum({ - start, - // Shift the end time to maintain the same duration - end: moment(this.state.eventData.end).add(timeDelta, 'ms'), - }); - }; - - setEnd = end => this.updateEventDatum({ end }); - receivedSuccessfulSeriesDataResponse = (response) => { const seriesData = response.data; diff --git a/src/pages/add-edit/save-cancel-buttons.jsx b/src/pages/add-edit/save-cancel-buttons.jsx index d8c6370..548bacb 100644 --- a/src/pages/add-edit/save-cancel-buttons.jsx +++ b/src/pages/add-edit/save-cancel-buttons.jsx @@ -2,23 +2,24 @@ import * as React from 'react'; -export default class SaveCancelButtons extends React.Component { - render() { - // Only render delete button if we're supposed to - const deleteButton = this.props.showDelete && ( - ); - return ( -
- {deleteButton} - - -
- ); - } -} +const SaveCancelButtons = (props) => { + // Only render delete button if we're supposed to + const deleteButton = props.showDelete && ( + + ); + return ( +
+ {deleteButton} + + +
+ ); +}; + +export default SaveCancelButtons; diff --git a/src/sidebar/event-actions-pane.jsx b/src/sidebar/event-actions-pane.jsx index 295d77a..e143772 100644 --- a/src/sidebar/event-actions-pane.jsx +++ b/src/sidebar/event-actions-pane.jsx @@ -2,21 +2,25 @@ import React from 'react'; -export default class EventActionsPane extends React.Component { - render() { - if (!this.props.currentEvent) return null; +const EventActionsPane = (props) => { + if (!props.currentEvent) return null; - const editRecurrence = this.props.currentEvent.recId ? ( - - ) : null; - const mainEditButtonText = this.props.currentEvent.recId ? 'Edit Recurrence' : 'Edit Event'; + const editRecurrence = props.currentEvent.recId ? ( + + ) : null; + const mainEditButtonText = props.currentEvent.recId ? 'Edit Recurrence' : 'Edit Event'; - return ( -
- {editRecurrence} - - {/* */} -
- ); - } -} + return ( +
+ {editRecurrence} + + {/* */} +
+ ); +}; + +export default EventActionsPane; diff --git a/src/sidebar/footer.jsx b/src/sidebar/footer.jsx index 59ca3cf..3d514fd 100644 --- a/src/sidebar/footer.jsx +++ b/src/sidebar/footer.jsx @@ -2,25 +2,26 @@ import * as React from 'react'; -export default class Footer extends React.Component { - render() { - return ( - - ); - } -} +const Footer = _props => ( + +); + +export default Footer; diff --git a/src/sidebar/markdown-guide.jsx b/src/sidebar/markdown-guide.jsx index 1de1188..60a1612 100644 --- a/src/sidebar/markdown-guide.jsx +++ b/src/sidebar/markdown-guide.jsx @@ -2,73 +2,73 @@ import React from 'react'; -export default class MarkdownGuide extends React.Component { - render() { - return ( -
- {/* Markdown Guide */} -
-
- Links -

[link text](url)

-

[url]

-
-
- Headers -

# big header

-

## smaller header

-

- And so on, adding more hashes to make the header smaller.
- Don’t forget the space between the hash and the text. +const MarkdownGuide = _props => ( +

+ {/* Markdown Guide */} +
+
+ Links +

[link text](url)

+

[url]

+
+
+ Headers +

# big header

+

## smaller header

+

+ And so on, adding more hashes to make the header smaller.
+ Don’t forget the space between the hash and the text. +

+
+
+ Emphasis +

*italic*

+

**bold**

+

***bold and italic***

+
+
+ Images +

![mouse hover text](url_to_image)

+

+ Currently images must be hosted elsewhere. If you need to upload your photo somewhere, put + it on Google Drive or Dropbox and use the public link to the file. +

+
+
+ Lists +

+ Indent each list item with two spaces, followed by an asterisk, number, + or letter, and then another space. +

+
+
+ Bulletted +

+   * List item
+   * List item
+   * List item

-
- Emphasis -

*italic*

-

**bold**

-

***bold and italic***

-
-
- Images -

![mouse hover text](url_to_image)

-

Currently images must be hosted elsewhere. If you need to upload your photo somewhere, - put it on Google Drive or Dropbox and use the public link to the file. +

+ Numbered +

+   1 List item
+   2 List item
+   3 List item

-
- Lists -

Indent each list item with two spaces, followed by an asterisk, number, or - letter, and then another space. +

+ Lettered +

+   a List item
+   b List item
+   c List item

-
-
- Bulletted -

-   * List item
-   * List item
-   * List item -

-
-
- Numbered -

-   1 List item
-   2 List item
-   3 List item -

-
-
- Lettered -

-   a List item
-   b List item
-   c List item -

-
-
- ); - } -} +
+
+); + +export default MarkdownGuide;