Skip to content

Commit

Permalink
Add resource
Browse files Browse the repository at this point in the history
  • Loading branch information
TeaBough committed Jun 2, 2017
1 parent 04f1fc7 commit 85918f2
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 16 deletions.
5 changes: 5 additions & 0 deletions src/Calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ class Calendar extends React.Component {
*/
events: PropTypes.arrayOf(PropTypes.object),

/**
* An array of resource objects that map events to a specific resource
*/
resources: PropTypes.arrayOf(PropTypes.object),

/**
* Callback fired when the `date` value changes.
*
Expand Down
2 changes: 2 additions & 0 deletions src/DayColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class DaySlot extends React.Component {
dayWrapperComponent: elementType,
eventComponent: elementType,
eventWrapperComponent: elementType.isRequired,
resource: React.PropTypes.string
};

static defaultProps = { dragThroughEvents: true };
Expand Down Expand Up @@ -299,6 +300,7 @@ class DaySlot extends React.Component {
slots,
start: startDate,
end: endDate,
resourceId: this.props.resource,
action
})
};
Expand Down
8 changes: 5 additions & 3 deletions src/TimeColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class TimeColumn extends Component {
timeGutterFormat: PropTypes.string,
type: PropTypes.string.isRequired,
className: PropTypes.string,
resource: PropTypes.string,

dayWrapperComponent: elementType,
}
Expand All @@ -31,7 +32,7 @@ export default class TimeColumn extends Component {
dayWrapperComponent: BackgroundWrapper,
}

renderTimeSliceGroup(key, isNow, date) {
renderTimeSliceGroup(key, isNow, date, resource) {
const { dayWrapperComponent, timeslots, showLabels, step, timeGutterFormat, culture } = this.props;

return (
Expand All @@ -42,6 +43,7 @@ export default class TimeColumn extends Component {
step={step}
culture={culture}
timeslots={timeslots}
resource={resource}
showLabels={showLabels}
timeGutterFormat={timeGutterFormat}
dayWrapperComponent={dayWrapperComponent}
Expand All @@ -50,7 +52,7 @@ export default class TimeColumn extends Component {
}

render() {
const { className, children, style, now, min, max, step, timeslots } = this.props;
const { className, children, style, now, min, max, step, timeslots, resource } = this.props;
const totalMin = dates.diff(min, max, 'minutes')
const numGroups = Math.ceil(totalMin / (step * timeslots))
const renderedSlots = []
Expand All @@ -69,7 +71,7 @@ export default class TimeColumn extends Component {
)

next = dates.add(date, groupLengthInMinutes, 'minutes');
renderedSlots.push(this.renderTimeSliceGroup(i, isNow, date))
renderedSlots.push(this.renderTimeSliceGroup(i, isNow, date, resource))

date = next
}
Expand Down
83 changes: 77 additions & 6 deletions src/TimeGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default class TimeGrid extends Component {

static propTypes = {
events: PropTypes.array.isRequired,
resources: PropTypes.array,

step: PropTypes.number,
range: PropTypes.arrayOf(
Expand Down Expand Up @@ -141,6 +142,7 @@ export default class TimeGrid extends Component {
, width
, startAccessor
, endAccessor
, resources
, allDayAccessor } = this.props;

width = width || this.state.gutterWidth;
Expand Down Expand Up @@ -174,10 +176,14 @@ export default class TimeGrid extends Component {

let gutterRef = ref => this._gutters[1] = ref && findDOMNode(ref);

let eventsRendered = resources ?
this.renderEventsWithResource(range, rangeEvents, this.props.now, resources) :
this.renderEvents(range, rangeEvents, this.props.now);

return (
<div className='rbc-time-view'>

{this.renderHeader(range, allDayEvents, width)}
{this.renderHeader(range, allDayEvents, width, resources)}

<div ref='content' className='rbc-time-content'>
<div ref='timeIndicator' className='rbc-current-time-indicator' />
Expand All @@ -189,22 +195,55 @@ export default class TimeGrid extends Component {
ref={gutterRef}
className='rbc-time-gutter'
/>

{this.renderEvents(range, rangeEvents, this.props.now)}
{eventsRendered}

</div>
</div>
);
}
renderEventsWithResource(range, events, today, resources) {
let { min, max, endAccessor, startAccessor, components } = this.props;

return range.map((date, idx) => {
let daysEvents = events.filter(
event => dates.inRange(date,
get(event, startAccessor),
get(event, endAccessor), 'day')
)

return resources.map((resource, id) => {

let eventsToDisplay = daysEvents.filter(
event => event.resourceId === resource.id
)

return (
<DayColumn
{...this.props }
min={dates.merge(date, min)}
max={dates.merge(date, max)}
eventComponent={components.event}
eventWrapperComponent={components.eventWrapper}
dayWrapperComponent={components.dayWrapper}
className={cn({ 'rbc-now': dates.eq(date, today, 'day') })}
style={segStyle(1, this.slots)}
key={idx + '-' + id}
date={date}
events={eventsToDisplay}
/>
)
})
})
}

renderEvents(range, events, today){
renderEvents(range, events, today, id){
let { min, max, endAccessor, startAccessor, components } = this.props;

return range.map((date, idx) => {
let daysEvents = events.filter(
event => dates.inRange(date,
get(event, startAccessor),
get(event, endAccessor), 'day')
get(event, endAccessor), 'day') && event.resourceId === id
)

return (
Expand All @@ -225,14 +264,18 @@ export default class TimeGrid extends Component {
})
}

renderHeader(range, events, width) {
renderHeader(range, events, width, resources) {
let { messages, rtl, selectable, components, now } = this.props;
let { isOverflowing } = this.state || {};

let style = {};
if (isOverflowing)
style[rtl ? 'marginLeft' : 'marginRight'] = scrollbarSize() + 'px';

let headerRendered = resources ?
this.renderHeaderResources(range, resources) :
message(messages).allDay;

return (
<div
ref='headerCell'
Expand All @@ -249,6 +292,13 @@ export default class TimeGrid extends Component {
/>
{ this.renderHeaderCells(range) }
</div>
{ resources && <div className='rbc-row rbc-row-resource'>
<div
className='rbc-label rbc-header-gutter'
style={{ width }}
/>
{ headerRendered }
</div> }
<div className='rbc-row'>
<div
ref={ref => this._gutters[0] = ref}
Expand Down Expand Up @@ -282,6 +332,27 @@ export default class TimeGrid extends Component {
)
}

renderHeaderResources(range, resources) {
return range.map((date, i) => {
return resources.map((resource, j) => {
return (
<div
key={i+ '-' + j}
className={cn(
'rbc-header',
dates.isToday(date) && 'rbc-today',
)}
style={segStyle(1, this.slots)}
>
<span>
{resource.title}
</span>
</div>
)
})
})
}

renderHeaderCells(range){
let { dayFormat, culture, components, getDrilldownView } = this.props;
let HeaderComponent = components.header || Header
Expand Down
7 changes: 4 additions & 3 deletions src/TimeSlot.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export default class TimeSlot extends Component {
isNow: PropTypes.bool,
showLabel: PropTypes.bool,
content: PropTypes.string,
culture: PropTypes.string
culture: PropTypes.string,
resource: PropTypes.string
}

static defaultProps = {
Expand All @@ -21,11 +22,11 @@ export default class TimeSlot extends Component {
}

render() {
const { value } = this.props;
const { value, resource } = this.props;
const Wrapper = this.props.dayWrapperComponent;

return (
<Wrapper value={value}>
<Wrapper value={value} resource={resource}>
<div
className={cn(
'rbc-time-slot',
Expand Down
5 changes: 3 additions & 2 deletions src/TimeSlotGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export default class TimeSlotGroup extends Component {
showLabels: PropTypes.bool,
isNow: PropTypes.bool,
timeGutterFormat: PropTypes.string,
culture: PropTypes.string
culture: PropTypes.string,
resource: PropTypes.string
}
static defaultProps = {
timeslots: 2,
Expand All @@ -24,7 +25,7 @@ export default class TimeSlotGroup extends Component {
}

renderSlice(slotNumber, content, value) {
const { dayWrapperComponent, showLabels, isNow, culture } = this.props;
const { dayWrapperComponent, showLabels, isNow, culture, resource } = this.props;
return (
<TimeSlot
key={slotNumber}
Expand Down
5 changes: 3 additions & 2 deletions src/addons/dragAndDrop/backgroundWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ function createWrapper(type) {
const dropTarget = {
drop(_, monitor, { props, context }) {
const event = monitor.getItem();
const { value } = props
const { value, resource } = props
const { onEventDrop, startAccessor, endAccessor } = context
const start = get(event, startAccessor);
const end = get(event, endAccessor);

onEventDrop({
event,
...getEventTimes(start, end, value, type)
...getEventTimes(start, end, value, type),
...resource && {resource}
})
}
};
Expand Down
4 changes: 4 additions & 0 deletions src/less/time-grid.less
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
border-bottom: 1px solid @cell-border;
}

> .rbc-row.rbc-row-resource {
border-bottom: 1px solid @cell-border;
}

.rbc-gutter-cell {
flex: none;
}
Expand Down
31 changes: 31 additions & 0 deletions stories/Calendar.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { storiesOf, action } from '@kadira/storybook';
import moment from 'moment';
import React from 'react';
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext } from 'react-dnd';

import Calendar from '../src';
import momentLocalizer from '../src/localizers/moment.js'
import '../src/less/styles.less'
import '../src/addons/dragAndDrop/styles.less'
import demoEvents from '../examples/events';
import createEvents from './createEvents';
import resources from './resourceEvents';
import withDragAndDrop from '../src/addons/dragAndDrop';

// Setup the localizer by providing the moment (or globalize) Object
// to the correct localizer.
Expand Down Expand Up @@ -38,6 +43,25 @@ const events = [{
allDay: true
}]

const DragAndDropCalendar = withDragAndDrop(Calendar)

const DragCalendar = () => {
return (
<DragAndDropCalendar
popup
selectable
events={resources.events}
resources={resources.list}
onEventDrop={(event) => { action(event) }}
onSelectEvent={action('event selected')}
onSelectSlot={action('slot selected')}
defaultDate={new Date(2015, 3, 1)}
/>
)
}

const DragableCalendar = DragDropContext(HTML5Backend)(DragCalendar)

storiesOf('module.Calendar.week', module)
.add('demo', () => {
return (
Expand Down Expand Up @@ -78,6 +102,13 @@ storiesOf('module.Calendar.week', module)
</div>
)
})
.add('resource', () => {
return (
<div style={{height: 500}}>
<DragableCalendar />
</div>
)
})

.add('selectable', () => {
return (
Expand Down
43 changes: 43 additions & 0 deletions stories/resourceEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export default {
events: [ {
'title': 'Rencontre',
'resourceId': 'a',
'start': new Date(2015, 3, 2, 5, 30, 0, 0),
'end': new Date(2015, 3, 2, 10, 30, 0, 0),
}, {
'title': 'Another Meeting',
'resourceId': 'b',
'start': new Date(2015, 3, 1, 2, 30, 0, 0),
'end': new Date(2015, 3, 1, 4, 30, 0, 0),
},
{
'title': 'A',
'resourceId': 'a',
'start': new Date(2015, 3, 4, 5, 30, 0, 0),
'end': new Date(2015, 3, 4, 10, 30, 0, 0),
},
{
'title': 'B',
'resourceId': 'b',
'start': new Date(2015, 3, 4, 5, 30, 0, 0),
'end': new Date(2015, 3, 4, 10, 30, 0, 0),
},
{
'title': 'C',
'resourceId': 'c',
'start': new Date(2015, 3, 4, 5, 30, 0, 0),
'end': new Date(2015, 3, 4, 10, 30, 0, 0),
}
],

list: [{
id: 'a',
title: 'Room A'
}, {
id: 'b',
title: 'Room B'
}, {
id: 'c',
title: 'Room C'
}]
}

0 comments on commit 85918f2

Please sign in to comment.