Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit rounds ui! #1856

Merged
merged 42 commits into from
Sep 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
87dfb25
Add a fancy show rounds page complete with cutoffs, time limits, and
jfly Apr 30, 2017
972b4e5
Add serializable_hash methods for the javascript infrastructure we're…
jfly May 18, 2017
c51541f
Added react and built a fancy edit rounds ui that saves WCIF via ajax.
jfly May 3, 2017
494739e
Change select to two radio buttons.
jfly Jul 21, 2017
88510a9
Tweaking dialog titles.
jfly Jul 22, 2017
a771de3
Catching up with latest WCIF spec: "percentile" -> "percent" and "att…
jfly Jul 22, 2017
7183bc9
Better support for time limits for 333mbf and 333fm, which do not have
jfly Jul 22, 2017
016cfc2
Don't display buttons to edit the time limit for events that do not
jfly Jul 22, 2017
fc4ca87
Explicitly disable the edit event form when there are deprecated events.
jfly Aug 24, 2017
c021ecf
Remove old test that no longer applies.
jfly Aug 24, 2017
31ac1b9
Clean up the advacement dialog a bit.
jfly Aug 28, 2017
109cdda
Add DISABLE_BULLET environment variable.
jfly Aug 28, 2017
a2e27a3
Start of support for timed events vs fmc vs mbld.
jfly Aug 28, 2017
268abe4
Implemented format1 / format2 ui for the cutoff dialog.
jfly Aug 28, 2017
9ad390e
Set backdrop static to prevent dismissing dialogs when clicking on th…
jfly Aug 28, 2017
a4876b6
Add a helpful description for the weird cumulative time limits.
jfly Aug 29, 2017
65fed78
Misc styling.
jfly Aug 29, 2017
c464071
Actually added support for cross round cumulative time limits.
jfly Aug 29, 2017
330acfb
Refactor modals code a bit, and create a AttemptResultInput component.
jfly Sep 1, 2017
280e7bc
Implement advanceReqToStr.
jfly Sep 1, 2017
cec04e4
Add support for mbld points =)
jfly Sep 1, 2017
798a6f7
Some polish: short formatting of times for our tiny buttons.
jfly Sep 1, 2017
6b7f1a7
Add a silly simple centiseconds input.
jfly Sep 1, 2017
cd4b8e9
Created a matchResult() method to stringify what it takes to beat a
jfly Sep 1, 2017
50a9133
Grey out events that are not being held.
jfly Sep 1, 2017
cd305e4
Implemented the UI for sharing a cumulative time limit with other rou…
jfly Sep 2, 2017
1dcf646
Added javascript feature test of rounds management.
jfly Sep 3, 2017
6bf146b
Polish the look of the advancement condition modal.
jfly Sep 3, 2017
639e7db
Limit the advancement percent to 75%.
jfly Sep 7, 2017
d669a51
Add nice big alerts notifying the user when there are unsaved changes.
jfly Sep 7, 2017
dd5f8d4
Added some explanation text to the cutoff modal.
jfly Sep 7, 2017
9e68654
Remove upper bound of 60 minutes on time limits.
jfly Sep 7, 2017
abad79d
Do not allow adding or removing events to a confirmed competition.
jfly Sep 7, 2017
5ea98d6
Update UI to reflect that events cannot be added or removed to confir…
jfly Sep 7, 2017
a7691d1
Less confusing modal behavior.
jfly Sep 9, 2017
dbde71e
Update submodal to have the new ok, cancel behavior for all our modals.
jfly Sep 9, 2017
a82ae46
Responding to @jonatanklosko's review comments.
jfly Sep 10, 2017
e5143e4
Fix as many Bullet warnings as possible, and ignore the one remaining
jfly Sep 10, 2017
18ef0e5
Added explicit add and remove event buttons, along with a confirmation
jfly Sep 12, 2017
94f9956
Improved show events page
viroulep Sep 12, 2017
6b6bbf2
Add support for 0 rounds in an event.
jfly Sep 13, 2017
f874096
Some ui polish.
jfly Sep 13, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion WcaOnRails/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"uglify": true
},
"useBuiltIns": true
}]
}],
"react",
"stage-2"
],

"plugins": [
Expand Down
4 changes: 4 additions & 0 deletions WcaOnRails/Envfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ group :production do
variable :SMTP_PASSWORD
end

group :development do
variable :DISABLE_BULLET, :boolean, default: false
end

# Set WCA_LIVE_SITE to enable Google Analytics
# and allow all on robots.txt.
variable :WCA_LIVE_SITE, :boolean, default: false
Expand Down
1 change: 1 addition & 0 deletions WcaOnRails/app/assets/stylesheets/application.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@
@import "competition_tabs";
@import "server_status";
@import "relations";
@import "edit_events";
5 changes: 5 additions & 0 deletions WcaOnRails/app/assets/stylesheets/competitions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ $competition-nav-padding: 50px;
width: calc(100% - (#{$competition-nav-width} + #{$competition-nav-padding}));
}

.show-events-table {
.last-round > td {
border-bottom: 4px solid #ccc;
}
}
}

// Workaround for https://github.com/cubing/icons/issues/16
Expand Down
49 changes: 49 additions & 0 deletions WcaOnRails/app/assets/stylesheets/edit_events.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#events-edit-area {
.panel-heading {
padding-top: 10px;
padding-bottom: 10px;

.panel-title {
white-space: nowrap;
overflow: hidden;
display: flex;
align-items: center;

$cubing-icon-size: 55px;
.img-thumbnail.cubing-icon {
font-size: 40px;
position: absolute;
top: -5px;
height: $cubing-icon-size;
z-index: 1;
}

.title {
padding-left: $cubing-icon-size;
padding-right: 5px;
}

.add-event {
margin-left: auto;
}

.input-group {
margin-left: auto;

select {
width: 100px;
}

.input-group-btn {
display: inline-block;
}
}
}
}

.panel-body {
select {
width: 100%;
}
}
}
59 changes: 59 additions & 0 deletions WcaOnRails/app/assets/stylesheets/wca.scss
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,62 @@ a.plain {
color: inherit;
text-decoration: none;
}

