Skip to content
This repository has been archived by the owner on Sep 5, 2019. It is now read-only.

Commit

Permalink
Adds a shortcut to create reservation n with the start/end of reserva…
Browse files Browse the repository at this point in the history
…tion n - 1.

Resolves #205
  • Loading branch information
Denis Krienbühl committed Jun 2, 2016
1 parent d0769c9 commit 9072fa5
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 12 deletions.
3 changes: 3 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Changelog
---------

- Adds a shortcut to create reservation n with the start/end of reservation n - 1.
[href]

- Always select the first field when opening a reservation popup.
[href]

Expand Down
78 changes: 72 additions & 6 deletions onegov/town/assets/js/reservationcalendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ rc.showActionsPopup = function(calendar, element, event) {
$(event.actions.join('')).appendTo(wrapper);
}

ReservationForm.render(reservation.get(0), event, function(state) {
ReservationForm.render(reservation.get(0), event, rc.previousReservationState, function(state) {
var url = new Url(event.reserveurl);
url.query.start = state.start;
url.query.end = state.end;
Expand Down Expand Up @@ -344,7 +344,7 @@ rc.onPopupOpen = function(calendar) {
popup.addClass(className);
});

var links = popup.find('a');
var links = popup.find('a:not(.internal)');

// hookup all links with intercool
links.each(function(_ix, link) {
Expand Down Expand Up @@ -453,13 +453,36 @@ rc.setupReservationSelect = function(fcOptions) {
calendar.on('rc-reservations-changed', function() {
$.getJSON(fcOptions.reservations + '&ie-cache=' + (new Date()).getTime(), function(reservations) {
ReservationSelection.render(selection.get(0), calendar, reservations, fcOptions.reservationform);
rc.loadPreviousReservationState(reservations);
});
});

calendar.trigger('rc-reservations-changed');
});
};

// takes the loaded reservations and deduces the previous state from them
rc.loadPreviousReservationState = function(reservations) {
if (reservations.length > 0) {
reservations = _.sortBy(reservations, function(reservation) {
return reservation.created;
});

for (var i = reservations.length - 1; i >= 0; i--) {
if (reservations[i].time.match(/^\d{2}:\d{2} - \d{2}:\d{2}$/)) {
rc.previousReservationState = {
'start': reservations[i].time.split(' - ')[0],
'end': reservations[i].time.split(' - ')[1]
};

break;
}
}
} else {
rc.previousReservationState = {};
}
};

// renders the occupied partitions on an event
rc.renderPartitions = function(event, element, calendar) {

Expand Down Expand Up @@ -741,6 +764,28 @@ ReservationForm = React.createClass({

e.preventDefault();
},
handleSetPreviousTime: function(e) {
var previousState = this.props.previousReservationState;
var node = $(this.getDOMNode());
var inputs = node.find('[name="start"],[name="end"]');

$(inputs[0]).val(previousState.start);
$(inputs[1]).val(previousState.end);

// briefly highlight the inputs
inputs.addClass('highlighted');
setTimeout(function() {
inputs.removeClass('highlighted');
}, 500);

var state = _.extend({}, this.state);
state.start = previousState.start;
state.end = previousState.end;

this.setState(state);

e.preventDefault();
},
handleTimeInputFocus: function(e) {
if (!Modernizr.inputtypes.time) {
e.target.select();
Expand Down Expand Up @@ -822,10 +867,21 @@ ReservationForm = React.createClass({
},
render: function() {
var buttonEnabled = this.isValidState();
var showWholeDay = this.props.partlyAvailable && this.props.wholeDay;
var showTimeRange = this.props.partlyAvailable && (!this.props.wholeDay || !this.state.wholeDay);

var showPreviousTime = showTimeRange &&
!_.isEmpty(this.props.previousReservationState) &&
(
this.props.previousReservationState.start !== this.state.start ||
this.props.previousReservationState.end !== this.state.end
);

var showQuota = !this.props.partlyAvailable;

return (
<form>
{this.props.partlyAvailable && this.props.wholeDay && (
{showWholeDay && (
<div className="field">
<span className="label-text">{locale("Whole day")}</span>

Expand All @@ -848,7 +904,7 @@ ReservationForm = React.createClass({
</div>
)}

{this.props.partlyAvailable && (!this.props.wholeDay || !this.state.wholeDay) && (
{showTimeRange && (
<div className="field split">
<div>
<label htmlFor="start">{locale("From")}</label>
Expand All @@ -874,7 +930,16 @@ ReservationForm = React.createClass({
</div>
</div>
)}
{!this.props.partlyAvailable && (

{showPreviousTime && (
<a href="#" onClick={this.handleSetPreviousTime} className="select-previous-time internal">
<span>{this.props.previousReservationState.start}</span>
<i className="fa fa-chevron-circle-up" aria-hidden="true"></i>
<span>{this.props.previousReservationState.end}</span>
</a>
)}

{showQuota && (
<div className="field">
<div>
<label htmlFor="count">{locale("Count")}</label>
Expand All @@ -894,7 +959,7 @@ ReservationForm = React.createClass({
}
});

ReservationForm.render = function(element, event, onSubmit) {
ReservationForm.render = function(element, event, previousReservationState, onSubmit) {

var fullyAvailable = event.partitions.length === 1 && event.partitions[0][1] === false;

Expand All @@ -907,6 +972,7 @@ ReservationForm.render = function(element, event, onSubmit) {
end={event.end}
wholeDay={event.wholeDay}
fullyAvailable={fullyAvailable}
previousReservationState={previousReservationState}
onSubmit={onSubmit}
/>,
element);
Expand Down
4 changes: 4 additions & 0 deletions onegov/town/models/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
CoordinatesExtension
)
from sqlalchemy.sql.expression import cast
from sqlalchemy.orm import undefer
from uuid import uuid4, uuid5


Expand Down Expand Up @@ -81,6 +82,9 @@ def bound_reservations(self, request, status='pending'):
res = res.order_by(False) # clear existing order
res = res.order_by(Reservation.start)

# used by ReservationInfo
res = res.options(undefer(Reservation.created))

return res

def bound_session_id(self, request):
Expand Down
2 changes: 1 addition & 1 deletion onegov/town/templates/macros.pt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<button href="#" data-dropdown="${dropdown_id}" class="${group.right_side and 'right-side'} tiny button dropdown">
${group.title}
</button>
<ul id="${dropdown_id}" data-dropdown-content class="f-dropdown">
<ul id="${dropdown_id}" data-dropdown-content class="f-dropdown disable-scroll">
<li tal:repeat="link group.links">
<tal:block replace="structure link(request)" />
</li>
Expand Down
28 changes: 25 additions & 3 deletions onegov/town/theme/styles/town.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1848,9 +1848,31 @@ button {
/*
Reservations Form
*/
.reservation-form h2 {
font-size: $h3-font-size - $h3-font-reduction;
font-weight: bold;
.reservation-form {
h2 {
font-size: $h3-font-size - $h3-font-reduction;
font-weight: bold;
}

input.highlighted {
background-color: $yellow-pastel;
}

.select-previous-time {
padding-bottom: 1px;
padding-top: 5px;
text-align: center;

&:hover {
font-weight: bold;
text-decoration: none;
}

i {
display: inline-block;
padding: .75ex;
}
}
}

/*
Expand Down
3 changes: 2 additions & 1 deletion onegov/town/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ def as_dict(self):
'date': self.date,
'time': self.time,
'delete': self.delete_link,
'quota': self.reservation.quota
'quota': self.reservation.quota,
'created': self.reservation.created.isoformat()
}


Expand Down
2 changes: 1 addition & 1 deletion onegov/town/views/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def handle_cleanup_allocations(self, request, form):
def get_reservations(self, request):
return [
utils.ReservationInfo(reservation, request).as_dict() for reservation
in self.bound_reservations(request)
in self.bound_reservations(request).all()
]


Expand Down

0 comments on commit 9072fa5

Please sign in to comment.