Skip to content

Commit

Permalink
[SDESK-1172] Repeat summary for recurring events (#190)
Browse files Browse the repository at this point in the history
[SDESK-1172] Test case fix

[SDESK-1172] Changes after review
  • Loading branch information
nrvikas authored and vied12 committed May 8, 2017
1 parent 1811ae9 commit 83e65f0
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 5 deletions.
132 changes: 132 additions & 0 deletions client/components/RepeatEventSummary/_test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from 'react'
import { mount } from 'enzyme'
import { RepeatEventSummary } from './index'
import moment from 'moment'

class TestForm extends React.Component {
render() {
const { byDay, interval, frequency, endRepeatMode, until, count, startDate } = this.props
return (
<RepeatEventSummary byDay={byDay}
interval={interval}
frequency={frequency}
endRepeatMode={endRepeatMode}
until={until}
count={count}
startDate={startDate} />
)
}
}

TestForm.propTypes = {
byDay: React.PropTypes.string,
interval: React.PropTypes.number,
frequency: React.PropTypes.string,
endRepeatMode: React.PropTypes.string,
until: React.PropTypes.object,
count: React.PropTypes.string,
startDate: React.PropTypes.object,
}

describe('<RepeatEventSummary />', () => {
const event = {
_id: '5800d71930627218866f1e80',
dates: {
start: moment('2016-10-15T14:30+0000'),
end: moment('2016-10-20T15:00+0000'),
},
definition_short: 'definition_short 1',
location: [{ name: 'location1' }],
name: 'name1',
files: [{
media: {
name: 'file.pdf',
length: 1000,
},
filemeta: { media_id: 'media1' },
}],
links: ['http://www.google.com'],
_plannings: [],
}

const mountForm = (recEvent) => {
const { byday, interval, frequency, endRepeatMode, until, count } =
recEvent.dates.recurring_rule
return (
mount(<TestForm byDay={byday}
interval={interval}
frequency={frequency}
endRepeatMode={endRepeatMode}
until={until}
count={count}
startDate={recEvent.dates.start} />)
)
}

it('Shows appropriate repeat summary for a given frequency with intervals', () => {
const recEvent = {
...event,
dates: {
start: moment('2016-10-15T14:30+0000'),
end: moment('2016-10-20T15:00+0000'),
recurring_rule: {
frequency: 'MONTHLY',
interval: '3',
},
},
}
let wrapper = mountForm(recEvent)
expect(wrapper.find('.repeatSummary').text()).toBe('Repeat summary: Every 3 months on day 15')
})
it('Shows appropriate repeat summary for a given frequency with intervals and until a date', () => {
const recEvent = {
...event,
dates: {
start: moment('2016-10-15T14:30+0000'),
end: moment('2016-10-20T15:00+0000' ),
recurring_rule: {
endRepeatMode: 'until',
frequency: 'DAILY',
interval: '3',
until: moment('2020-07-01T00:00'),
},
},
}
let wrapper = mountForm(recEvent)
expect(wrapper.find('.repeatSummary').text()).toBe('Repeat summary: Every 3 days, until 1 Jul 2020')
})
it('Shows appropriate repeat summary for a given frequency with intervals and for a number of occurances', () => {
const recEvent = {
...event,
dates: {
start: moment('2016-10-15T14:30+0000'),
end: moment('2016-10-20T15:00+0000'),
recurring_rule: {
endRepeatMode: 'count',
frequency: 'DAILY',
interval: '3',
count: '9',
},
},
}
let wrapper = mountForm(recEvent)
expect(wrapper.find('.repeatSummary').text()).toBe('Repeat summary: Every 3 days, 9 times')
})
it('Shows appropriate repeat summary for a given weekly frequency with intervals and by days', () => {
const recEvent = {
...event,
dates: {
start: moment('2016-10-15T14:30+0000'),
end: moment('2016-10-20T15:00+0000'),
recurring_rule: {
frequency: 'WEEKLY',
interval: '3',
byday: 'TH FR',
},
},
}
let wrapper = mountForm(recEvent)
expect(wrapper.find('.repeatSummary').text()).toBe('Repeat summary: Every 3 weeks on Thursday, Friday')
})

})
100 changes: 100 additions & 0 deletions client/components/RepeatEventSummary/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react'

export class RepeatEventSummary extends React.Component {
constructor(props) {
super(props)
}

getDaysFromByDays() {
let byDays = this.props.byDay && this.props.byDay.length > 0 ? this.props.byDay :
this.props.startDate ? this.props.startDate.format('dd').toUpperCase() : ''

if (byDays) {
const days = {
'MO': 'Monday',
'TU': 'Tuesday',
'WE': 'Wednesday',
'TH': 'Thursday',
'FR': 'Friday',
'SA': 'Saturday',
'SU': 'Sunday',
}

let dayNames = []

byDays.split(' ').forEach((day) => {
dayNames.push(days[day])
})
return dayNames
}
}

getPrefix() {
let prefix = ''
if (this.props.interval > 1) {
const duration = this.props.frequency === 'DAILY' ? 'days' :
this.props.frequency.replace('LY', 's').toLowerCase()
prefix = 'Every ' + this.props.interval + ' ' + duration
} else {
if (this.props.frequency) {
const f = this.props.frequency
prefix = f === 'YEARLY' ? 'Annualy' : (f.charAt(0).toUpperCase() + f.slice(1).toLowerCase())
}
}
return prefix
}

getStemText() {
let stemText = ''
const days = this.getDaysFromByDays()
switch(this.props.frequency) {
case 'WEEKLY':
stemText = days && days.length > 0 ? ('on ' + days.join(', ')) : ''
break
case 'MONTHLY':
stemText = this.props.startDate ? ('on day ' + this.props.startDate.format('D')) : ''
break
case 'YEARLY':
stemText = this.props.startDate ? ('on ' + this.props.startDate.format('MMM D')) : ''
break
}
return stemText
}

getSuffix() {
let suffix = ''
if (this.props.endRepeatMode !== 'unlimited') {
if (this.props.endRepeatMode === 'count' && parseInt(this.props.count) > 0) {
suffix = ', ' + this.props.count + ' times'
} else if (this.props.endRepeatMode === 'until' && this.props.until &&
this.props.until.isValid()) {
suffix = ', until ' + this.props.until.format('D MMM YYYY')
}
}
return suffix
}

getRepeatSummary() {
const stemText = this.getStemText()
return this.getPrefix() + (stemText !== '' ? ( ' ' + stemText ) : '') + this.getSuffix()
}

render() {
return (
<div>
<span><strong className='repeatSummary'>{'Repeat summary: ' + this.getRepeatSummary()}</strong>
</span>
</div>
)
}
}

RepeatEventSummary.propTypes = {
byDay: React.PropTypes.string,
interval: React.PropTypes.string,
frequency: React.PropTypes.string,
endRepeatMode: React.PropTypes.string,
until: React.PropTypes.object,
count: React.PropTypes.string,
startDate: React.PropTypes.object,
}
1 change: 1 addition & 0 deletions client/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ import * as fields from './fields'
export { fields }
import * as tooltips from './Tooltips'
export { tooltips }
export { RepeatEventSummary } from './RepeatEventSummary/index'
55 changes: 50 additions & 5 deletions client/containers/RepeatEventForm.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
import React, { PropTypes } from 'react'
import { Field, formValueSelector } from 'redux-form'
import { fields } from '../components'
import { fields, RepeatEventSummary } from '../components'
import { connect } from 'react-redux'

class RepeatEventFormComponent extends React.Component {

constructor(props) {
super(props)
const { endRepeatMode } = props
}

componentWillMount() {
const { endRepeatMode, frequency, interval, start } = this.props

const intervals = interval || 1
const startDate = start || null

if (endRepeatMode) {
this.state = { endRepeatMode: endRepeatMode }
this.state = {
endRepeatMode: endRepeatMode,
interval: intervals,
frequency: frequency,
date: startDate,
}
} else {
// if endRepeatMode not present set the default value for it
this.state = { endRepeatMode: 'unlimited' }
this.state = {
endRepeatMode: 'unlimited',
interval: intervals,
frequency: frequency,
date: startDate,
}
this.props.change('dates.recurring_rule.endRepeatMode', 'unlimited')
}
}

componentWillReceiveProps(nextProps) {
const { endRepeatMode, until, count } = nextProps
const { endRepeatMode, until, count, frequency, start, interval } = nextProps

if (until && endRepeatMode != 'until') {
// force the selection of 'until' for endRepeatMode
Expand All @@ -41,6 +57,22 @@ class RepeatEventFormComponent extends React.Component {

if (endRepeatMode && endRepeatMode !== this.state.endRepeatMode) {
this.setState({ endRepeatMode: endRepeatMode })
return
}

if (frequency !== this.props.frequency) {
this.setState({ frequency: frequency })
return
}

if (start !== this.props.start) {
this.setState({ date: start })
return
}

if (interval !== this.props.interval) {
this.setState({ interval: interval })
return
}
}

Expand Down Expand Up @@ -138,6 +170,13 @@ class RepeatEventFormComponent extends React.Component {
ref="recurring_rule--until"
component={fields.DayPickerInput} />
</label>
<RepeatEventSummary byDay={this.props.byDay}
interval={this.state.interval}
frequency={this.props.frequency}
endRepeatMode={this.state.endRepeatMode}
until={this.props.until}
count={this.props.count}
startDate={this.props.start} />
</div>
</div>
)
Expand All @@ -149,6 +188,9 @@ RepeatEventFormComponent.propTypes = {
endRepeatMode: PropTypes.oneOf(['unlimited', 'count', 'until']),
until: PropTypes.object,
count: PropTypes.string,
byDay: PropTypes.string,
start: PropTypes.object,
interval: PropTypes.string,
}

// This is the same name defined in EventForm.jsx because it is just a sub form
Expand All @@ -158,6 +200,9 @@ const mapStateToProps = (state) => ({
endRepeatMode: selector(state, 'dates.recurring_rule.endRepeatMode'),
until: selector(state, 'dates.recurring_rule.until'),
count: selector(state, 'dates.recurring_rule.count'),
byDay: selector(state, 'dates.recurring_rule.byday'),
start: selector(state, 'dates.start'),
interval: selector(state, 'dates.recurring_rule.interval'),
})

export const RepeatEventForm = connect(mapStateToProps)(RepeatEventFormComponent)

0 comments on commit 83e65f0

Please sign in to comment.