// From http://stackoverflow.com/a/22892773
.row.equal {
display: flex;
flex-wrap: wrap;
}

// Modified from http://bootsnipp.com/snippets/featured/loading-button-effect-no-js
button.saving {
@keyframes ld {
0% { transform: rotate(0deg) scale(1); }
50% { transform: rotate(180deg) scale(1.1); }
100% { transform: rotate(360deg) scale(1); }
}

position: relative;
opacity: 0.8;

&:hover,
&:active,
&:focus {
cursor: default;
box-shadow: none;
}

&::before {
content: '';

display: inline-block;

position: absolute;
background: transparent;
border: 1px solid currentColor;
border-top-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;

box-sizing: border-box;

top: 50%;
left: 50%;
margin-top: -12px;
margin-left: -12px;

width: 24px;
height: 24px;

animation: ld 1s ease-in-out infinite;
}
}

// Modified from https://stackoverflow.com/a/22920590
.input-xs {
height: 22px;
padding: 2px 0;
font-size: 12px;
line-height: 1.5; /* If Placeholder of the input is moved up, rem/modify this. */
border-radius: 3px;
}
10 changes: 8 additions & 2 deletions WcaOnRails/app/controllers/competitions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,16 @@ def post_results
end
end

def show_events
@competition = competition_from_params(includes: [:events, competition_events: { rounds: [:format, :competition_event] }])
end

def edit_events
@competition = competition_from_params(includes: [:events])
@competition = competition_from_params(includes: [:events, competition_events: { rounds: [:competition_event] }])
end

def update_events
@competition = competition_from_params(includes: [:events])
@competition = competition_from_params
if @competition.update_attributes(competition_params)
flash[:success] = t('.update_success')
redirect_to edit_events_path(@competition)
Expand All @@ -348,6 +352,8 @@ def update_events_from_wcif
status: "Error while saving WCIF events",
error: e.message,
}
rescue WcaExceptions::ApiException => e
render status: e.status, json: { error: e.to_s }
end

def get_nearby_competitions(competition)
Expand Down
77 changes: 77 additions & 0 deletions WcaOnRails/app/javascript/edit-events/ButtonActivatedModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react'
import cn from 'classnames'
import Modal from 'react-bootstrap/lib/Modal'
import Button from 'react-bootstrap/lib/Button'
import addEventListener from 'react-overlays/lib/utils/addEventListener';
import ownerDocument from 'react-overlays/lib/utils/ownerDocument';

export default class ButtonActivatedModal extends React.Component {
constructor() {
super();
this.state = { showModal: false };
}

open = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this method defined as an arrow function? I believe it's in order to save the this context even when passed as an event handler, but then why do you prefer bind here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Because I wrote that code in EditEvents class before I knew you could define instance methods using the arrow function. I've changed the EditEvents class to get rid of the binds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, to be honest I was surprised seeing this property assignment style, I was sure it's not a part of the ES6 spec, but we have a babel plugin enabling this.

this.setState({ showModal: true });
}

close = ({ skipUnsavedChangesCheck } = { skipUnsavedChangesCheck: false }) => {
if(skipUnsavedChangesCheck || !this.props.hasUnsavedChanges() || confirm("Are you sure you want to discard your changes?")) {
this.props.reset();
this.setState({ showModal: false });
}
}

render() {
return (
<button type="button" name={this.props.name} className={cn("btn", this.props.buttonClass)} onClick={this.open}>
{this.props.buttonValue}
<KeydownDismissModal show={this.state.showModal} onHide={this.close}>
<form className={this.props.formClass} onSubmit={e => { e.preventDefault(); this.props.onOk(); }}>
{this.props.children}
<Modal.Footer>
<Button onClick={this.close} bsStyle="warning">Close</Button>
<Button type="submit" bsStyle="success">Ok</Button>
</Modal.Footer>
</form>
</KeydownDismissModal>
</button>
);
}
}

// More or less copied from https://github.com/react-bootstrap/react-overlays/pull/195
// This can go away once a new version of react-overlays is released and react-bootstrap
// is updated to depend on it.
class KeydownDismissModal extends React.Component {
static defaultProps = Modal.defaultProps;

handleDocumentKeyDown = (e) => {
if (this.props.keyboard && e.key === 'Escape' && this._modal._modal.isTopModal()) {
if (this.props.onEscapeKeyDown) {
this.props.onEscapeKeyDown(e);
}

this.props.onHide();
}
}

onShow = () => {
let doc = ownerDocument(this);
this._onDocumentKeydownListener =
addEventListener(doc, 'keydown', this.handleDocumentKeyDown);
}

onHide = () => {
this._onDocumentKeydownListener.remove();
}

render() {
let subprops = {
...this.props,
keyboard: false,
onShow: this.onShow,
};
return <Modal {...subprops} ref={m => this._modal = m} />;
}
}
Loading