Merge branch 'master' into organization-links

This commit is contained in:
Shlok Srivastava 2017-08-26 09:53:25 +00:00 • committed by GitHub
commit dcaf074753
174 changed files with 4210 additions and 722 deletions

View file

@ -11,6 +11,7 @@ linters:
# Offense count: 945 # Offense count: 945
LineLength: LineLength:
exclude: exclude:
- "app/views/admin/booths/_change_state_dropdown.html.haml"
- "app/views/admin/booths/_form.html.haml" - "app/views/admin/booths/_form.html.haml"
- "app/views/admin/booths/index.html.haml" - "app/views/admin/booths/index.html.haml"
- "app/views/admin/booths/show.html.haml" - "app/views/admin/booths/show.html.haml"
@ -77,6 +78,7 @@ linters:
- "app/views/admin/resources/show.html.haml" - "app/views/admin/resources/show.html.haml"
- "app/views/admin/roles/_form.html.haml" - "app/views/admin/roles/_form.html.haml"
- "app/views/admin/roles/_users.html.haml" - "app/views/admin/roles/_users.html.haml"
- "app/views/admin/roles/_users_with_org_admin_role.haml"
- "app/views/admin/roles/index.html.haml" - "app/views/admin/roles/index.html.haml"
- "app/views/admin/roles/show.html.haml" - "app/views/admin/roles/show.html.haml"
- "app/views/admin/rooms/_form.html.haml" - "app/views/admin/rooms/_form.html.haml"
@ -109,6 +111,9 @@ linters:
- "app/views/admin/versions/_object_desc_and_link.html.haml" - "app/views/admin/versions/_object_desc_and_link.html.haml"
- "app/views/admin/versions/index.html.haml" - "app/views/admin/versions/index.html.haml"
- "app/views/admin/volunteers/index.html.haml" - "app/views/admin/volunteers/index.html.haml"
- "app/views/booths/_form.html.haml"
- "app/views/booths/index.html.haml"
- "app/views/booths/show.html.haml"
- "app/views/commercials/edit.html.haml" - "app/views/commercials/edit.html.haml"
- "app/views/commercials/new.html.haml" - "app/views/commercials/new.html.haml"
- "app/views/conference_registrations/_form.html.haml" - "app/views/conference_registrations/_form.html.haml"
@ -116,6 +121,7 @@ linters:
- "app/views/conference_registrations/_registration_info.html.haml" - "app/views/conference_registrations/_registration_info.html.haml"
- "app/views/conference_registrations/_volunteer.html.haml" - "app/views/conference_registrations/_volunteer.html.haml"
- "app/views/conference_registrations/show.html.haml" - "app/views/conference_registrations/show.html.haml"
- "app/views/conferences/_booths.html.haml"
- "app/views/conferences/_call_for_paper.html.haml" - "app/views/conferences/_call_for_paper.html.haml"
- "app/views/conferences/_conference_details.html.haml" - "app/views/conferences/_conference_details.html.haml"
- "app/views/conferences/_gallery.html.haml" - "app/views/conferences/_gallery.html.haml"
@ -147,6 +153,7 @@ linters:
- "app/views/layouts/_admin_sidebar_index.html.haml" - "app/views/layouts/_admin_sidebar_index.html.haml"
- "app/views/layouts/_messages.html.haml" - "app/views/layouts/_messages.html.haml"
- "app/views/layouts/_navigation.html.haml" - "app/views/layouts/_navigation.html.haml"
- "app/views/layouts/_user_menu.html.haml"
- "app/views/layouts/application.html.haml" - "app/views/layouts/application.html.haml"
- "app/views/organizations/index.html.haml" - "app/views/organizations/index.html.haml"
- "app/views/payments/_payment.html.haml" - "app/views/payments/_payment.html.haml"
@ -178,6 +185,10 @@ linters:
- "app/views/tracks/_form.html.haml" - "app/views/tracks/_form.html.haml"
- "app/views/tracks/index.html.haml" - "app/views/tracks/index.html.haml"
- "app/views/tracks/show.html.haml" - "app/views/tracks/show.html.haml"
- "app/views/conferences/_call_for_tracks.html.haml"
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
- "app/views/proposals/_encouragement_text.html.haml"
- "app/views/admin/schedules/_form.html.haml"
# Offense count: 223 # Offense count: 223
InstanceVariables: InstanceVariables:
@ -240,6 +251,10 @@ linters:
- "app/views/schedules/_schedule_tabs.html.haml" - "app/views/schedules/_schedule_tabs.html.haml"
- "app/views/admin/cfps/_events_cfp.html.haml" - "app/views/admin/cfps/_events_cfp.html.haml"
- "app/views/tracks/_form.html.haml" - "app/views/tracks/_form.html.haml"
- "app/views/admin/cfps/_tracks_cfp.html.haml"
- "app/views/conferences/_call_for_tracks.html.haml"
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
- "app/views/admin/schedules/_form.html.haml"
# Offense count: 32 # Offense count: 32
IdNames: IdNames:
@ -259,6 +274,7 @@ linters:
- "app/views/admin/users/show.html.haml" - "app/views/admin/users/show.html.haml"
- "app/views/users/edit.html.haml" - "app/views/users/edit.html.haml"
- "app/views/admin/cfps/_events_cfp.html.haml" - "app/views/admin/cfps/_events_cfp.html.haml"
- "app/views/admin/cfps/_tracks_cfp.html.haml"
# Offense count: 4 # Offense count: 4
UnnecessaryInterpolation: UnnecessaryInterpolation:
@ -294,6 +310,7 @@ linters:
SpaceInsideHashAttributes: SpaceInsideHashAttributes:
exclude: exclude:
- "app/views/admin/conferences/_todo_list.html.haml" - "app/views/admin/conferences/_todo_list.html.haml"
- "app/views/admin/emails/index.html.haml"
- "app/views/admin/questions/_form.html.haml" - "app/views/admin/questions/_form.html.haml"
- "app/views/admin/questions/index.html.haml" - "app/views/admin/questions/index.html.haml"
- "app/views/admin/registrations/index.html.haml" - "app/views/admin/registrations/index.html.haml"
@ -369,6 +386,7 @@ linters:
- "app/views/admin/tracks/show.html.haml" - "app/views/admin/tracks/show.html.haml"
- "app/views/admin/venues/show.html.haml" - "app/views/admin/venues/show.html.haml"
- "app/views/admin/versions/index.html.haml" - "app/views/admin/versions/index.html.haml"
- "app/views/booths/index.html.haml"
- "app/views/conference_registrations/_form.html.haml" - "app/views/conference_registrations/_form.html.haml"
- "app/views/conference_registrations/_ticket.html.haml" - "app/views/conference_registrations/_ticket.html.haml"
- "app/views/conference_registrations/show.html.haml" - "app/views/conference_registrations/show.html.haml"
@ -393,10 +411,12 @@ linters:
# Offense count: 14 # Offense count: 14
ConsecutiveSilentScripts: ConsecutiveSilentScripts:
exclude: exclude:
- "app/views/admin/booths/_change_state_dropdown.html.haml"
- "app/views/admin/events/index.html.haml" - "app/views/admin/events/index.html.haml"
- "app/views/admin/schedules/_day_tab.html.haml" - "app/views/admin/schedules/_day_tab.html.haml"
- "app/views/admin/schedules/_event.html.haml" - "app/views/admin/schedules/_event.html.haml"
- "app/views/admin/versions/_object_desc_and_link.html.haml" - "app/views/admin/versions/_object_desc_and_link.html.haml"
- "app/views/booths/index.html.haml"
- "app/views/schedules/_carousel.html.haml" - "app/views/schedules/_carousel.html.haml"
# Offense count: 29 # Offense count: 29

View file

@ -31,3 +31,4 @@ Metrics/BlockLength:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
- 'spec/features/ability_spec.rb' - 'spec/features/ability_spec.rb'
- 'spec/models/ability_spec.rb' - 'spec/models/ability_spec.rb'
- 'spec/models/admin_ability_spec.rb'

View file

@ -317,6 +317,8 @@ Metrics/BlockLength:
# Offense count: 23 # Offense count: 23
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Max: 12 Max: 12
Exclude:
- 'app/models/track.rb'
# Offense count: 2353 # Offense count: 2353
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
@ -328,15 +330,21 @@ Metrics/LineLength:
# Configuration parameters: CountComments. # Configuration parameters: CountComments.
Metrics/MethodLength: Metrics/MethodLength:
Max: 56 Max: 56
Exclude:
- 'app/models/admin_ability.rb'
# Offense count: 3 # Offense count: 3
# Configuration parameters: CountComments. # Configuration parameters: CountComments.
Metrics/ModuleLength: Metrics/ModuleLength:
Max: 159 Max: 159
Exclude:
- 'app/helpers/format_helper.rb'
# Offense count: 15 # Offense count: 15
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Max: 16 Max: 16
Exclude:
- 'app/models/track.rb'
# Offense count: 20 # Offense count: 20
Style/AccessorMethodName: Style/AccessorMethodName:
@ -437,6 +445,7 @@ Style/HashSyntax:
# Configuration parameters: MaxLineLength. # Configuration parameters: MaxLineLength.
Style/IfUnlessModifier: Style/IfUnlessModifier:
Exclude: Exclude:
- 'app/controllers/admin/booths_controller.rb'
- 'app/controllers/admin/events_controller.rb' - 'app/controllers/admin/events_controller.rb'
- 'app/controllers/api/v1/events_controller.rb' - 'app/controllers/api/v1/events_controller.rb'
- 'app/controllers/conference_registrations_controller.rb' - 'app/controllers/conference_registrations_controller.rb'
@ -444,6 +453,7 @@ Style/IfUnlessModifier:
- 'app/helpers/application_helper.rb' - 'app/helpers/application_helper.rb'
- 'app/models/commercial.rb' - 'app/models/commercial.rb'
- 'app/models/conference.rb' - 'app/models/conference.rb'
- 'app/models/email_settings.rb'
- 'app/models/ticket_purchase.rb' - 'app/models/ticket_purchase.rb'
- 'app/models/user.rb' - 'app/models/user.rb'
- 'db/migrate/20151031092713_change_conference_id_to_venue_id_in_rooms.rb' - 'db/migrate/20151031092713_change_conference_id_to_venue_id_in_rooms.rb'
@ -563,6 +573,7 @@ Style/PercentLiteralDelimiters:
- 'app/models/subscription.rb' - 'app/models/subscription.rb'
- 'app/uploaders/picture_uploader.rb' - 'app/uploaders/picture_uploader.rb'
- 'spec/models/program_spec.rb' - 'spec/models/program_spec.rb'
- 'app/models/track.rb'
# Offense count: 2 # Offense count: 2
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.

View file

@ -57,7 +57,7 @@ gem 'unobtrusive_flash', '>=3'
gem 'transitions', :require => %w( transitions active_record/transitions ) gem 'transitions', :require => %w( transitions active_record/transitions )
# for comments # for comments
gem 'awesome_nested_set', '~> 3.0.0.rc.5' gem 'awesome_nested_set', '~> 3.1.3'
gem 'acts_as_commentable_with_threading' gem 'acts_as_commentable_with_threading'
# as templating language # as templating language

View file

@ -69,11 +69,10 @@ GEM
uuidtools uuidtools
arel (6.0.4) arel (6.0.4)
ast (2.3.0) ast (2.3.0)
autoprefixer-rails (5.1.9) autoprefixer-rails (7.1.1)
execjs execjs
json awesome_nested_set (3.1.3)
awesome_nested_set (3.0.0.rc.5) activerecord (>= 4.0.0, < 5.2)
activerecord (>= 4.0.0, < 5)
aws_cf_signer (0.1.3) aws_cf_signer (0.1.3)
axlsx_rails (0.2.0) axlsx_rails (0.2.0)
axlsx (>= 2.0.1) axlsx (>= 2.0.1)
@ -117,13 +116,14 @@ GEM
rest-client rest-client
cocoon (1.2.6) cocoon (1.2.6)
coderay (1.1.1) coderay (1.1.1)
coffee-rails (4.1.1) coffee-rails (4.2.2)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x) railties (>= 4.0.0)
coffee-script (2.4.1) coffee-script (2.4.1)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.10.0) coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
countable-rails (0.0.1) countable-rails (0.0.1)
railties (>= 3.1) railties (>= 3.1)
countries (1.2.5) countries (1.2.5)
@ -145,10 +145,10 @@ GEM
dante (0.2.0) dante (0.2.0)
database_cleaner (1.3.0) database_cleaner (1.3.0)
debug_inspector (0.0.2) debug_inspector (0.0.2)
delayed_job (4.1.1) delayed_job (4.1.3)
activesupport (>= 3.0, < 5.0) activesupport (>= 3.0, < 5.2)
delayed_job_active_record (4.1.0) delayed_job_active_record (4.1.2)
activerecord (>= 3.0, < 5) activerecord (>= 3.0, < 5.2)
delayed_job (>= 3.0, < 5) delayed_job (>= 3.0, < 5)
devise (4.2.0) devise (4.2.0)
bcrypt (~> 3.0) bcrypt (~> 3.0)
@ -162,10 +162,10 @@ GEM
docile (1.1.5) docile (1.1.5)
domain_name (0.5.20160310) domain_name (0.5.20160310)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.1.1) dotenv (2.2.1)
dotenv-rails (2.1.1) dotenv-rails (2.2.1)
dotenv (= 2.1.1) dotenv (= 2.2.1)
railties (>= 4.0, < 5.1) railties (>= 3.2, < 5.2)
erubis (2.7.0) erubis (2.7.0)
execjs (2.6.0) execjs (2.6.0)
factory_girl (4.5.0) factory_girl (4.5.0)
@ -180,8 +180,8 @@ GEM
fastimage (2.0.0) fastimage (2.0.0)
addressable (~> 2) addressable (~> 2)
ffi (1.9.18) ffi (1.9.18)
font-awesome-rails (4.1.0.0) font-awesome-rails (4.7.0.2)
railties (>= 3.2, < 5.0) railties (>= 3.2, < 5.2)
formatador (0.2.5) formatador (0.2.5)
formtastic (3.1.3) formtastic (3.1.3)
actionpack (>= 3.2.13) actionpack (>= 3.2.13)
@ -219,8 +219,7 @@ GEM
rubocop (>= 0.47.0) rubocop (>= 0.47.0)
sysexits (~> 1.1) sysexits (~> 1.1)
hashdiff (0.3.4) hashdiff (0.3.4)
hashie (2.1.1) hashie (3.5.5)
hike (1.2.3)
hoptoad_notifier (2.4.11) hoptoad_notifier (2.4.11)
activesupport activesupport
builder builder
@ -235,8 +234,9 @@ GEM
jquery-datatables-rails (2.2.3) jquery-datatables-rails (2.2.3)
jquery-rails jquery-rails
sass-rails sass-rails
jquery-rails (3.1.4) jquery-rails (4.3.1)
railties (>= 3.0, < 5.0) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
jquery-ui-rails (4.2.1) jquery-ui-rails (4.2.1)
railties (>= 3.2.16) railties (>= 3.2.16)
@ -295,15 +295,15 @@ GEM
notiffany (0.1.1) notiffany (0.1.1)
nenv (~> 0.1) nenv (~> 0.1)
shellany (~> 0.0) shellany (~> 0.0)
oauth2 (0.9.4) oauth2 (1.3.1)
faraday (>= 0.8, < 0.10) faraday (>= 0.8, < 0.12)
jwt (~> 1.0) jwt (~> 1.0)
multi_json (~> 1.3) multi_json (~> 1.3)
multi_xml (~> 0.5) multi_xml (~> 0.5)
rack (~> 1.2) rack (>= 1.2, < 3)
omniauth (1.2.1) omniauth (1.6.1)
hashie (>= 1.2, < 3) hashie (>= 3.4.6, < 3.6.0)
rack (~> 1.0) rack (>= 1.6.2, < 3)
omniauth-facebook (1.6.0) omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
omniauth-github (1.1.2) omniauth-github (1.1.2)
@ -312,10 +312,8 @@ GEM
omniauth-google-oauth2 (0.2.4) omniauth-google-oauth2 (0.2.4)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
omniauth-oauth2 (1.1.2) omniauth-oauth2 (1.4.0)
faraday (>= 0.8, < 0.10) oauth2 (~> 1.0)
multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2) omniauth (~> 1.2)
omniauth-openid (1.0.1) omniauth-openid (1.0.1)
omniauth (~> 1.0) omniauth (~> 1.0)
@ -425,8 +423,9 @@ GEM
redcarpet (3.2.3) redcarpet (3.2.3)
referer-parser (0.2.1) referer-parser (0.2.1)
request_store (1.1.0) request_store (1.1.0)
responders (2.1.1) responders (2.4.0)
railties (>= 4.2.0, < 5.1) actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rest-client (1.8.0) rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0) http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0) mime-types (>= 1.16, < 3.0)
@ -473,11 +472,12 @@ GEM
rubyzip (1.2.1) rubyzip (1.2.1)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sass (3.2.19) sass (3.2.19)
sass-rails (4.0.4) sass-rails (5.0.6)
railties (>= 4.0.0, < 5.0) railties (>= 4.0.0, < 6)
sass (~> 3.2.2) sass (~> 3.1)
sprockets (~> 2.8, < 2.12) sprockets (>= 2.8, < 4.0)
sprockets-rails (~> 2.0) sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selectize-rails (0.12.4) selectize-rails (0.12.4)
shellany (0.0.1) shellany (0.0.1)
shoulda-matchers (2.8.0) shoulda-matchers (2.8.0)
@ -494,11 +494,9 @@ GEM
spring (1.6.3) spring (1.6.3)
spring-commands-rspec (1.0.4) spring-commands-rspec (1.0.4)
spring (>= 0.9.1) spring (>= 0.9.1)
sprockets (2.11.3) sprockets (3.7.1)
hike (~> 1.2) concurrent-ruby (~> 1.0)
multi_json (~> 1.0) rack (> 1, < 3)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.3.3) sprockets-rails (2.3.3)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
@ -566,7 +564,7 @@ DEPENDENCIES
acts_as_list acts_as_list
ahoy_matey ahoy_matey
autoprefixer-rails autoprefixer-rails
awesome_nested_set (~> 3.0.0.rc.5) awesome_nested_set (~> 3.1.3)
axlsx! axlsx!
axlsx_rails axlsx_rails
bootstrap-sass (~> 3.3.4.1) bootstrap-sass (~> 3.3.4.1)

View file

@ -1,5 +1,5 @@
# Translation # Translation
We are using [Transifex] (https://www.transifex.com/opensuse-community/osem/) to manage our translations. We are using [Transifex](https://www.transifex.com/opensuse-community/osem/) to manage our translations.
We are also using the _Live_ feature of Transifex. That means that all strings from OSEM instances are automatically collected and are available for translating. We are also using the _Live_ feature of Transifex. That means that all strings from OSEM instances are automatically collected and are available for translating.
>Automated collection only works if you use the API key (See at the end of this file) >Automated collection only works if you use the API key (See at the end of this file)
@ -7,7 +7,7 @@ We are also using the _Live_ feature of Transifex. That means that all strings f
## 1. Translate ## 1. Translate
* Start translating: * Start translating:
1. Navigate to the [project's page] (https://www.transifex.com/opensuse-community/osem) 1. Navigate to the [project's page](https://www.transifex.com/opensuse-community/osem)
2. Click **translation** button 2. Click **translation** button
3. Select **language** 3. Select **language**
4. Select **resource** (events.opensuse.org) 4. Select **resource** (events.opensuse.org)
@ -27,7 +27,7 @@ Eg. Assuming you have signed up yourself as a translator for OSEM, to translate
* How to request to publish translated strings * How to request to publish translated strings
After you make sure that you have properly reviewed the newly translated strings (they need to be marked as **reviewed** otherwise they won't go live), you can open a [new issue] (https://github.com/openSUSE/osem/issues/new) with the following information: After you make sure that you have properly reviewed the newly translated strings (they need to be marked as **reviewed** otherwise they won't go live), you can open a [new issue](https://github.com/openSUSE/osem/issues/new) with the following information:
Title: [Transifex] Publish translation for EN Title: [Transifex] Publish translation for EN

View file

@ -55,7 +55,6 @@ $(function() {
} }
function draw_line_chart(animation, $canvas){ function draw_line_chart(animation, $canvas){
var options = get_animation({}, animation);
var chart_data = create_dataset($canvas); var chart_data = create_dataset($canvas);
var weeks = $canvas.parent().data('weeks'); var weeks = $canvas.parent().data('weeks');
var data = { var data = {
@ -63,10 +62,27 @@ $(function() {
datasets : chart_data datasets : chart_data
} }
var options = get_animation(wholeNumberAxisFix(data), animation);
var ctx = $canvas.get(0).getContext("2d"); var ctx = $canvas.get(0).getContext("2d");
new Chart(ctx).Line(data, options); new Chart(ctx).Line(data, options);
} }
function wholeNumberAxisFix(data){
var maxValue = false;
for(datasetIndex = 0; datasetIndex < data.datasets.length; ++datasetIndex){
var setMax = Math.max.apply(null, data.datasets[datasetIndex].data);
if (maxValue === false || setMax > maxValue) maxValue = setMax;
}
var steps = maxValue;
var stepWidth = 1;
if (maxValue > 10) {
stepWidth = Math.floor(maxValue / 10);
steps = Math.ceil(maxValue / stepWidth);
}
return { scaleOverride: true, scaleSteps: steps, scaleStepWidth: stepWidth, scaleStartValue: 0 };
}
function create_dataset($canvas){ function create_dataset($canvas){
var selected = getSelectedConferences($canvas); var selected = getSelectedConferences($canvas);
var chart_data = $canvas.parent().data('chart'); var chart_data = $canvas.parent().data('chart');

View file

@ -1,18 +1,14 @@
$(function () { $(function () {
$(document).ready(function() { $('.datatable').DataTable({
$('.datatable').DataTable({ // ajax: ...,
// ajax: ..., stateSave: true,
stateSave: true, autoWidth: false,
autoWidth: false, pagingType: 'full_numbers',
pagingType: 'full_numbers', "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
"lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]] });
});
$('#versionstable').DataTable({ $('#versionstable').DataTable({
pagingType: 'full_numbers', pagingType: 'full_numbers',
order: [[ 0, 'desc' ]] order: [[ 0, 'desc' ]]
});
}); });
}); });

View file

@ -78,11 +78,12 @@ var Schedule = {
}; };
$(document).ready( function() { $(document).ready( function() {
// hide the remove button for unscheduled events // hide the remove button for unscheduled and non schedulable events
$('.unscheduled-events .schedule-event-delete-button').hide(); $('.unscheduled-events .schedule-event-delete-button').hide();
$('.non_schedulable .schedule-event-delete-button').hide();
// set events as draggable // set events as draggable
$('.schedule-event').draggable({ $('.schedule-event').not('.non_schedulable').draggable({
snap: '.schedule-room-slot', snap: '.schedule-room-slot',
revertDuration: 200, revertDuration: 200,
revert: function (event, ui) { revert: function (event, ui) {
@ -99,7 +100,7 @@ $(document).ready( function() {
}); });
// set room cells as droppable // set room cells as droppable
$('.schedule-room-slot').droppable({ $('.schedule-room-slot').not('.non_schedulable .schedule-room-slot').droppable({
accept: '.schedule-event', accept: '.schedule-event',
tolerance: "pointer", tolerance: "pointer",
drop: function(event, ui) { drop: function(event, ui) {

View file

@ -29,7 +29,7 @@
} }
} }
.dropdown-menu { .dropdown-menu {
padding: 17px 17px 0px 17px; padding: 17px;
min-width: 225px; min-width: 225px;
} }
} }

View file

@ -267,6 +267,10 @@ td.no-padding{
font-size: 7px; font-size: 7px;
} }
.non_schedulable{
opacity: 0.5;
}
/* Small devices (tablets, 768px and up) */ /* Small devices (tablets, 768px and up) */
@media (min-width: 768px) { @media (min-width: 768px) {
.room, .event-title{ .room, .event-title{

View file

@ -90,3 +90,17 @@ p.comment-body {
.changeset{ .changeset{
display: none; display: none;
} }
.box{
height: 230px;
}
/* sidebar hamburger btn */
.side-nav-btn{
margin-left: 10px;
float: left;
}
.qr-image{
margin-left: 120px;
}

View file

@ -7,9 +7,13 @@ module Admin
def show; end def show; end
def new; end def new
@url = admin_conference_booths_path(@conference.short_title)
end
def create def create
@url = admin_conference_booths_path(@conference.short_title)
@booth = @conference.booths.new(booth_params) @booth = @conference.booths.new(booth_params)
@booth.submitter = current_user @booth.submitter = current_user
@ -23,9 +27,13 @@ module Admin
end end
end end
def edit; end def edit
@url = admin_conference_booth_path(@conference.short_title, @booth.id)
end
def update def update
@url = admin_conference_booth_path(@conference.short_title, @booth.id)
@booth.update_attributes(booth_params) @booth.update_attributes(booth_params)
if @booth.save if @booth.save
@ -38,18 +46,19 @@ module Admin
end end
end end
def destroy
if @booth.destroy
redirect_to admin_conference_booths_path,
notice: 'Booth successfully destroyed.'
else
redirect_to admin_conference_booths_path,
error: "Booth couldn't be deleted. #{@booth.errors.full_messages.join('. ')}."
end
end
def accept def accept
update_state(:accept, 'Booth accepted!') @booth.accept!
if @booth.save
if @conference.email_settings.send_on_booths_acceptance
Mailbot.conference_booths_acceptance_mail(@booth).deliver
end
redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
notice: 'Booth successfully accepted!'
else
redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
flash[:error] = "Booth could not be accepted. #{@booth.errors.full_messages.to_sentence}."
end
end end
def to_accept def to_accept
@ -61,7 +70,16 @@ module Admin
end end
def reject def reject
update_state(:reject, 'Booth rejected') @booth.reject!
if @booth.save
Mailbot.conference_booths_rejection_mail(@booth).deliver
redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
notice: 'Booth successfully rejected.'
else
redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
flash[:error] = "Booth could not be rejected. #{@booth.errors.full_messages.to_sentence}."
end
end end
def restart def restart
@ -72,6 +90,10 @@ module Admin
update_state(:cancel, 'Booth is canceled') update_state(:cancel, 'Booth is canceled')
end end
def confirm
update_state(:confirm, 'Booth successfully confirmed')
end
private private
def update_state(transition, notice) def update_state(transition, notice)

View file

@ -72,11 +72,12 @@ module Admin
def new def new
@conference = Conference.new @conference = Conference.new
@organizations = Organization.accessible_by(current_ability, :update).pluck(:name, :id)
end end
def create def create
@conference = Conference.new(conference_params) @conference = Conference.new(conference_params)
@conference.organization = Organization.find_or_create_by(name: 'organization')
if @conference.save if @conference.save
# user that creates the conference becomes organizer of that conference # user that creates the conference becomes organizer of that conference
current_user.add_role :organizer, @conference current_user.add_role :organizer, @conference
@ -211,7 +212,7 @@ module Admin
:vpositions_attributes, :use_volunteers, :color, :vpositions_attributes, :use_volunteers, :color,
:sponsorship_levels_attributes, :sponsors_attributes, :sponsorship_levels_attributes, :sponsors_attributes,
:targets, :targets_attributes, :targets, :targets_attributes,
:campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout) :campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout, :booth_limit)
end end
end end
end end

View file

@ -30,7 +30,9 @@ module Admin
:send_on_conference_registration_dates_updated, :conference_registration_dates_updated_subject, :conference_registration_dates_updated_body, :send_on_conference_registration_dates_updated, :conference_registration_dates_updated_subject, :conference_registration_dates_updated_body,
:send_on_venue_updated, :venue_updated_subject, :venue_updated_body, :send_on_venue_updated, :venue_updated_subject, :venue_updated_body,
:send_on_cfp_dates_updated, :cfp_dates_updated_subject, :cfp_dates_updated_body, :send_on_cfp_dates_updated, :cfp_dates_updated_subject, :cfp_dates_updated_body,
:send_on_program_schedule_public, :program_schedule_public_subject, :program_schedule_public_body) :send_on_program_schedule_public, :program_schedule_public_subject, :program_schedule_public_body,
:send_on_booths_acceptance, :booths_acceptance_subject, :booths_acceptance_body,
:send_on_booths_rejection, :booths_rejection_subject, :booths_rejection_body)
end end
end end
end end

View file

@ -4,8 +4,10 @@ module Admin
load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource :program, through: :conference, singleton: true
load_and_authorize_resource :event, through: :program load_and_authorize_resource :event, through: :program
load_and_authorize_resource :events_registration, only: :toggle_attendance load_and_authorize_resource :events_registration, only: :toggle_attendance
# For some reason this doesn't work, so a workaround is used
# load_and_authorize_resource :track, through: :program, only: [:index, :show, :edit]
before_action :get_event, except: [:index, :create, :new] before_action :get_tracks, only: [:index, :show, :edit]
# FIXME: The timezome should only be applied on output, otherwise # FIXME: The timezome should only be applied on output, otherwise
# you get lost in timezone conversions... # you get lost in timezone conversions...
@ -16,8 +18,6 @@ module Admin
end end
def index def index
@events = @program.events
@tracks = @program.tracks
@difficulty_levels = @program.difficulty_levels @difficulty_levels = @program.difficulty_levels
@event_types = @program.event_types @event_types = @program.event_types
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed) @tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
@ -43,7 +43,6 @@ module Admin
end end
def show def show
@tracks = @program.tracks
@event_types = @program.event_types @event_types = @program.event_types
@comments = @event.root_comments @comments = @event.root_comments
@comment_count = @event.comment_threads.count @comment_count = @event.comment_threads.count
@ -58,7 +57,6 @@ module Admin
def edit def edit
@event_types = @program.event_types @event_types = @program.event_types
@tracks = Track.all
@comments = @event.root_comments @comments = @event.root_comments
@comment_count = @event.comment_threads.count @comment_count = @event.comment_threads.count
@user = @event.submitter @user = @event.submitter
@ -187,16 +185,6 @@ module Admin
params.require(:comment).permit(:commentable, :body, :user_id) params.require(:comment).permit(:commentable, :body, :user_id)
end end
def get_event
@event = @conference.program.events.find(params[:id])
unless @event
redirect_to admin_conference_program_events_path(conference_id: @conference.short_title),
error: 'Error! Could not find event!'
return
end
@event
end
def update_state(transition, notice, mail = false, subject = false, send_mail = false) def update_state(transition, notice, mail = false, subject = false, send_mail = false)
alert = @event.update_state(transition, mail, subject, send_mail, params[:send_mail].blank?) alert = @event.update_state(transition, mail, subject, send_mail, params[:send_mail].blank?)
@ -208,5 +196,9 @@ module Admin
return redirect_back_or_to(admin_conference_program_events_path(conference_id: @conference.short_title)) && return return redirect_back_or_to(admin_conference_program_events_path(conference_id: @conference.short_title)) && return
end end
end end
def get_tracks
@tracks = Track.accessible_by(current_ability).where(program: @program).confirmed
end
end end
end end

View file

@ -1,6 +1,7 @@
module Admin module Admin
class OrganizationsController < Admin::BaseController class OrganizationsController < Admin::BaseController
load_and_authorize_resource :organization load_and_authorize_resource :organization
before_action :verify_user, only: [:assign_org_admins, :unassign_org_admins]
def index def index
@organizations = Organization.all @organizations = Organization.all
@ -43,8 +44,49 @@ module Admin
end end
end end
def assign_org_admins
if @user.has_role? 'organization_admin', @organization
flash[:error] = "User #{@user.email} already has the role organization admin"
elsif @user.add_role 'organization_admin', @organization
flash[:notice] = "Successfully added role organization admin to user #{@user.email}"
else
flash[:error] = "Coud not add role organization admin to #{@user.email}"
end
redirect_to admins_admin_organization_path(@organization)
end
def unassign_org_admins
if @user.remove_role 'organization_admin', @organization
flash[:notice] = "Successfully removed role organization admin from user #{@user.email}"
else
flash[:error] = "Could not remove role organization admin from user #{@user.email}"
end
redirect_to admins_admin_organization_path(@organization)
end
def admins
@role = @organization.roles.first
@users = @role.users
render 'show_org_admins'
end
private private
def user_params
params.require(:user).permit(:email)
end
def verify_user
@user = User.find_by(email: user_params[:email])
unless @user
redirect_to admins_admin_organization_path(@organization),
error: 'Could not find user. Please provide a valid email!'
return
end
end
def organization_params def organization_params
params.require(:organization).permit(:name, :description, :picture) params.require(:organization).permit(:name, :description, :picture)
end end

View file

@ -2,9 +2,11 @@ module Admin
class ReportsController < Admin::BaseController class ReportsController < Admin::BaseController
load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource :program, through: :conference, singleton: true
# For some reason this doesn't work, so a workaround is used
# load_and_authorize_resource :event, through: :program
def index def index
@events = @program.events @events = Event.accessible_by(current_ability).where(program: @program)
@events_commercials = Commercial.where(commercialable_type: 'Event', commercialable_id: @events.pluck(:id)) @events_commercials = Commercial.where(commercialable_type: 'Event', commercialable_id: @events.pluck(:id))
@events_missing_commercial = @events.where.not(id: @events_commercials.pluck(:commercialable_id)) @events_missing_commercial = @events.where.not(id: @events_commercials.pluck(:commercialable_id))
@events_with_requirements = @events.where.not(description: ['', nil]) @events_with_requirements = @events.where.not(description: ['', nil])

View file

@ -4,14 +4,21 @@ module Admin
# the schedule of a conference, which should not be accessed in the first place # the schedule of a conference, which should not be accessed in the first place
load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource :program, through: :conference, singleton: true
load_and_authorize_resource :schedule, through: :program load_and_authorize_resource :schedule, through: :program, except: [:new, :create]
load_resource :event_schedules, through: :schedule load_resource :event_schedules, through: :schedule
load_resource :selected_schedule, through: :program, singleton: true load_resource :selected_schedule, through: :program, singleton: true
load_resource :venue, through: :conference, singleton: true load_resource :venue, through: :conference, singleton: true
def index; end def index; end
def new
@schedule = @program.schedules.build(track: @program.tracks.new)
authorize! :new, @schedule
end
def create def create
@schedule = @program.schedules.new(schedule_params)
authorize! :create, @schedule
if @schedule.save if @schedule.save
redirect_to admin_conference_schedule_path(@conference.short_title, @schedule.id), redirect_to admin_conference_schedule_path(@conference.short_title, @schedule.id),
notice: 'Schedule was successfully created.' notice: 'Schedule was successfully created.'
@ -23,9 +30,23 @@ module Admin
def show def show
@event_schedules = @schedule.event_schedules @event_schedules = @schedule.event_schedules
@unscheduled_events = @program.events.confirmed - @schedule.events
@dates = @conference.start_date..@conference.end_date if @schedule.track
@rooms = @conference.venue.rooms if @conference.venue track = @schedule.track
@unscheduled_events = track.events.confirmed - @schedule.events
@dates = track.start_date..track.end_date
@rooms = [track.room]
else
@program.tracks.self_organized.confirmed.each do |t|
@event_schedules += t.selected_schedule.event_schedules if t.selected_schedule
end
self_organized_tracks_events = @program.tracks.self_organized.confirmed.map do |t|
t.events.confirmed
end
@unscheduled_events = @program.events.confirmed - @schedule.events - self_organized_tracks_events.flatten.compact
@dates = @conference.start_date..@conference.end_date
@rooms = @conference.venue.rooms if @conference.venue
end
end end
def destroy def destroy
@ -37,5 +58,11 @@ module Admin
error: "Schedule couldn't be deleted. #{@schedule.errors.full_messages.join('. ')}." error: "Schedule couldn't be deleted. #{@schedule.errors.full_messages.join('. ')}."
end end
end end
private
def schedule_params
params.require(:schedule).permit(:track_id) if params[:schedule]
end
end end
end end

View file

@ -47,7 +47,8 @@ module Admin
:include_tracks, :include_program, :include_cfp, :include_tracks, :include_program, :include_cfp,
:include_venue, :include_registrations, :include_venue, :include_registrations,
:include_tickets, :include_lodgings, :include_tickets, :include_lodgings,
:include_sponsors, :include_social_media) :include_sponsors, :include_social_media,
:include_booths)
end end
end end
end end

View file

@ -0,0 +1,16 @@
module Admin
class TicketScanningsController < Admin::BaseController
before_action :authenticate_user!
load_resource :physical_ticket, find_by: :token
# We authorize manually in these actions
skip_authorize_resource only: [:create]
def create
@ticket_scanning = TicketScanning.new(physical_ticket: @physical_ticket)
authorize! :create, @ticket_scanning
@ticket_scanning.save
redirect_to conferences_path,
notice: "Ticket with token #{@physical_ticket.token} successfully scanned."
end
end
end

View file

@ -50,7 +50,7 @@ module Admin
private private
def ticket_params def ticket_params
params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price) params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price, :registration_ticket)
end end
end end
end end

View file

@ -4,6 +4,9 @@ module Admin
load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource :program, through: :conference, singleton: true
load_and_authorize_resource through: :program, find_by: :short_name load_and_authorize_resource through: :program, find_by: :short_name
# Show flash message with ajax calls
after_action :prepare_unobtrusive_flash, only: :toggle_cfp_inclusion
def index; end def index; end
def show def show
@ -19,6 +22,8 @@ module Admin
def create def create
@track = @program.tracks.new(track_params) @track = @program.tracks.new(track_params)
@track.state = 'confirmed'
@track.cfp_active = true
if @track.save if @track.save
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
notice: 'Track successfully created.' notice: 'Track successfully created.'
@ -53,16 +58,77 @@ module Admin
def toggle_cfp_inclusion def toggle_cfp_inclusion
@track.cfp_active = !@track.cfp_active @track.cfp_active = !@track.cfp_active
if @track.save if @track.save
head :ok flash[:notice] = "Successfully changed cfp inclusion of #{@track.name} to #{@track.cfp_active}"
else else
head :unprocessable_entity flash[:error] = "Failed to toggle cfp inclusion of #{@track.name} to #{@track.cfp_active}"
end
respond_to do |format|
format.js
end
end
def restart
update_state(:restart, "Review for #{@track.name} started!")
end
def to_accept
update_state(:to_accept, "Track #{@track.name} marked as a possible acceptance!")
end
def accept
if @track.room && @track.start_date && @track.end_date
update_state(:accept, "Track #{@track.name} accepted!")
else
flash[:alert] = 'Please make sure that the track has a room and start/end dates before accepting it'
redirect_to edit_admin_conference_program_track_path(@conference.short_title, @track)
end
end
def confirm
update_state(:confirm, "Track #{@track.name} confirmed!")
end
def to_reject
update_state(:to_reject, "Track #{@track.name} marked as a possible rejection!")
end
def reject
update_state(:reject, "Track #{@track.name} rejected!")
end
def cancel
update_state(:cancel, "Track #{@track.name} canceled!")
end
def update_selected_schedule
if @track.update_attributes(params.require(:track).permit(:selected_schedule_id))
respond_to do |format|
format.js { render json: {} }
end
else
respond_to do |format|
format.js { render json: { errors: "The selected schedule couldn't been updated #{@track.errors.to_a.join('. ')}" }, status: 422 }
end
end end
end end
private private
def track_params def track_params
params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active) params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id)
end
def update_state(transition, notice)
errors = @track.update_state(transition)
if errors.blank?
flash[:notice] = notice
else
flash[:error] = errors
end
redirect_back_or_to(admin_conference_program_tracks_path(conference_id: @conference.short_title))
end end
end end
end end

View file

@ -1,17 +1,21 @@
module Admin module Admin
class VersionsController < Admin::BaseController class VersionsController < Admin::BaseController
skip_authorization_check load_resource :conference, find_by: :short_title, only: :index
load_and_authorize_resource class: PaperTrail::Version
def index def index
authorize! :index, PaperTrail::Version.new(item_type: 'User') @conferences_with_role = current_user.is_admin? ? Conference.pluck(:short_title) : Conference.with_role([:organizer, :cfp, :info_desk], current_user).pluck(:short_title)
conf_ids_for_organizer = current_user.is_admin? ? Conference.pluck(:id) : Conference.with_role(:organizer, current_user).pluck(:id)
@versions = PaperTrail::Version.where(["conference_id IN (?) OR item_type = 'User'", conf_ids_for_organizer]) if current_user.has_role? :organization_admin, :any
@conferences_with_role = Organization.with_role('organization_admin', current_user).map { |org| org.conferences.pluck :short_title }.flatten
end
@conferences_with_role.uniq!
return if @conference.blank?
@versions = PaperTrail::Version.where(conference_id: @conference.id).accessible_by(current_ability)
end end
def revert_attribute def revert_attribute
@version = PaperTrail::Version.find(params[:id])
authorize! :revert_attribute, @version
if params[:attribute] && @version.changeset.reject{ |_, values| values[0].blank? && values[1].blank? }.keys.include?(params[:attribute]) if params[:attribute] && @version.changeset.reject{ |_, values| values[0].blank? && values[1].blank? }.keys.include?(params[:attribute])
if @version.item[params[:attribute]] == @version.changeset[params[:attribute]][0] if @version.item[params[:attribute]] == @version.changeset[params[:attribute]][0]
flash[:error] = 'The item is already in the state that you are trying to revert it back to' flash[:error] = 'The item is already in the state that you are trying to revert it back to'
@ -33,9 +37,6 @@ module Admin
end end
def revert_object def revert_object
@version = PaperTrail::Version.find(params[:id])
authorize! :revert_object, @version
if @version.event != 'create' if @version.event != 'create'
if @version.reify.save if @version.reify.save
flash[:notice] = 'The selected change was successfully reverted' flash[:notice] = 'The selected change was successfully reverted'

View file

@ -0,0 +1,97 @@
class BoothsController < ApplicationController
before_action :authenticate_user!
load_resource :conference, find_by: :short_title
load_and_authorize_resource through: :conference
skip_authorize_resource only: [:withdraw, :confirm, :restart]
def index
@booths = current_user.booths.where(conference_id: @conference.id).uniq
end
def show; end
def new
@url = conference_booths_path(@conference.short_title)
end
def create
@url = conference_booths_path(@conference.short_title)
@booth.submitter = current_user
if @booth.save
redirect_to conference_booths_path,
notice: 'Booth successfully created.'
else
flash[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
render :new
end
end
def edit
@url = conference_booth_path(@conference.short_title, @booth.id)
end
def update
@url = conference_booth_path(@conference.short_title, @booth.id)
@booth.update_attributes(booth_params)
if @booth.save
redirect_to conference_booths_path,
notice: 'Booth successfully updated!'
else
flash[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}."
end
end
def destroy; end
def withdraw
authorize! :update, @booth
@url = conference_booth_path(@conference.short_title, @booth.id)
@booth.withdraw!
if @booth.save
redirect_to conference_booths_path,
notice: 'Booth successfully withdrawn'
else
flash[:error] = "Booth could not be withdrawn. #{@booth.errors.full_messages.to_sentence}."
end
end
def confirm
authorize! :update, @booth
@url = conference_booth_path(@conference.short_title, @booth.id)
@booth.confirm!
if @booth.save
redirect_to conference_booths_path,
notice: 'Booth successfully confirmed'
else
flash[:error] = "Booth could not be confirmed. #{@booth.errors.full_messages.to_sentence}."
end
end
def restart
authorize! :update, @booth
@url = conference_booth_path(@conference.short_title, @booth.id)
@booth.restart!
if @booth.save
redirect_to conference_booths_path,
notice: 'Booth successfully re-submitted'
else
flash[:error] = "Booth could not be re-submitted. #{@booth.errors.full_messages.to_sentence}."
end
end
private
def booth_params
params.require(:booth).permit(:title, :description, :reasoning, :state, :picture, :conference_id,
:created_at, :updated_at, :submitter_relationship, :website_url, responsible_ids: [])
end
end

View file

@ -1,18 +1,29 @@
class ConferencesController < ApplicationController class ConferencesController < ApplicationController
protect_from_forgery with: :null_session protect_from_forgery with: :null_session
before_action :respond_to_options before_action :respond_to_options
load_and_authorize_resource find_by: :short_title load_and_authorize_resource find_by: :short_title, except: :show
load_resource :program, through: :conference, singleton: true, except: :index
def index def index
@current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc) @current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
@antiquated = @conferences - @current @antiquated = @conferences - @current
end end
def show; end def show
@conference = if params[:id]
Conference.find_by_short_title(params[:id])
else
load_conference_by_domain
end
authorize! :show, @conference
@program = @conference.program
end
private private
def load_conference_by_domain
Conference.find_by(custom_domain: request.domain)
end
def respond_to_options def respond_to_options
respond_to do |format| respond_to do |format|
format.html { head :ok } format.html { head :ok }

View file

@ -1,7 +1,7 @@
class PhysicalTicketController < ApplicationController class PhysicalTicketController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
load_resource :conference, find_by: :short_title load_resource :conference, find_by: :short_title
load_and_authorize_resource load_and_authorize_resource find_by: :token
authorize_resource :conference_registrations, class: Registration authorize_resource :conference_registrations, class: Registration
def index def index
@ -13,6 +13,7 @@ class PhysicalTicketController < ApplicationController
@file_name = "ticket_for_#{@conference.short_title}" @file_name = "ticket_for_#{@conference.short_title}"
@user = @physical_ticket.user @user = @physical_ticket.user
@ticket_layout = @conference.ticket_layout.to_sym @ticket_layout = @conference.ticket_layout.to_sym
@qrcode_image = RQRCode::QRCode.new(@physical_ticket.token).as_png(size: 180, border_modules: 0)
respond_to do |format| respond_to do |format|
format.html format.html
format.pdf do format.pdf do

View file

@ -49,6 +49,13 @@ class ProposalsController < ApplicationController
# by default. # by default.
@event.speakers = [current_user] @event.speakers = [current_user]
@event.submitter = current_user @event.submitter = current_user
if Track.find_by(id: params[:event][:track_id]).try(:cfp_active) == false
flash.now[:error] = 'You have selected a track that doesn\'t accept proposals'
render action: 'new'
return
end
if @event.save if @event.save
ahoy.track 'Event submission', title: 'New submission' ahoy.track 'Event submission', title: 'New submission'
redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.' redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.'
@ -61,6 +68,12 @@ class ProposalsController < ApplicationController
def update def update
@url = conference_program_proposal_path(@conference.short_title, params[:id]) @url = conference_program_proposal_path(@conference.short_title, params[:id])
if Track.find_by(id: params[:event][:track_id]).try(:cfp_active) == false
flash.now[:error] = 'You have selected a track that doesn\'t accept proposals'
render action: 'edit'
return
end
if @event.update(event_params) if @event.update(event_params)
redirect_to conference_program_proposals_path(conference_id: @conference.short_title), redirect_to conference_program_proposals_path(conference_id: @conference.short_title),
notice: 'Proposal was successfully updated.' notice: 'Proposal was successfully updated.'

View file

@ -24,6 +24,13 @@ class SchedulesController < ApplicationController
return unless @current_day return unless @current_day
# the schedule takes you to the current time if it is beetween the start and the end time. # the schedule takes you to the current time if it is beetween the start and the end time.
@hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour) @hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
# Ids of the schedules of confrmed self_organized tracks along with the selected_schedule_id
@selected_schedules_ids = [@conference.program.selected_schedule_id]
@conference.program.tracks.self_organized.confirmed.each do |track|
@selected_schedules_ids << track.selected_schedule_id
end
@selected_schedules_ids.compact!
end end
def events def events
@ -32,11 +39,7 @@ class SchedulesController < ApplicationController
@events_schedules = @program.selected_event_schedules @events_schedules = @program.selected_event_schedules
@events_schedules = [] unless @events_schedules @events_schedules = [] unless @events_schedules
@unscheduled_events = if @program.selected_schedule @unscheduled_events = @program.events.confirmed - @events_schedules.map(&:event)
@program.events.confirmed - @program.selected_schedule.events
else
@program.events.confirmed
end
day = @conference.current_conference_day day = @conference.current_conference_day
@tag = day.strftime('%Y-%m-%d') if day @tag = day.strftime('%Y-%m-%d') if day

View file

@ -5,17 +5,19 @@ class SubscriptionsController < ApplicationController
def create def create
@subscription = current_user.subscriptions.build(conference_id: @conference.id) @subscription = current_user.subscriptions.build(conference_id: @conference.id)
if @subscription.save! if @subscription.save
redirect_to root_path, notice: "You have been subscribed to receive email notifications for #{@conference.short_title}." redirect_to root_path, notice: "You have subscribed to receive email notifications for #{@conference.title}."
else else
redirect_to root_path, error: subscription.errors.full_messages.to_sentence redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
end end
end end
def destroy def destroy
@subscription = current_user.subscriptions.find_by(conference_id: @conference.id) @subscription = current_user.subscriptions.find_by(conference_id: @conference.id)
redirect_to(root_path, error: "You are not subscribed to #{@conference.title}.") && return unless @subscription
if @subscription.destroy if @subscription.destroy
redirect_to root_path, notice: "You have been unsubscribed and now you will not be receiving email notifications for #{@conference.short_title}." redirect_to root_path, notice: "You have unsubscribed and you will not be receiving email notifications for #{@conference.title}."
else else
redirect_to root_path, error: @subscription.errors.full_messages.to_sentence redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
end end

View file

@ -2,6 +2,7 @@ class TicketPurchasesController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
load_resource :conference, find_by: :short_title load_resource :conference, find_by: :short_title
authorize_resource :conference_registrations, class: Registration authorize_resource :conference_registrations, class: Registration
authorize_resource
def create def create
current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all

View file

@ -4,7 +4,7 @@ class TracksController < ApplicationController
load_and_authorize_resource through: :program, find_by: :short_name load_and_authorize_resource through: :program, find_by: :short_name
def index def index
@tracks = current_user.tracks.where(program: @program) @tracks = @tracks.where(submitter: current_user)
end end
def show; end def show; end
@ -18,7 +18,6 @@ class TracksController < ApplicationController
def create def create
@track = @program.tracks.new(track_params) @track = @program.tracks.new(track_params)
@track.submitter = current_user @track.submitter = current_user
@track.state = 'new'
@track.cfp_active = false @track.cfp_active = false
if @track.save if @track.save
redirect_to conference_program_tracks_path(conference_id: @conference.short_title), redirect_to conference_program_tracks_path(conference_id: @conference.short_title),
@ -39,9 +38,33 @@ class TracksController < ApplicationController
end end
end end
def restart
update_state(:restart, "Track #{@track.name} re-submitted.")
end
def confirm
update_state(:confirm, "Track #{@track.name} confirmed.")
end
def withdraw
update_state(:withdraw, "Track #{@track.name} withdrawn.")
end
private private
def track_params def track_params
params.require(:track).permit(:name, :description, :color, :short_name) params.require(:track).permit(:name, :description, :color, :short_name, :start_date, :end_date, :relevance)
end
def update_state(transition, notice)
errors = @track.update_state(transition)
if errors.blank?
flash[:notice] = notice
else
flash[:error] = errors
end
redirect_back_or_to(conference_program_tracks_path(conference_id: @conference.short_title))
end end
end end

View file

@ -56,7 +56,7 @@ module ApplicationHelper
end end
def tracks(conference) def tracks(conference)
all = conference.program.tracks.map {|t| t.name} all = conference.program.tracks.confirmed.cfp_active.pluck(:name)
first = all[0...-1] first = all[0...-1]
last = all[-1] last = all[-1]
ts = '' ts = ''
@ -98,25 +98,6 @@ module ApplicationHelper
.reverse.sub(',', ' dna ').reverse .reverse.sub(',', ' dna ').reverse
end end
# Recieves a model_name and id
# Returns nil if model_name is invalid
# Returns object in its current state if its alive
# Otherwise Returns object state just before deletion
def current_or_last_object_state(model_name, id)
return nil unless id.present? && model_name.present?
begin
object = model_name.constantize.find_by(id: id)
rescue NameError
return nil
end
if object.nil?
object_last_version = PaperTrail::Version.where(item_type: model_name, item_id: id).last
object = object_last_version.reify if object_last_version
end
object
end
def normalize_array_length(hashmap, length) def normalize_array_length(hashmap, length)
hashmap.each do |_, value| hashmap.each do |_, value|
if value.length < length if value.length < length
@ -136,7 +117,7 @@ module ApplicationHelper
def concurrent_events(event) def concurrent_events(event)
return nil unless event.scheduled? && event.program.selected_event_schedules return nil unless event.scheduled? && event.program.selected_event_schedules
event_schedule = event.program.selected_event_schedules.find_by(event: event) event_schedule = event.program.selected_event_schedules.find { |es| es.event == event }
other_event_schedules = event.program.selected_event_schedules.reject { |other_event_schedule| other_event_schedule == event_schedule } other_event_schedules = event.program.selected_event_schedules.reject { |other_event_schedule| other_event_schedule == event_schedule }
concurrent_events = [] concurrent_events = []

View file

@ -39,4 +39,12 @@ module EventsHelper
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes) content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
end end
end end
def track_selector_input(form)
if @program.tracks.any?
form.input :track_id, as: :select,
collection: @program.tracks.where(state: 'confirmed', cfp_active: true).pluck(:name, :id),
include_blank: true
end
end
end end

View file

@ -15,6 +15,19 @@ module FormatHelper
end end
end end
def booth_status_icon(booth)
case booth.state
when 'new', 'to_reject', 'to_accept'
'fa-eye'
when 'accepted'
'fa-check text-muted'
when 'confirmed'
'fa-check text-success'
when 'rejected', 'withdrawn', 'canceled'
'fa-ban'
end
end
def event_progress_color(progress) def event_progress_color(progress)
progress = progress.to_i progress = progress.to_i
if progress == 100 if progress == 100

View file

@ -2,14 +2,6 @@ module PathsHelper
## ##
# Includes functions related to links or redirects # Includes functions related to links or redirects
## ##
def link_to_user(user_id)
user = User.find_by(id: user_id)
if user
link_to user.name, admin_user_path(id: user_id)
else
'Someone (probably via the console)'
end
end
def active_nav_li(link) def active_nav_li(link)
if current_page?(link) if current_page?(link)

View file

@ -2,35 +2,88 @@ module VersionsHelper
## ##
# Groups functions related to change description # Groups functions related to change description
## ##
def link_if_alive(version, link_text, link_url) def link_if_alive(version, link_text, link_url, conference)
version.item ? link_to(link_text, link_url) : link_text version.item && conference ? link_to(link_text, link_url) : "#{link_text} with ID #{version.item_id}"
end
def link_to_organization(organization_id)
return 'deleted organization' unless organization_id
org = Organization.find_by(id: organization_id)
return current_or_last_object_state('Organization', organization_id).try(:name) unless org
org.name.to_s
end
def link_to_conference(conference_id)
return 'deleted conference' if conference_id.nil?
conference = Conference.find_by(id: conference_id)
if conference
link_to conference.short_title,
edit_admin_conference_path(conference.short_title)
else
short_title = current_or_last_object_state('Conference', conference_id).try(:short_title) || ''
" #{short_title} with ID #{conference_id}"
end
end
def link_to_user(user_id)
return 'Someone (probably via the console)' unless user_id
user = User.find_by(id: user_id)
if user
link_to user.name, admin_user_path(id: user_id)
else
name = current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset['name'].second if PaperTrail::Version.where(item_type: 'User', item_id: user_id).any?
"#{name ? name : 'Unknown user'} with ID #{user_id}"
end
end
# Receives a model_name and id
# Returns nil if model_name is invalid
# Returns object in its current state if its alive
# Otherwise Returns object state just before deletion
def current_or_last_object_state(model_name, id)
return nil unless id.present? && model_name.present?
begin
object = model_name.constantize.find_by(id: id)
rescue NameError
return nil
end
if object.nil?
object_last_version = PaperTrail::Version.where(item_type: model_name, item_id: id).last
object = object_last_version.reify if object_last_version
end
object
end end
def subscription_change_description(version) def subscription_change_description(version)
user = current_or_last_object_state(version.item_type, version.item_id).user user_id = current_or_last_object_state(version.item_type, version.item_id).user_id
user_name = user.name unless user.id.to_s == version.whodunnit user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second unless user_id.to_s == version.whodunnit
version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from" version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from"
end end
def registration_change_description(version) def registration_change_description(version)
if version.item_type == 'Registration' if version.item_type == 'Registration'
user = current_or_last_object_state(version.item_type, version.item_id).user user_id = current_or_last_object_state(version.item_type, version.item_id).user_id
elsif version.item_type == 'EventsRegistration' elsif version.item_type == 'EventsRegistration'
registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id
user = current_or_last_object_state('Registration', registration_id).user user_id = current_or_last_object_state('Registration', registration_id).user_id
end end
user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second
if user.id.to_s == version.whodunnit if user_id.to_s == version.whodunnit
case version.event case version.event
when 'create' then 'registered to' when 'create' then 'registered to'
when 'update' then "updated #{updated_attributes(version)} of the registration for" when 'update' then "updated #{updated_attributes(version)} of the registration for"
when 'destroy' then 'unregistered from' when 'destroy' then 'unregistered from'
end end
else else
case version.event case version.event
when 'create' then "registered #{user.name} to" when 'create' then "registered #{user_name} to"
when 'update' then "updated #{updated_attributes(version)} of #{user.name}'s registration for" when 'update' then "updated #{updated_attributes(version)} of #{user_name}'s registration for"
when 'destroy' then "unregistered #{user.name} from" when 'destroy' then "unregistered #{user_name} from"
end end
end end
end end

View file

@ -8,6 +8,22 @@ class Mailbot < ActionMailer::Base
conference.email_settings.registration_body)) conference.email_settings.registration_body))
end end
def ticket_confirmation_mail(ticket_purchase)
@ticket_purchase = ticket_purchase
@conference = ticket_purchase.conference
@user = ticket_purchase.user
PhysicalTicket.last(ticket_purchase.quantity).each do |physical_ticket|
pdf = TicketPdf.new(@conference, @user, physical_ticket, @conference.ticket_layout.to_sym, "ticket_for_#{@conference.short_title}_#{physical_ticket.id}")
attachments["ticket_for_#{@conference.short_title}_#{physical_ticket.id}.pdf"] = pdf.render
end
mail(to: @user.email,
from: @conference.contact.email,
template_name: 'ticket_confirmation_template',
subject: "#{@conference.title} | Ticket Confirmation and PDF!")
end
def acceptance_mail(event) def acceptance_mail(event)
conference = event.program.conference conference = event.program.conference
@ -81,6 +97,24 @@ class Mailbot < ActionMailer::Base
conference.email_settings.cfp_dates_updated_body)) conference.email_settings.cfp_dates_updated_body))
end end
def conference_booths_acceptance_mail(booth)
conference = booth.conference
mail(to: booth.submitter.email,
from: conference.contact.email,
subject: conference.email_settings.booths_acceptance_subject,
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_acceptance_body))
end
def conference_booths_rejection_mail(booth)
conference = booth.conference
mail(to: booth.submitter.email,
from: conference.contact.email,
subject: conference.email_settings.booths_rejection_subject,
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_rejection_body))
end
def event_comment_mail(comment, user) def event_comment_mail(comment, user)
@comment = comment @comment = comment
@event = @comment.commentable @event = @comment.commentable

View file

@ -75,13 +75,21 @@ class Ability
can [:new, :create], Payment, user_id: user.id can [:new, :create], Payment, user_id: user.id
can [:index, :show], PhysicalTicket, user: user can [:index, :show], PhysicalTicket, user: user
can [:new, :create], Booth do |booth|
booth.new_record? && booth.conference.program.cfps.for_booths.try(:open?)
end
can [:edit, :update, :index, :show], Booth do |booth|
booth.users.include?(user)
end
can [:create, :destroy], Subscription, user_id: user.id can [:create, :destroy], Subscription, user_id: user.id
can [:new, :create], Event do |event| can [:new, :create], Event do |event|
event.program.cfp_open? && event.new_record? event.program.cfp_open? && event.new_record?
end end
can [:update, :show, :delete, :index], Event do |event| can [:update, :show, :index], Event do |event|
event.users.include?(user) event.users.include?(user)
end end
@ -89,6 +97,16 @@ class Ability
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
can [:destroy], Openid can [:destroy], Openid
can [:new, :create], Track do |track|
track.new_record? && track.program.cfps.for_tracks.try(:open?)
end
can [:index, :show, :restart, :confirm, :withdraw], Track, submitter_id: user.id
can [:edit, :update], Track do |track|
user == track.submitter && !(track.accepted? || track.confirmed?)
end
end end
# Abilities for users with roles wandering around in non-admin views. # Abilities for users with roles wandering around in non-admin views.

View file

@ -18,7 +18,6 @@ class AdminAbility
end end
def common_abilities_for_roles(user) def common_abilities_for_roles(user)
can :manage, User, id: user.id
can :manage, Registration, user_id: user.id can :manage, Registration, user_id: user.id
can :index, Conference can :index, Conference
@ -29,7 +28,7 @@ class AdminAbility
conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user) conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
end end
can :index, Organization can [:index, :admins], Organization
can :index, Ticket can :index, Ticket
can :manage, TicketPurchase, user_id: user.id can :manage, TicketPurchase, user_id: user.id
can [:new, :create], Payment, user_id: user.id can [:new, :create], Payment, user_id: user.id
@ -40,10 +39,6 @@ class AdminAbility
event.program.cfp_open? && event.new_record? event.program.cfp_open? && event.new_record?
end end
can [:update, :show, :delete, :index], Event do |event|
event.users.include?(user)
end
# can manage the commercials of their own events # can manage the commercials of their own events
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
@ -75,6 +70,11 @@ class AdminAbility
cannot :destroy, Track do |track| cannot :destroy, Track do |track|
track.self_organized? track.self_organized?
end end
# Can't accept a booth when booth_limit is reached
cannot :accept, Booth do |booth|
conference = booth.conference
conference.maximum_accepted_booths?
end
end end
# Abilities for signed in users with roles # Abilities for signed in users with roles
@ -92,13 +92,11 @@ class AdminAbility
org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id)
conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id) conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id)
can [:read, :update, :destroy], Organization, id: org_ids_for_organization_admin can [:read, :update, :destroy, :assign_org_admins, :unassign_org_admins, :admins], Organization, id: org_ids_for_organization_admin
can :new, Conference can :new, Conference
can :manage, Conference, organization_id: org_ids_for_organization_admin can :manage, Conference, organization_id: org_ids_for_organization_admin
can [:index, :show], Role can [:index, :show], Role
can [:edit, :update], Role do |role|
role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id)
end
signed_in_with_organizer_role(user, conf_ids_for_organization_admin) signed_in_with_organizer_role(user, conf_ids_for_organization_admin)
end end
@ -119,7 +117,10 @@ class AdminAbility
can :manage, Commercial, commercialable_type: 'Conference', can :manage, Commercial, commercialable_type: 'Conference',
commercialable_id: conf_ids commercialable_id: conf_ids
can :manage, Registration, conference_id: conf_ids can :manage, Registration, conference_id: conf_ids
can :manage, RegistrationPeriod, conference_id: conf_ids can :manage, RegistrationPeriod do |registration_period|
conference = registration_period.conference
conf_ids.include?(conference.id) && conference.tickets.for_registration.any?
end
can :manage, Booth, conference_id: conf_ids can :manage, Booth, conference_id: conf_ids
can :manage, Question, conference_id: conf_ids can :manage, Question, conference_id: conf_ids
can :manage, Question do |question| can :manage, Question do |question|
@ -145,6 +146,10 @@ class AdminAbility
can :manage, Sponsor, conference_id: conf_ids can :manage, Sponsor, conference_id: conf_ids
can :manage, SponsorshipLevel, conference_id: conf_ids can :manage, SponsorshipLevel, conference_id: conf_ids
can :manage, Ticket, conference_id: conf_ids can :manage, Ticket, conference_id: conf_ids
can :create, TicketScanning do |ticket_scanning|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
conf_ids.include? conf_id
end
can :index, Comment, commentable_type: 'Event', can :index, Comment, commentable_type: 'Event',
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id) commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id)
@ -158,9 +163,8 @@ class AdminAbility
role.resource_type == 'Track' && (track_ids.include? role.resource_id) role.resource_type == 'Track' && (track_ids.include? role.resource_id)
end end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'User'
version.item_type == 'User' || (conf_ids.include? version.conference_id) can [:index, :revert_object, :revert_attribute], PaperTrail::Version, conference_id: conf_ids
end
end end
def signed_in_with_cfp_role(user) def signed_in_with_cfp_role(user)
@ -199,9 +203,10 @@ class AdminAbility
(Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id) (Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id)
end end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Event', conference_id: conf_ids_for_cfp can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Vote', conference_id: conf_ids_for_cfp item_type: %w[Event EventType Track DifficultyLevel EmailSettings Room Cfp Program Comment], conference_id: conf_ids_for_cfp
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
["item_type = 'Commercial' AND conference_id IN (?) AND (object LIKE '%Event%' OR object_changes LIKE '%Event%')", conf_ids_for_cfp] do |version|
version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) && version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) &&
(version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event')) (version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event'))
end end
@ -220,6 +225,10 @@ class AdminAbility
can :manage, Question do |question| can :manage, Question do |question|
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty? !(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
end end
can :create, TicketScanning do |ticket_scanning|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
conf_ids_for_info_desk.include? conf_id
end
# Abilities for Role (Conference resource) # Abilities for Role (Conference resource)
can [:index, :show], Role do |role| can [:index, :show], Role do |role|
@ -231,6 +240,7 @@ class AdminAbility
role.resource_type == 'Conference' && role.name == 'info_desk' && role.resource_type == 'Conference' && role.name == 'info_desk' &&
(Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id) (Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id)
end end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Registration', conference_id: conf_ids_for_info_desk
end end
def signed_in_with_volunteers_coordinator_role(user) def signed_in_with_volunteers_coordinator_role(user)
@ -276,6 +286,10 @@ class AdminAbility
can :manage, Track, id: track_ids_for_track_organizer can :manage, Track, id: track_ids_for_track_organizer
cannot [:edit, :update], Track do |track|
track.self_organized_and_accepted_or_confirmed?
end
# Show Roles in the admin sidebar and allow authorization of the index action # Show Roles in the admin sidebar and allow authorization of the index action
can [:index, :show], Role do |role| can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track' role.resource_type == 'Conference' || role.resource_type == 'Track'
@ -284,5 +298,27 @@ class AdminAbility
can :toggle_user, Role do |role| can :toggle_user, Role do |role|
role.resource_type == 'Track' && track_ids_for_track_organizer.include?(role.resource_id) role.resource_type == 'Track' && track_ids_for_track_organizer.include?(role.resource_id)
end end
# Show Events in the admin sidebar
can :update, Event do |event|
event.new_record? && conf_ids_for_track_organizer.include?(event.program.conference_id)
end
can :manage, Event, track_id: track_ids_for_track_organizer
can :manage, Commercial, commercialable_type: 'Event',
commercialable_id: Event.where(track_id: track_ids_for_track_organizer).pluck(:id)
# Show Scheduless in the admin sidebar
can :update, Schedule do |schedule|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id)
end
# Show new track schedule button
can :new, Schedule do |schedule|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id) && schedule.track.try(:new_record?)
end
can :manage, Schedule, track_id: track_ids_for_track_organizer
can :manage, EventSchedule, schedule: { track_id: track_ids_for_track_organizer }
end end
end end

View file

@ -25,6 +25,9 @@ class Booth < ActiveRecord::Base
:submitter_relationship, :submitter_relationship,
presence: true presence: true
scope :accepted, -> { where(state: 'accepted') }
scope :confirmed, -> { where(state: 'confirmed') }
mount_uploader :picture, PictureUploader, mount_on: :logo_link mount_uploader :picture, PictureUploader, mount_on: :logo_link
state_machine initial: :new do state_machine initial: :new do
@ -35,12 +38,16 @@ class Booth < ActiveRecord::Base
state :to_reject state :to_reject
state :rejected state :rejected
state :canceled state :canceled
state :confirmed
event :restart do event :restart do
transitions to: :new, from: [:withdrawn, :to_accept, :to_reject, :canceled] transitions to: :new, from: [:withdrawn, :rejected, :canceled]
end end
event :withdraw do event :withdraw do
transitions to: :withdrawn, from: [:new, :to_accept, :accepted, :to_reject, :rejected] transitions to: :withdrawn, from: [:new, :to_accept, :accepted, :to_reject, :rejected, :confirmed]
end
event :confirm do
transitions to: :confirmed, from: [:accepted]
end end
event :to_accept do event :to_accept do
transitions to: :to_accept, from: [:new, :to_reject] transitions to: :to_accept, from: [:new, :to_reject]
@ -55,7 +62,7 @@ class Booth < ActiveRecord::Base
transitions to: :rejected, from: [:new, :to_reject] transitions to: :rejected, from: [:new, :to_reject]
end end
event :cancel do event :cancel do
transitions to: :canceled, from: [:accepted, :rejected] transitions to: :canceled, from: [:accepted, :rejected, :to_accept, :to_reject, :confirmed]
end end
end end

View file

@ -1,9 +1,7 @@
# cannot delete program if there are events submitted # cannot delete program if there are events submitted
class Cfp < ActiveRecord::Base class Cfp < ActiveRecord::Base
TYPES = %w(events booths).freeze TYPES = %w(events booths tracks).freeze
scope :for_events, (-> { find_by(cfp_type: 'events') })
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id } has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
belongs_to :program belongs_to :program
@ -78,6 +76,33 @@ class Cfp < ActiveRecord::Base
(start_date..end_date).cover?(Date.current) (start_date..end_date).cover?(Date.current)
end end
##
# Finds the cfp for events if it exists
#
# ====Returns
# * +Cfp+ -> The cfp with type 'events'
def self.for_events
find_by(cfp_type: 'events')
end
##
# Finds the cfp for tracks if it exists
#
# ====Returns
# * +Cfp+ -> The cfp with type 'tracks'
def self.for_tracks
find_by(cfp_type: 'tracks')
end
##
# Finds the cfp for booths if it exists
#
# ====Returns
# * +Cfp+ -> The cfp with type 'booths'
def self.for_booths
find_by(cfp_type: 'booths')
end
private private
def before_end_of_conference def before_end_of_conference

View file

@ -26,7 +26,11 @@ class Conference < ActiveRecord::Base
has_many :ticket_purchases, dependent: :destroy has_many :ticket_purchases, dependent: :destroy
has_many :payments, dependent: :destroy has_many :payments, dependent: :destroy
has_many :supporters, through: :ticket_purchases, source: :user has_many :supporters, through: :ticket_purchases, source: :user
has_many :tickets, dependent: :destroy has_many :tickets, dependent: :destroy do
def for_registration
where(registration_ticket: true)
end
end
has_many :resources, dependent: :destroy has_many :resources, dependent: :destroy
has_many :booths, dependent: :destroy has_many :booths, dependent: :destroy
@ -738,6 +742,15 @@ class Conference < ActiveRecord::Base
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0 (start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
end end
##
#
# ====Returns
# * +True+ -> if accepted booths are equal to the booth limit
# * +False+ -> Accepted booths have not reached the booth limit
def maximum_accepted_booths?
booth_limit > 0 && booths.accepted.count + booths.confirmed.count >= booth_limit
end
## ##
# Return the current conference object to be used in RevisionCount # Return the current conference object to be used in RevisionCount
# #
@ -747,6 +760,10 @@ class Conference < ActiveRecord::Base
self self
end end
def to_param
short_title
end
private private
# Returns a different html colour for every i and consecutive colors are # Returns a different html colour for every i and consecutive colors are

View file

@ -3,7 +3,7 @@ class EmailSettings < ActiveRecord::Base
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id } has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
def get_values(conference, user, event = nil) def get_values(conference, user, event = nil, booth = nil)
h = { h = {
'email' => user.email, 'email' => user.email,
'name' => user.name, 'name' => user.name,
@ -45,6 +45,10 @@ class EmailSettings < ActiveRecord::Base
h['proposalslink'] = Rails.application.routes.url_helpers.conference_program_proposals_url( h['proposalslink'] = Rails.application.routes.url_helpers.conference_program_proposals_url(
conference.short_title, host: (ENV['OSEM_HOSTNAME'] || 'localhost:3000')) conference.short_title, host: (ENV['OSEM_HOSTNAME'] || 'localhost:3000'))
end end
if booth
h['booth_title'] = booth.title
end
h h
end end
@ -58,6 +62,11 @@ class EmailSettings < ActiveRecord::Base
parse_template(conf_update_template, values) parse_template(conf_update_template, values)
end end
def generate_booth_mail(booth, booth_template)
values = get_values(booth.conference, booth.submitter, nil, booth)
parse_template(booth_template, values)
end
private private
def parse_template(text, values) def parse_template(text, values)

View file

@ -45,6 +45,7 @@ class Event < ActiveRecord::Base
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true } validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
validate :max_attendees_no_more_than_room_size validate :max_attendees_no_more_than_room_size
validate :valid_track
scope :confirmed, -> { where(state: 'confirmed') } scope :confirmed, -> { where(state: 'confirmed') }
scope :canceled, -> { where(state: 'canceled') } scope :canceled, -> { where(state: 'canceled') }
@ -84,7 +85,7 @@ class Event < ActiveRecord::Base
# ====Returns # ====Returns
# * +true+ or +false+ # * +true+ or +false+
def scheduled? def scheduled?
event_schedules.find_by(schedule_id: program.selected_schedule_id).present? event_schedules.find_by(schedule_id: selected_schedule_id).present?
end end
def registration_possible? def registration_possible?
@ -242,14 +243,18 @@ class Event < ActiveRecord::Base
def room def room
# We use try(:selected_schedule_id) because this function is used for # We use try(:selected_schedule_id) because this function is used for
# validations so program could not be present there # validations so program could not be present there
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id)).try(:room) if track.try(:self_organized?)
track.room
else
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id)).try(:room)
end
end end
## ##
# Returns the start time at which this event is scheduled # Returns the start time at which this event is scheduled
# #
def time def time
event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time) event_schedules.find_by(schedule_id: selected_schedule_id).try(:start_time)
end end
def conference def conference
@ -303,4 +308,25 @@ class Event < ActiveRecord::Base
def conference_id def conference_id
program.conference_id program.conference_id
end end
##
# Allow only confirmed tracks that belong to the same program as the event
#
def valid_track
return unless track && track.program && program
errors.add(:track, 'is invalid') unless track.confirmed? && track.program == program
end
##
# Return the id of the selected schedule
#
# ====Returns
# * +Integer+ -> selected_schedule_id of self-organized track or program
def selected_schedule_id
if track.try(:self_organized?)
track.selected_schedule_id
else
program.selected_schedule_id
end
end
end end

View file

@ -12,6 +12,9 @@ class EventSchedule < ActiveRecord::Base
validates :event, uniqueness: { scope: :schedule } validates :event, uniqueness: { scope: :schedule }
validate :start_after_end_hour validate :start_after_end_hour
validate :start_before_start_hour validate :start_before_start_hour
validate :same_room_as_track
validate :during_track
validate :valid_schedule
scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') } scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') }
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') } scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
@ -52,4 +55,35 @@ class EventSchedule < ActiveRecord::Base
def conference_id def conference_id
schedule.program.conference_id schedule.program.conference_id
end end
##
# Validates that the event is scheduled in the same room as its track
#
def same_room_as_track
return unless event.try(:track).try(:room)
errors.add(:room, "must be the same as the track's room (#{event.track.room.name})") unless event.track.room == room
end
##
# Validates that the event is scheduled within its track's time slot
#
def during_track
return unless event.try(:track) && start_time
if event.track.try(:start_date) && event.track.start_date > start_time
errors.add(:start_time, "can't be before the track's start date (#{event.track.start_date})")
end
if event.track.try(:end_date) && event.track.end_date + 1.day < end_time
errors.add(:end_time, "can't be after the track's end date (#{event.track.end_date})")
end
end
##
# Validates that the event is scheduled in its self-organized tracks's schedules
#
def valid_schedule
return unless event.try(:track).try(:self_organized?) && schedule
errors.add(:schedule, "must be one of #{event.track.name} track's schedules") unless event.track.schedules.include?(schedule)
end
end end

View file

@ -1,6 +1,8 @@
class Organization < ActiveRecord::Base class Organization < ActiveRecord::Base
resourcify :roles, dependent: :delete_all resourcify :roles, dependent: :delete_all
has_paper_trail
has_many :conferences, dependent: :destroy has_many :conferences, dependent: :destroy
after_create :create_roles after_create :create_roles

View file

@ -4,4 +4,19 @@ class PhysicalTicket < ActiveRecord::Base
has_one :conference, through: :ticket_purchase has_one :conference, through: :ticket_purchase
has_one :user, through: :ticket_purchase has_one :user, through: :ticket_purchase
has_many :ticket_scannings has_many :ticket_scannings
before_create :set_token
private
def set_token
self.token = generate_token
end
def generate_token
loop do
token = SecureRandom.hex(10)
break token unless PhysicalTicket.exists?(token: token)
end
end
end end

View file

@ -71,7 +71,11 @@ class Program < ActiveRecord::Base
# Returns all event_schedules for the selected schedule ordered by start_time # Returns all event_schedules for the selected schedule ordered by start_time
def selected_event_schedules def selected_event_schedules
selected_schedule.event_schedules.order(start_time: :asc) if selected_schedule event_schedules = selected_schedule.event_schedules.order(start_time: :asc) if selected_schedule
tracks.self_organized.confirmed.order(start_date: :asc).each do |track|
event_schedules += track.selected_schedule.event_schedules.order(start_time: :asc) if track.selected_schedule
end
event_schedules.sort_by(&:start_time) if event_schedules
end end
## ##

View file

@ -2,6 +2,7 @@ class Room < ActiveRecord::Base
include RevisionCount include RevisionCount
belongs_to :venue belongs_to :venue
has_many :event_schedules, dependent: :destroy has_many :event_schedules, dependent: :destroy
has_many :tracks
has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id } has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id }

View file

@ -1,5 +1,6 @@
class Schedule < ActiveRecord::Base class Schedule < ActiveRecord::Base
belongs_to :program belongs_to :program
belongs_to :track
has_many :event_schedules, dependent: :destroy has_many :event_schedules, dependent: :destroy
has_many :events, through: :event_schedules has_many :events, through: :event_schedules

View file

@ -1,5 +1,4 @@
class Subscription < ActiveRecord::Base class Subscription < ActiveRecord::Base
validates :user_id, uniqueness: { scope: [:conference_id] }
belongs_to :conference belongs_to :conference
belongs_to :user belongs_to :user

View file

@ -69,6 +69,7 @@ class TicketPurchase < ActiveRecord::Base
PhysicalTicket.transaction do PhysicalTicket.transaction do
quantity.times { physical_tickets.create } quantity.times { physical_tickets.create }
end end
Mailbot.ticket_confirmation_mail(self).deliver_later
end end
end end

View file

@ -1,13 +1,17 @@
class Track < ActiveRecord::Base class Track < ActiveRecord::Base
include ActiveRecord::Transitions
include RevisionCount include RevisionCount
resourcify :roles, dependent: :delete_all resourcify :roles, dependent: :delete_all
belongs_to :program belongs_to :program
belongs_to :submitter, class_name: 'User' belongs_to :submitter, class_name: 'User'
belongs_to :room
belongs_to :selected_schedule, class_name: 'Schedule'
has_many :events, dependent: :nullify has_many :events, dependent: :nullify
has_many :schedules
has_paper_trail only: [:name, :description, :color], meta: { conference_id: :conference_id } has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
before_create :generate_guid before_create :generate_guid
validates :name, presence: true validates :name, presence: true
@ -18,12 +22,61 @@ class Track < ActiveRecord::Base
uniqueness: { uniqueness: {
scope: :program scope: :program
} }
validates :state, presence: true, if: :self_organized? validates :state,
validates :cfp_active, inclusion: { in: [true, false] }, if: :self_organized? presence: true,
inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }
validates :cfp_active, inclusion: { in: [true, false] }
validates :start_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
validates :end_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
validates :room, presence: true, if: :self_organized_and_accepted_or_confirmed?
validates :relevance, presence: true, if: :self_organized?
validates :description, presence: true, if: :self_organized?
validate :valid_dates
validate :valid_room, if: :self_organized_and_accepted_or_confirmed?
validate :overlapping
before_validation :capitalize_color before_validation :capitalize_color
after_create :create_organizer_role, if: :self_organized? scope :accepted, -> { where(state: 'accepted') }
scope :confirmed, -> { where(state: 'confirmed') }
scope :cfp_active, -> { where(cfp_active: true) }
scope :self_organized, -> { where.not(submitter: nil) }
state_machine initial: :pending do
state :new
state :to_accept
state :accepted
state :confirmed
state :to_reject
state :rejected
state :canceled
state :withdrawn
event :restart do
transitions to: :new, from: [:rejected, :withdrawn, :canceled]
end
event :to_accept do
transitions to: :to_accept, from: [:new]
end
event :accept do
transitions to: :accepted, from: [:new, :to_accept], on_transition: :create_organizer_role
end
event :confirm do
transitions to: :confirmed, from: [:accepted], on_transition: :assign_role_to_submitter
end
event :to_reject do
transitions to: :to_reject, from: [:new]
end
event :reject do
transitions to: :rejected, from: [:new, :to_reject]
end
event :cancel do
transitions to: :canceled, from: [:to_accept, :to_reject, :accepted, :confirmed], on_transition: :revoke_role_and_cleanup
end
event :withdraw do
transitions to: :withdrawn, from: [:new, :to_accept, :to_reject, :accepted, :confirmed], on_transition: :revoke_role_and_cleanup
end
end
def conference def conference
program.conference program.conference
@ -43,6 +96,80 @@ class Track < ActiveRecord::Base
short_name short_name
end end
def transition_possible?(transition)
self.class.state_machine.events_for(current_state).include?(transition)
end
# Gives the role of the track_organizer to the submitter
def assign_role_to_submitter
submitter.add_role 'track_organizer', self
end
##
# Revokes the track organizer role, destroys the track's schedule, removes the
# track from events that have it set and reverts their state to new
#
def revoke_role_and_cleanup
role = Role.find_by(name: 'track_organizer', resource: self)
if role
role.users.each do |user|
user.remove_role 'track_organizer', self
end
end
self.selected_schedule_id = nil
save!
schedules.each(&:destroy!)
events.each do |event|
event.track = nil
event.state = 'new'
event.save!
end
end
##
# Checks if the track is accepted
# ====Returns
# * +true+ -> If the track's state is 'accepted'
# * +false+ -> If the track's state isn't 'accepted'
def accepted?
state == 'accepted'
end
##
# Checks if the track is confirmed
# ====Returns
# * +true+ -> If the track's state is 'confirmed'
# * +false+ -> If the track's state isn't 'confirmed'
def confirmed?
state == 'confirmed'
end
##
# Checks if a self-organized track is accepted or confirmed
# ====Returns
# * +true+ -> If the track's state is 'accepted' or 'confirmed'
# * +false+ -> If the track's state is neither 'accepted' nor 'confirmed'
def self_organized_and_accepted_or_confirmed?
self_organized? && (accepted? || confirmed?)
end
def update_state(transition)
error = ''
begin
send(transition)
rescue Transitions::InvalidTransition => e
error += "State update failed. #{e.message} "
end
error += errors.full_messages.join(', ') unless save
error
end
private private
def generate_guid def generate_guid
@ -66,4 +193,50 @@ class Track < ActiveRecord::Base
def create_organizer_role def create_organizer_role
Role.where(name: 'track_organizer', resource: self).first_or_create(description: 'For the organizers of the Track') Role.where(name: 'track_organizer', resource: self).first_or_create(description: 'For the organizers of the Track')
end end
def valid_dates
if start_date && program && program.conference && program.conference.start_date && (start_date < program.conference.start_date)
errors.add(:start_date, "can't be before the conference start date (#{program.conference.start_date})")
end
if end_date && program && program.conference && program.conference.start_date && (end_date < program.conference.start_date)
errors.add(:end_date, "can't be before the conference start date (#{program.conference.start_date})")
end
if start_date && program && program.conference && program.conference.end_date && (start_date > program.conference.end_date)
errors.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})")
end
if end_date && program && program.conference && program.conference.end_date && (end_date > program.conference.end_date)
errors.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})")
end
if start_date && end_date && (start_date > end_date)
errors.add(:start_date, 'can\'t be after the end date')
end
end
##
# Verify that the room is a room of the conference
def valid_room
if room && room.venue && room.venue.conference && program && program.conference && (program.conference != room.venue.conference)
errors.add(:room, "must be a room of #{program.conference.venue.name}")
end
end
##
# Check that there is no other track in the same room with overlapping dates
def overlapping
return unless start_date && end_date && room && program.try(:tracks)
(program.tracks.accepted + program.tracks.confirmed - [self]).each do |other_track|
if other_track.room == room &&
other_track.start_date && other_track.end_date &&
(other_track.start_date <= start_date && other_track.end_date >= start_date ||
other_track.start_date <= end_date && other_track.end_date >= end_date ||
start_date <= other_track.start_date && other_track.end_date <= end_date)
errors.add(:track, 'has overlapping dates with a confirmed or accepted track in the same room')
break
end
end
end
end end

View file

@ -165,7 +165,11 @@ class User < ActiveRecord::Base
def get_roles def get_roles
result = {} result = {}
roles.each do |role| roles.each do |role|
resource = Conference.find(role.resource_id).short_title resource = if role.resource_type == 'Conference'
Conference.find(role.resource_id).short_title
elsif role.resource_type == 'Track'
Track.find(role.resource_id).name
end
if result[role.name].nil? if result[role.name].nil?
result[role.name] = [resource] result[role.name] = [resource]
else else

View file

@ -77,5 +77,9 @@ class TicketPdf < Prawn::Document
move_up 180 move_up 180
end end
def draw_fourth_square; end def draw_fourth_square
x = @mid_horizontal + (@right - @mid_horizontal - 180) / 2
y = cursor - (bounds.top - @mid_vertical - 180) / 2
print_qr_code(@physical_ticket.token, pos: [x, y], extent: 180, stroke: false)
end
end end

View file

@ -1,17 +1,32 @@
- if booth.transition_possible? :accept - if booth.transition_possible? :accept
%li= link_to 'Accept booth', - if can? :accept, booth
accept_admin_conference_booth_path(@conference.short_title, booth), - if @conference.booth_limit > 0
method: :patch, id: "accept_booth_#{booth.id}" - confirm_message = ' You are able to accept '+ pluralize(@conference.booth_limit - (@conference.booths.accepted.count + @conference.booths.confirmed.count), 'more booth') + " (booth limit set to #{@conference.booth_limit}). Are you sure you want to accept this one?"
- if @conference.email_settings.send_on_booths_acceptance
- link = 'Accept with email'
- confirm_message = "By accepting this booth, an email will be sent informing the submitter for the acceptance. You may change the state to \'To accept\' until you are completely sure." + confirm_message
- else
- link = 'Accept booth'
%li= link_to link,
accept_admin_conference_booth_path(@conference.short_title, booth),
method: :patch ,id: "accept_booth_#{booth.id}",
data: (confirm_message ? { confirm: confirm_message } : nil)
- if booth.transition_possible? :reject - if booth.transition_possible? :reject
%li= link_to 'Reject booth', - if @conference.email_settings.send_on_booths_rejection
- link = 'Reject with email'
- else
- link = 'Reject'
%li= link_to link,
reject_admin_conference_booth_path(@conference.short_title, booth), reject_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, confirm: 'Are you sure?', id: "reject_booth_#{booth.id}" method: :patch, id: "reject_booth_#{booth.id}",
data: (@conference.email_settings.send_on_booths_rejection ? { confirm: 'By rejecting this booth, an email will be sent informing the submitter about the rejection. You may change the state to \'To reject\' until you are completely sure.'} : nil)
- if booth.transition_possible? :to_reject - if booth.transition_possible? :to_reject
%li= link_to 'To reject booth', %li= link_to 'To reject booth',
to_reject_admin_conference_booth_path(@conference.short_title, booth), to_reject_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, confirm: 'Are you sure?', id: "to_reject_booth_#{booth.id}" method: :patch, id: "to_reject_booth_#{booth.id}"
- if booth.transition_possible? :restart - if booth.transition_possible? :restart
%li= link_to 'Start review', %li= link_to 'Start review',
@ -27,3 +42,8 @@
%li= link_to 'Cancel booth', %li= link_to 'Cancel booth',
cancel_admin_conference_booth_path(@conference.short_title, booth), cancel_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "cancel_booth_#{booth.id}" method: :patch, id: "cancel_booth_#{booth.id}"
- if booth.transition_possible? :confirm
%li= link_to 'Confirm booth',
confirm_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "confirm_booth_#{booth.id}"

View file

@ -1,33 +0,0 @@
.row
.col-md-12
.page-header
%title Request a Booth
.row
.col-md-8
= semantic_form_for(@booth, url: @booth.new_record? ? admin_conference_booths_path(@conference.short_title) : admin_conference_booth_path(@conference.short_title, @booth.id), html: { multipart: true }) do |f|
= f.input :title, as: :string, required: true
= f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
hint: 'This field becomes public upon request acceptance'
= f.input :reasoning, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'How it fits the conference'
= f.input :submitter_relationship, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'Submitter\'s relation',
hint: 'e.g. employee, comunity manager, etc'
= f.input :website_url
= responsibles_selector_input f
= image_tag f.object.picture.thumb.url if f.object.picture?
= f.input :picture
%p.text-right
- if @booth.new_record?
= f.submit 'Create Booth Request', class: 'btn btn-success'
- else
= f.submit 'Update Booth Request', class: 'btn btn-success'
:javascript
$(document).ready(function() {
$('#booth_responsible_ids').selectize({
plugins: ['remove_button'],
minItems: 2
} )
});

View file

@ -2,4 +2,4 @@
Editing Editing
= @booth.title = @booth.title
= render 'form' = render 'booths/form'

View file

@ -9,51 +9,68 @@
= link_to 'Add Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary' = link_to 'Add Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary'
%p.text-muted %p.text-muted
All the booth requests All the booth requests
.row .row
.col-md-12 .col-md-12
.margin-booth-table %h4
%table.table.table-striped.table-bordered.table-hover.datatable - if @conference.booth_limit == 0
%thead %p
%th Set the
%b ID = link_to 'Booth limit', edit_admin_conference_path(@conference.short_title)
%th to make sure you are not accepting more booths than you can accommodate.
%b Logo - elsif !@conference.maximum_accepted_booths?
%th %p
%b Title You cannot accept more than
%th %b
%b Submitter = pluralize(@conference.booth_limit, 'booth')
%th (
%b Responsibles = pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, 'accepted booth')
%th so far)
%b State - else
%th %p
%b Actions You have reached the maximum number of accepted booths.
- @booths.each do |booth| (
%tr = link_to "#{@conference.booth_limit} booths", edit_admin_conference_path(@conference.short_title)
)
%table.table.table-striped.table-bordered.table-hover.datatable
%thead
%th
%b ID
%th
%b Logo
%th
%b Title
%th
%b Submitter
%th
%b Responsibles
%th
%b State
%th
%b Actions
- @booths.each do |booth|
%tr
%td
= booth.id
%td
- if booth.logo_link
= image_tag(booth.picture.thumb.url, width: '20%')
%td
= link_to booth.title, admin_conference_booth_path(@conference.short_title, booth)
%td
= link_to booth.submitter.name, admin_user_path(booth.submitter) if booth.submitter
%td
.responsibles
- booth.responsibles.each_with_index do |responsible, i|
= link_to responsible.name, admin_user_path(responsible)
= ", " unless i == booth.responsibles.length - 1
%td
.btn-group
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
= booth.state.humanize
%span.caret
%ul.dropdown-menu{ role: 'menu' }
= render 'change_state_dropdown', booth: booth
%td %td
= booth.id = link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id),
%td class: 'btn btn-primary'
- if booth.logo_link
= image_tag(booth.picture.thumb.url, width: '20%')
%td
= link_to booth.title, admin_conference_booth_path(@conference.short_title, booth)
%td
= link_to booth.submitter.name, admin_user_path(booth.submitter) if booth.submitter
%td
.responsibles
- booth.responsibles.each do |responsible|
= link_to responsible.name, admin_user_path(responsible)
%td
.btn-group
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
= booth.state.humanize
%span.caret
%ul.dropdown-menu{ role: 'menu' }
= render 'change_state_dropdown', booth: booth
%td
.btn-group{ role: "group" }
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id),
class: 'btn btn-primary'
= link_to 'Delete', admin_conference_booth_path(@conference.short_title, booth.id),
method: :delete, class: 'btn btn-danger',
data: {confirm: "Do you really want to delete this booth request?"}

View file

@ -1,3 +1,3 @@
%h1 New booth %h1 New booth
= render 'form' = render 'booths/form'

View file

@ -39,12 +39,13 @@
%td.col-md-2 %td.col-md-2
%b Responsibles %b Responsibles
%td %td
- @booth.responsibles.each do |responsibles| - @booth.responsibles.each_with_index do |responsibles, i|
.responsibles .responsibles
= link_to responsibles.name, admin_user_path(responsibles) = link_to responsibles.name, admin_user_path(responsibles)
( (
= responsibles.email = responsibles.email
) )
= " , " unless i == @booth.responsibles.length - 1
%tr %tr
%td.col-md-2 %td.col-md-2
%b Submitted on %b Submitted on

View file

@ -0,0 +1,12 @@
%dt
Start Date:
%dd#start_date
= @cfp.start_date.strftime('%A, %B %-d. %Y')
%dt
End Date:
%dd#end_date
= @cfp.end_date.strftime('%A, %B %-d. %Y')
%dt
Days Left:
%dd
= pluralize(@cfp.remaining_days, 'day')

View file

@ -26,4 +26,7 @@
= f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24} = f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}
= f.inputs name: 'Registrations' do = f.inputs name: 'Registrations' do
= f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration') = f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration')
= f.inputs name: 'Booths' do
= f.input :booth_limit, as: :number, in: 0..9999,
hint: 'Booth limit is the maximum number of booths that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more booths than the conference can accommodate. You currently have ' + pluralize(@conference.booths.accepted.count, 'accepted booth') +'.'
= f.action :submit, as: :button, button_html: {class: 'btn btn-primary'} = f.action :submit, as: :button, button_html: {class: 'btn btn-primary'}

View file

@ -2,6 +2,7 @@
.col-md-8 .col-md-8
= semantic_form_for(@conference, url: admin_conferences_path) do |f| = semantic_form_for(@conference, url: admin_conferences_path) do |f|
= f.inputs 'Basic Information' do = f.inputs 'Basic Information' do
= f.input :organization, as: :select, collection: @organizations
= f.input :title, hint: "The name of your conference as it shall appear throughout the site. Example: 'OpenSUSE Conference 2013'", = f.input :title, hint: "The name of your conference as it shall appear throughout the site. Example: 'OpenSUSE Conference 2013'",
input_html: { required: 'required' } input_html: { required: 'required' }
= f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", = f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'",

View file

@ -55,4 +55,10 @@
%tr %tr
%td {conference_splash_link} %td {conference_splash_link}
%td The link to conference splash page %td The link to conference splash page
- if @conference.booths
%tr
%td {submitter_name}
%td Submitter's name
%tr
%td {booth_title}
%td Booth's title

View file

@ -14,6 +14,8 @@
%a{ 'aria-controls' => 'notifications', 'data-toggle' => 'tab', href: '#notifications', role: 'tab' } Update Notifications %a{ 'aria-controls' => 'notifications', 'data-toggle' => 'tab', href: '#notifications', role: 'tab' } Update Notifications
%li{ role: 'presentation' } %li{ role: 'presentation' }
%a{ 'aria-controls' => 'cfp', 'data-toggle' => 'tab', href: '#cfp', role: 'tab' } Call for Papers %a{ 'aria-controls' => 'cfp', 'data-toggle' => 'tab', href: '#cfp', role: 'tab' } Call for Papers
%li{ role: 'presentation' }
%a{ 'aria-controls' => 'booths', 'data-toggle' => 'tab', href: '#booth', role: 'tab' } Booth
/ Tab panes / Tab panes
.tab-content .tab-content
#onboarding.tab-pane.active{ role: 'tabpanel' } #onboarding.tab-pane.active{ role: 'tabpanel' }
@ -100,6 +102,26 @@
'data-body-text' => "Dear {name},\n\nThe Conference Call for Papers Details of {conference} has changed.\nNew Dates : {cfp_start_date} - {cfp_end_date}.\n Link to Schedule {schedule_link} \n\nBest wishes\n\n{conference} Team" } Load Template 'data-body-text' => "Dear {name},\n\nThe Conference Call for Papers Details of {conference} has changed.\nNew Dates : {cfp_start_date} - {cfp_end_date}.\n Link to Schedule {schedule_link} \n\nBest wishes\n\n{conference} Team" } Load Template
%a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'updated_cfp_help' } Show Help %a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'updated_cfp_help' } Show Help
= render partial: 'help', locals: {id: 'updated_cfp_help', show_event_variables: false} = render partial: 'help', locals: {id: 'updated_cfp_help', show_event_variables: false}
#booth.tab-pane{ role: 'tabpanel' }
= f.input :send_on_booths_acceptance
= f.input :booths_acceptance_subject
= f.input :booths_acceptance_body, input_html: { rows:10, cols: 20 }
%a.btn.btn-link.control_label.load_template{ 'data-subject-input-id' => 'email_settings_booths_acceptance_subject',
'data-subject-text' => 'Your booth has been accepted!',
'data-body-input-id' => 'email_settings_booths_acceptance_body',
'data-body-text' => "Dear {name},\n\nWe are pleased to inform you that your booth request {booth_title} has been accepted for the conference {conference}.\nPlease click the confirm button to let us know you can make it as soon as possible!\n\nFeel free to contact us with any questions or concerns.\n\nWe are looking forward to seeing you there.\n\nBest wishes\n\n{conference} Team"} Load Template
%a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'booth_acceptance_help' } Show help
= render partial: 'help', locals: {id: 'booth_acceptance_help', show_event_variables: false}
= f.input :send_on_booths_rejection
= f.input :booths_rejection_subject
= f.input :booths_rejection_body, input_html: { rows:10, cols:20 }
%a.btn.btn-link.control_label.load_template{ 'data-subject-input-id' => 'email_settings_booths_rejection_subject',
'data-subject-text' => 'Your booth request has been rejected',
'data-body-input-id' => 'email_settings_booths_rejection_body',
'data-body-text' => "Dear {name},\n\nThank you for your booth request {booth_title} for the conference {conference}.\n\nUnfortunately, we are sorry to inform you that your request has been rejected.\n\n\nBest wishes\n\n{conference} Team" } Load Template
%a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'booth_rejection_help' } Show help
= render partial: 'help', locals: {id: 'booth_rejection_help', show_event_variables: false}
.row .row
.col-md-12 .col-md-12
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -0,0 +1,25 @@
.page-header
%h3 Users (#{users.length})
- if users.present?
%table.table.table-striped.table-bordered.table-hover.datatable#users
%thead
%th Name
%th Email
- if ( can? :unassign_org_admins, organization )
%th
Actions
%tbody
- users.each do |user|
%tr
%td= user.name
%td= user.email
- if ( can? :unassign_org_admins, organization )
%td
= link_to 'Remove from organization admin',
unassign_org_admins_admin_organization_path(organization.id,
role.name,
user: {email: user.email}),
method: :delete,
class: 'btn btn-danger'
- else
%h5 No users found!

View file

@ -25,6 +25,8 @@
= organization.conferences.past.count = organization.conferences.past.count
%td %td
.btn-group .btn-group
= link_to 'Admins', admins_admin_organization_path(organization),
method: :get, class: 'btn btn-success'
= link_to 'Edit', edit_admin_organization_path(organization), = link_to 'Edit', edit_admin_organization_path(organization),
method: :get, class: 'btn btn-primary' method: :get, class: 'btn btn-primary'
= link_to 'Delete', admin_organization_path(organization), = link_to 'Delete', admin_organization_path(organization),

View file

@ -0,0 +1,24 @@
.row
.col-md-12
.page-header
%h2
Organization admins for #{@organization.name}
.text-muted
= @role.description
.row.col-md-3
- if ( can? :assign_org_admins, @organization )
= semantic_form_for :user,
url: assign_org_admins_admin_organization_path(@organization,
@role.name), method: :post do |u|
= u.label 'Add user by email: '
.input-group
= u.input :email, label: false, placeholder: "User's email"
.input-group-btn
= u.submit 'Add', id: 'user-add', class: 'btn btn-primary'
.row
.col-md-12
= render partial: 'users_with_org_admin_role',
locals: { users: @users, organization: @organization, role: @role }

View file

@ -32,12 +32,12 @@
.btn-group .btn-group
= link_to 'Show', = link_to 'Show',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id), physical_ticket.token),
class: 'btn btn-primary' class: 'btn btn-primary'
= link_to 'Generate PDF', = link_to 'Generate PDF',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id, physical_ticket.token,
format: :pdf), format: :pdf),
class: 'button btn btn-default btn-info' class: 'button btn btn-default btn-info'
- else - else
%h5 No Tickets sold! %h5 No Tickets sold!

View file

@ -25,5 +25,12 @@
= link_to 'Delete', admin_conference_registration_period_path, = link_to 'Delete', admin_conference_registration_period_path,
method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger'
- else - else
- if can? :create, @conference.build_registration_period - unless @conference.tickets.for_registration.empty?
= link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary' - if can? :create, @conference.build_registration_period
= link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary'
- else
.h3.text-left
No Registration Tickets!
%small
= link_to 'Create registration tickets', new_admin_conference_ticket_path
before creating the registration period.

View file

@ -5,7 +5,9 @@
- date_event_schedules = @event_schedules.select{ |e| e.start_time.to_date.eql? date } - date_event_schedules = @event_schedules.select{ |e| e.start_time.to_date.eql? date }
.row .row
- @rooms.each do |room| - @rooms.each do |room|
.col-md-2.col-xs-6 - non_schedulable = room.tracks.self_organized.confirmed.any? do |track|
- !track.schedules.include?(@schedule) && (track.start_date..track.end_date).include?(date)
.col-md-2.col-xs-6{ class: ('non_schedulable' if non_schedulable) }
.room-name .room-name
- room_date_event_schedules = date_event_schedules.select{ |e| e.room == room } - room_date_event_schedules = date_event_schedules.select{ |e| e.room == room }
= room.name = room.name

View file

@ -7,12 +7,13 @@
/ subtracting the padding before calculate the number of lines / subtracting the padding before calculate the number of lines
- lines = (height - 7) / 23 - lines = (height - 7) / 23
- color = event.track.try(:color).present? ? event.track.try(:color) : 'FFFFFF' - color = event.track.try(:color).present? ? event.track.try(:color) : 'FFFFFF'
- non_schedulable = event_schedule_id && (EventSchedule.find(event_schedule_id).schedule != @schedule)
.schedule-event{ style: "height: #{height}px; background-color: #{color}; color: #{contrast_color(color)}", | .schedule-event{ style: "height: #{height}px; background-color: #{color}; color: #{contrast_color(color)}", |
id: "event-#{event.id}", | id: "event-#{event.id}", |
event_id: event.id, | event_id: event.id, |
length: cells_length, | length: cells_length, |
event_schedule_id: event_schedule_id, | event_schedule_id: event_schedule_id, |
class: ('compact' if compact_grid) } class: "#{'compact' if compact_grid} #{'non_schedulable' if non_schedulable}" }
.schedule-event-text{ style: "-webkit-line-clamp: #{lines}; height: #{lines * 23}px;"} .schedule-event-text{ style: "-webkit-line-clamp: #{lines}; height: #{lines * 23}px;"}
%span.schedule-event-delete-button{ onclick: "Schedule.remove(\'event-#{event.id}\');" } X %span.schedule-event-delete-button{ onclick: "Schedule.remove(\'event-#{event.id}\');" } X
= event.title = event.title

View file

@ -0,0 +1,10 @@
.row
.col-md-12
.page-header
%h1
New Track Schedule
.row
.col-md-12
= semantic_form_for @schedule, url: admin_conference_schedules_path(@conference.short_title) do |f|
= f.input :track, collection: Track.accessible_by(current_ability).where(program: @program).self_organized.confirmed.pluck(:name, :id), include_blank: false
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -4,42 +4,85 @@
%h1 Schedules %h1 Schedules
%p.text-muted %p.text-muted
The schedules for your conference The schedules for your conference
.row .tabbable
.col-md-12 %ul.nav.nav-tabs
%table.table.table-hover#event_types %li.active
%thead = link_to 'Conference schedules', '#conference', 'data-toggle' => 'tab'
%th Schedule %li
%th Selected = link_to 'Track schedules', '#tracks', 'data-toggle' => 'tab'
%th Actions .tab-content
%tbody .tab-pane.active#conference
- @schedules.each do |schedule| .row
%tr .col-md-12
%td %table.table.table-hover
Schedule %thead
= schedule.id %th Schedule
%td %th Selected
= selected_scheduled?(schedule) %th Actions
%td %tbody
.btn-group{role: "group"} - @schedules.where(track: nil).each do |schedule|
= link_to 'Show', admin_conference_schedule_path(@conference.short_title, schedule.id), %tr
method: :get, class: 'btn btn-primary' %td
= link_to 'Delete', admin_conference_schedule_path(@conference.short_title, schedule.id), Schedule
method: :delete, class: 'btn btn-danger', data: { confirm: "Do you really want to delete Schedule #{schedule.id}?" } = schedule.id
.row %td
.col-md-12 = selected_scheduled?(schedule)
- if @venue.try(:rooms).present? %td
.text-right .btn-group{role: "group"}
= link_to 'Add Schedule', admin_conference_schedules_path(@conference.short_title), - if can? :show, schedule
method: :post, class: 'btn btn-primary' = link_to 'Show', admin_conference_schedule_path(@conference.short_title, schedule),
- elsif @venue method: :get, class: 'btn btn-primary'
.h3 - if can? :destroy, schedule
No Rooms! = link_to 'Delete', admin_conference_schedule_path(@conference.short_title, schedule),
%small method: :delete, class: 'btn btn-danger', data: { confirm: "Do you really want to delete Schedule #{schedule.id}?" }
= link_to 'Create rooms', admin_conference_venue_rooms_path .row
before creating the schedule. .col-md-12
- else - if @venue.try(:rooms).present?
.h3 .text-right
No Venue! - if can? :create, @program.schedules.new
%small = link_to 'Add Schedule', admin_conference_schedules_path(@conference.short_title),
= link_to 'Create a venue with rooms', new_admin_conference_venue_path method: :post, class: 'btn btn-primary'
before creating the schedule. - elsif @venue
.h3
No Rooms!
%small
= link_to 'Create rooms', admin_conference_venue_rooms_path
before creating the schedule.
- else
.h3
No Venue!
%small
= link_to 'Create a venue with rooms', new_admin_conference_venue_path
before creating the schedule.
.tab-pane#tracks
.row
.col-md-12
%table.table.table-hover
%thead
%th Schedule
%th Track
%th Selected
%th Actions
%tbody
- @schedules.where.not(track: nil).each do |schedule|
%tr
%td
Schedule
= schedule.id
%td
- track = schedule.track
= link_to track.name, admin_conference_program_track_path(@conference.short_title, track)
%td
= schedule == schedule.track.selected_schedule ? 'Yes' : 'No'
%td
.btn-group{role: "group"}
- if can? :show, schedule
= link_to 'Show', admin_conference_schedule_path(@conference.short_title, schedule), class: 'btn btn-primary'
- if can? :destroy, schedule
= link_to 'Delete', admin_conference_schedule_path(@conference.short_title, schedule),
method: :delete, class: 'btn btn-danger', data: { confirm: "Do you really want to delete Schedule #{schedule.id}?" }
.row
.col-md-12
.text-right
- if can? :new, @program.schedules.build(track: @program.tracks.new)
= link_to 'Add Track Schedule', new_admin_conference_schedule_path(@conference.short_title), class: 'btn btn-primary'

View file

@ -11,8 +11,15 @@
.row .row
.col-md-2 .col-md-2
Selected schedule Selected schedule
= check_box_tag @conference.short_title, @schedule.id, (@schedule.id == @selected_schedule.try(:id)), :ruby
method: :patch, url: (admin_conference_program_path(@conference.short_title) + '?[program][selected_schedule_id]='), if @schedule.track
value = @schedule == @schedule.track.selected_schedule
url = update_selected_schedule_admin_conference_program_track_path(@conference.short_title, @schedule.track) + '?[track][selected_schedule_id]='
else
value = @schedule.id == @selected_schedule.try(:id)
url = admin_conference_program_path(@conference.short_title) + '?[program][selected_schedule_id]='
end
= check_box_tag @conference.short_title, @schedule.id, value, method: :patch, url: url,
class: 'switch-checkbox-schedule', data: { size: 'small', class: 'switch-checkbox-schedule', data: { size: 'small',
off_color: 'warning', off_color: 'warning',
on_text: 'Yes', on_text: 'Yes',

View file

@ -14,6 +14,7 @@
= f.input :include_tickets, label: 'Display tickets', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tickets) } = f.input :include_tickets, label: 'Display tickets', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tickets) }
= f.input :include_lodgings, label: 'Display the lodgings', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_lodgings) } = f.input :include_lodgings, label: 'Display the lodgings', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_lodgings) }
= f.input :include_sponsors, label: 'Display sponsors', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_sponsors) } = f.input :include_sponsors, label: 'Display sponsors', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_sponsors) }
= f.input :include_booths, label: 'Display confirmed booths', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) }
= f.input :include_social_media, label: 'Display social media', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_social_media) } = f.input :include_social_media, label: 'Display social media', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_social_media) }
= f.inputs name: 'Access' do = f.inputs name: 'Access' do
= f.input :public, label: 'Make splash page public?' = f.input :public, label: 'Make splash page public?'

View file

@ -66,6 +66,13 @@
Yes Yes
- else - else
No No
%dt
Include Booths
%dd
- if @splashpage.include_booths
Yes
- else
No
%dt %dt
Include Social Media: Include Social Media:
%dd %dd

View file

@ -13,5 +13,6 @@
= f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } } = f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :price = f.input :price
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY'], include_blank: false = f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY'], include_blank: false
= f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.'
%p.text-right %p.text-right
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -14,6 +14,7 @@
%th Price %th Price
%th Sold %th Sold
%th Turnover %th Turnover
%th Registration Ticket
%th Actions %th Actions
%tbody %tbody
- @conference.tickets.each do |ticket| - @conference.tickets.each do |ticket|
@ -27,6 +28,8 @@
= ticket.tickets_sold = ticket.tickets_sold
%td %td
= humanized_money_with_symbol ticket.tickets_turnover = humanized_money_with_symbol ticket.tickets_turnover
%td
= ticket.registration_ticket? ? 'Yes' : 'No'
%td %td
.btn-group .btn-group
= link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id), = link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id),

View file

@ -0,0 +1,34 @@
- if track.transition_possible? :restart
%li= link_to 'Start review',
restart_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "restart_track_#{track.id}"
- if track.transition_possible? :to_accept
%li= link_to 'Mark as possible acceptance',
to_accept_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "to_accept_track_#{track.id}"
- if track.transition_possible? :accept
%li= link_to 'Accept track request',
accept_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "accept_track_#{track.id}"
- if track.transition_possible? :confirm
%li= link_to 'Confirm track',
confirm_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "confirm_track_#{track.id}"
- if track.transition_possible? :to_reject
%li= link_to 'Mark as possible rejection',
to_reject_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "to_reject_track_#{track.id}"
- if track.transition_possible? :reject
%li= link_to 'Reject track request',
reject_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, confirm: 'Are you sure?', id: "reject_track_#{track.id}"
- if track.transition_possible? :cancel
%li= link_to 'Cancel track request',
cancel_admin_conference_program_track_path(@conference.short_title, track),
method: :patch, id: "cancel_track_#{track.id}"

View file

@ -8,11 +8,21 @@
Track Track
.row .row
.col-md-12 .col-md-12
= semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track))) do |f| = semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path(@conference.short_title) : admin_conference_program_track_path(@conference.short_title, @track))) do |f|
= f.input :name = f.input :name
= f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' } = f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }
= f.input :color, input_html: {size: 6, type: 'color'}, required: true = f.input :color, input_html: {size: 6, type: 'color'}, required: true
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? }
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? }
- if @conference.venue.try(:rooms)
= f.input :room, as: :select, collection: (@conference.venue.rooms).map {|room| ["#{room.name}", room.id]}, include_blank: true, label: 'Room', input_html: { class: 'select-help-toggle', required: @track.self_organized_and_accepted_or_confirmed? }
- else
%b
Please add a
= link_to 'venue', admin_conference_venue_path(@conference.short_title)
with
= link_to 'rooms', admin_conference_venue_rooms_path(@conference.short_title)
, if you want to select a room for the track.
= f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, hint: markdown_hint = f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, hint: markdown_hint
- if @track.self_organized? = f.input :cfp_active, label: 'Allow event submitters to select this track for their proposal'
= f.input :cfp_active, label: 'Allow event submitters to select this track for their proposal'
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -1,3 +1,4 @@
.unobtrusive-flash-container
.row .row
.col-md-12 .col-md-12
.page-header .page-header
@ -6,60 +7,75 @@
Categorize events in your conference Categorize events in your conference
.row .row
.col-md-12 .col-md-12
%table.table.table-hover#tracks %table.table.table-hover.table-striped.table-bordered.datatable#tracks
%thead %thead
%th ID
%th Name %th Name
%th Short name
%th Description %th Description
%th Room
%th Start Date
%th End Date
%th Submitter %th Submitter
%th Color %th Included in Cfp
%th State %th State
%th Included in the Cfp
%th Actions %th Actions
%tbody %tbody
- @tracks.each do |track| - @tracks.each do |track|
%tr %tr
%td %td
= link_to(admin_conference_program_track_path(@conference.short_title, track)) do = track.id
= track.name %td{style: "padding: 15px 0px 0px 10px;"}
%td = link_to admin_conference_program_track_path(@conference.short_title, track), class: 'btn' do
= track.short_name %span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
= track.name
%td %td
%p %p
= truncate(track.description) = markdown(truncate(track.description))
%td %td
= track.room.try(:name)
%td
= track.start_date.strftime('%A, %B %-d. %Y') if track.start_date
%td
= track.end_date.strftime('%A, %B %-d. %Y') if track.end_date
%td
= link_to track.submitter.name, admin_user_path(track.submitter) if track.self_organized?
%td.text-center{ 'id' => "cfp_switch_#{track.id}", 'data-order' => track.cfp_active.to_s }
= check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
class: 'switch-checkbox', method: :patch,
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
data: { size: 'small',
on_color: 'success',
off_color: 'warning',
on_text: 'Yes',
off_text: 'No' }
%td.text-center
- if track.self_organized? - if track.self_organized?
= link_to track.submitter.name, admin_user_path(track.submitter) .btn-group
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
= track.state.humanize
%span.caret
%ul.dropdown-menu{ role: 'menu' }
= render 'change_state_dropdown', track: track
- else - else
N/A = track.state.humanize
%td
%span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
= track.color
%td
- if track.self_organized?
= track.state
- else
N/A
%td
- if track.self_organized?
= check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
class: 'switch-checkbox', method: :patch,
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
data: { size: 'small',
on_color: 'success',
off_color: 'warning',
on_text: 'Yes',
off_text: 'No' }
- else
%i.fa.fa-check
%td %td
.btn-group{role: "group"} .btn-group{role: "group"}
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), - if can? :edit, track
method: :get, class: 'btn btn-primary' = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), class: 'btn btn-primary'
- special_style = true
- if can? :destroy, track - if can? :destroy, track
= link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track), = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track), method: :delete, class: 'btn btn-danger',
method: :delete, class: 'btn btn-danger',
data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" } data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" }
- if track.self_organized?
- if track.selected_schedule
- if can? :show, track.selected_schedule
= link_to 'Show Schedule', admin_conference_schedule_path(@conference.short_title, track.selected_schedule),
class: 'btn btn-default'
- elsif can? :create, @program.schedules.build(track: track)
= button_to 'Create Schedule', admin_conference_schedules_path(@conference.short_title),
form: { class: 'btn', style: 'padding: 0px 0px; margin-top: -1px;' }, class: 'btn btn-default',
style: ('border-top-left-radius: 0; border-bottom-left-radius: 0;' if special_style), params: { 'schedule[track_id]' => track.id }
.row .row
.col-md-12.text-right .col-md-12.text-right
= link_to 'New Track', new_admin_conference_program_track_path(@conference.short_title), class: 'btn btn-success' = link_to 'New Track', new_admin_conference_program_track_path(@conference.short_title), class: 'btn btn-success'

View file

@ -1,30 +1,134 @@
.unobtrusive-flash-container
.row .row
.col-md-12 .col-md-12
.page-header .page-header
%h1 %h1
= @track.name = @track.name
Track Track
%p.text-muted
Events in this track .tabbable
.row %ul.nav.nav-tabs
.col-md-12 %li.active
%table.table.table-hover.datatable = link_to 'Details', '#details', 'data-toggle' => 'tab'
%thead %li
%th Title = link_to 'Events', '#events', 'data-toggle' => 'tab'
%th Type
%th Submitter .tab-content
%th State .tab-pane.active#details
%th Time .row
%tbody .col-md-12
- @track.events.each_with_index do |event| .btn-group.pull-right
%tr - if can? :edit, @track
%td = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, @track),
=link_to event.title, admin_conference_program_event_path(@conference.short_title, event) method: :get, class: 'btn btn-primary'
%td - special_style = true
= event.event_type.title - if can? :destroy, @track
%td = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, @track),
=link_to event.submitter.name, admin_user_path(event.submitter) method: :delete, class: 'btn btn-danger',
%td data: { confirm: "Do you really want to delete #{@track.name}? Attention: This track will be removed from all Events that have it set" }
= event.state - if @track.self_organized?
%td - if @track.selected_schedule
= event.time - if can? :show, @track.selected_schedule
= link_to 'Show Schedule', admin_conference_schedule_path(@conference.short_title, @track.selected_schedule),
class: 'btn btn-default'
- elsif can? :create, @program.schedules.build(track: @track)
= button_to 'Create Schedule', admin_conference_schedules_path(@conference.short_title),
form: { class: 'btn', style: 'padding: 0px 0px; margin-top: -1px;' }, class: 'btn btn-default',
style: ('border-top-left-radius: 0; border-bottom-left-radius: 0;' if special_style), params: { 'schedule[track_id]' => @track.id }
.row
.col-md-12
%table.table
%tr
%td.col-md-2
%b Color
%td
%span.label{ style: "background-color: #{@track.color}; color: #{ contrast_color(@track.color) }" }
= @track.color
%tr
%td
%b Room
%td
= @track.room.try(:name)
%tr
%td
%b Start date
%td
= @track.start_date.strftime('%A, %B %-d. %Y') if @track.start_date
%tr
%td
%b End date
%td
= @track.end_date.strftime('%A, %B %-d. %Y') if @track.end_date
- if @track.self_organized?
%tr
%td
%b Submitter
%td
= link_to @track.submitter.name, admin_user_path(@track.submitter)
- if @track.confirmed?
%tr
%td
%b Organizers
%td
- Role.find_by(name: 'track_organizer', resource: @track).users.each do |organizer|
%div
= link_to organizer.name, admin_user_path(organizer)
%tr
%td
%b Included in the Cfp?
%td
= check_box_tag "#{@conference.short_title}_#{@track.short_name}", @track.id, @track.cfp_active,
class: 'switch-checkbox', method: :patch,
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: @track.short_name)+"?included=",
data: { size: 'small',
on_color: 'success',
off_color: 'warning',
on_text: 'Yes',
off_text: 'No' }
%tr
%td
%b State
%td
- if @track.self_organized?
.btn-group
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
= @track.state.humanize
%span.caret
%ul.dropdown-menu{ role: 'menu' }
= render 'change_state_dropdown', track: @track
- else
= @track.state.humanize
%tr
%td
%b Description
%td
= markdown(@track.description)
- if @track.self_organized?
%tr
%td
%b Relevance
%td
= markdown(@track.relevance)
.tab-pane#events
.col-md-12
%table.table.table-hover.datatable
%thead
%th Title
%th Type
%th Submitter
%th State
%th Time
%tbody
- @track.events.each_with_index do |event|
%tr
%td
=link_to event.title, admin_conference_program_event_path(@conference.short_title, event)
%td
= event.event_type.title
%td
=link_to event.submitter.name, admin_user_path(event.submitter)
%td
= event.state
%td
= event.time

View file

@ -0,0 +1,8 @@
$('.alert').remove();
track_id = <%= @track.id %>;
track_cfp_td = $('#cfp_switch_' + track_id);
track_cfp_value = <%= @track.cfp_active %>;
track_cfp_td.attr('data-order', track_cfp_value);
$('#tracks').DataTable().cell(track_cfp_td).invalidate();

View file

@ -1,84 +1,106 @@
- unless version.item_type == 'Role' || version.item_type == 'UsersRole'
- conference = Conference.find_by(id: version.conference_id)
- conference_short_title = conference.try(:short_title) || current_or_last_object_state('Conference', version.conference_id).try(:short_title) || ' '
- case version.item_type - case version.item_type
- when 'Organization'
organization
= link_to_organization(version.item_id)
- when 'UsersRole' - when 'UsersRole'
- users_role = current_or_last_object_state(version.item_type, version.item_id) - users_role = current_or_last_object_state(version.item_type, version.item_id)
- user = current_or_last_object_state('User', users_role.user_id) - role = Role.find_by(id: users_role.role_id) if users_role
= 'role' role
= link_to users_role.role.name, admin_conference_role_path(conference_id: Conference.find(version.conference_id).short_title, id: users_role.role.name) - if role.name == 'organization_admin'
= version.event == 'create' ? 'to' : 'from' -# organization_admin belongs to organization and not conferences
= 'user' - organization = Organization.find(version.conference_id)
= link_if_alive version, role.name,
admins_admin_organization_path(organization), organization
- else
- conference = Conference.find_by(id: version.conference_id)
- conference_short_title = conference.try(:short_title) || current_or_last_object_state('Conference', version.conference_id).try(:short_title) || ' '
= link_if_alive version, role.try(:name), admin_conference_role_path(role.try(:name) || ' ', conference_short_title), conference
= link_to (user.try(:name) || 'deleted user'), admin_user_path(id: users_role.user.id) = version.event == 'create' ? 'to' : 'from'
user
= link_to_user(users_role.user_id)
- when 'Subscription', 'Registration' - when 'Subscription', 'Registration'
= 'conference' conference
= link_to Conference.find(version.conference_id).title, = link_to_conference(version.conference_id)
admin_conference_registrations_path(conference_id: Conference.find(version.conference_id).short_title)
- when 'Commercial' - when 'Commercial'
- commercial = current_or_last_object_state(version.item_type, version.item_id) - commercial = current_or_last_object_state(version.item_type, version.item_id)
- commercialable = current_or_last_object_state(commercial.commercialable_type, commercial.commercialable_id) - commercialable = current_or_last_object_state(commercial.commercialable_type, commercial.commercialable_id)
- commercialable_last_version = PaperTrail::Version.where(item_type: commercial.commercialable_type, item_id: commercial.commercialable_id).last
- case commercial.commercialable_type - case commercial.commercialable_type
- when 'Event' - when 'Event'
commercial in commercial in event
- if commercialable_last_version.item - if commercialable && conference
event
= link_to commercialable.title, = link_to commercialable.title,
admin_conference_program_event_path(conference_id: Conference.find(version.conference_id).short_title, id: commercialable.id) admin_conference_program_event_path(conference, commercialable.id)
- else - else
= commercialable.title = commercialable.title
= "with ID #{commercialable.id}"
- when 'Venue' - when 'Venue'
commercial in venue commercial in venue
- if commercialable_last_version.item - if commercialable && conference
= link_to commercialable.name, = link_to commercialable.name,
edit_admin_conference_venue_path(conference_id: Conference.find(version.conference_id).short_title, edit_admin_conference_venue_path(conference_short_title,
id: commercialable.id, anchor: 'commercials-content') commercialable.id, anchor: 'commercials-content')
- else - else
= commercialable.name = commercialable.name
= "with ID #{commercialable.id}"
- when 'Conference' - when 'Conference'
= link_to 'commercial', commercial in conference
admin_conference_commercials_path(conference_id: Conference.find(version.conference_id).short_title) - if commercialable
= link_to commercialable.short_title,
admin_conference_commercials_path(commercialable.short_title)
- else
= commercialable.short_title
= "with ID #{commercialable.id}"
- when 'EventsRegistration', 'Comment', 'Vote', 'Event' - when 'EventsRegistration', 'Comment', 'Vote', 'Event'
= 'event' event
- object = current_or_last_object_state(version.item_type, version.item_id) - object = current_or_last_object_state(version.item_type, version.item_id)
- event_id = object.try(:event_id) || object.try(:commentable_id) || object.id - event_id = object.try(:event_id) || object.try(:commentable_id) || object.id
= link_to (current_or_last_object_state('Event', event_id).try(:title) || 'deleted event'), = link_to (current_or_last_object_state('Event', event_id).try(:title) || 'deleted event'),
admin_conference_program_event_path(conference_id: Conference.find(version.conference_id).short_title, id: event_id) admin_conference_program_event_path(conference_short_title, event_id)
- when 'Target' - when 'Target'
= 'target' target
- target = current_or_last_object_state(version.item_type, version.item_id) - target = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, target.to_s, admin_conference_targets_path(conference_id: Conference.find(version.conference_id).short_title) = link_if_alive version, target.to_s, admin_conference_targets_path(conference_short_title), conference
- when 'EventSchedule' - when 'EventSchedule'
- event_schedule = current_or_last_object_state(version.item_type, version.item_id) - event_schedule = current_or_last_object_state(version.item_type, version.item_id)
event event
= link_to (current_or_last_object_state('Event', event_schedule.event_id).try(:title) || 'deleted event'), = link_to (current_or_last_object_state('Event', event_schedule.event_id).try(:title) || 'deleted'),
admin_conference_program_event_path(conference_id: Conference.find(version.conference_id).short_title, id: event_schedule.event_id) admin_conference_program_event_path(conference_short_title, event_schedule.event_id)
in in
= link_to "Schedule #{event_schedule.schedule_id}", = link_to "Schedule #{event_schedule.schedule_id}",
admin_conference_schedule_path(conference_id: Conference.find(version.conference_id).short_title, id: event_schedule.schedule_id) admin_conference_schedule_path(conference_short_title, event_schedule.schedule_id)
- when 'Schedule' - when 'Schedule'
= link_if_alive version, "Schedule #{version.item_id}", = link_if_alive version, "Schedule #{version.item_id}",
admin_conference_schedule_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) admin_conference_schedule_path(conference_short_title, version.item_id),
conference
- when 'Conference' - when 'Conference'
= 'conference' conference
= link_to Conference.find(version.conference_id).title, = link_to_conference(version.item_id)
edit_admin_conference_path(id: Conference.find(version.conference_id).short_title)
- when 'RegistrationPeriod' - when 'RegistrationPeriod'
= link_if_alive version, 'registration period', = link_if_alive version, 'registration period',
admin_conference_registration_period_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_registration_period_path(conference_short_title),
conference
- when 'Contact' - when 'Contact'
= link_if_alive version, 'contact details', = link_if_alive version, 'contact details',
edit_admin_conference_contact_path(conference_id: Conference.find(version.conference_id).short_title) edit_admin_conference_contact_path(conference_short_title),
conference
- when 'Booth' - when 'Booth'
= 'booth' = 'booth'
@ -88,94 +110,120 @@
- when 'Program' - when 'Program'
= link_if_alive version, 'program', = link_if_alive version, 'program',
admin_conference_program_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_program_path(conference_short_title),
conference
- when 'Cfp' - when 'Cfp'
= 'cfp for' cfp for
- cfp = current_or_last_object_state(version.item_type, version.item_id) - cfp = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, cfp.cfp_type, = link_if_alive version, cfp.cfp_type,
admin_conference_program_cfp_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) admin_conference_program_cfp_path(conference_short_title, version.item_id),
conference
- when 'Track' - when 'Track'
= 'track' track
- track = current_or_last_object_state(version.item_type, version.item_id) - track = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, track.name, = link_if_alive version, track.name,
admin_conference_program_track_path(conference_id: Conference.find(version.conference_id).short_title, id: track.try(:short_name)) admin_conference_program_track_path(conference_short_title, track.try(:short_name)),
conference
- when 'EventType' - when 'EventType'
= 'event type' event type
- event_type = current_or_last_object_state(version.item_type, version.item_id) - event_type = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, event_type.title, = link_if_alive version, event_type.title,
admin_conference_program_event_types_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_program_event_types_path(conference_short_title),
conference
- when 'Role' - when 'Role'
= 'role' role
- role = current_or_last_object_state(version.item_type, version.item_id) - role = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, role.name, - role_name = role.try(:name) || PaperTrail::Version.where(item_type: 'Role', item_id: version.item_id).last.changeset[:name].second
admin_conference_role_path(conference_id: Conference.find(version.conference_id).short_title, id: role.name) - if role_name == 'organization_admin'
-# organization_admin belongs to organization and not conferences
- organization = Organization.find(version.conference_id)
= link_if_alive version, role_name,
admins_admin_organization_path(organization), organization
- else
- conference = Conference.find_by(id: version.conference_id)
- conference_short_title = conference.try(:short_title) || current_or_last_object_state('Conference', version.conference_id).try(:short_title) || ' '
= link_if_alive version, role_name,
admin_conference_role_path(conference_short_title, role_name), conference
- when 'Venue' - when 'Venue'
= 'venue' venue
- venue = current_or_last_object_state(version.item_type, version.item_id) - venue = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, venue.name, = link_if_alive version, venue.name,
admin_conference_venue_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_venue_path(conference_short_title),
conference
- when 'Lodging' - when 'Lodging'
= 'lodging' lodging
- lodging = current_or_last_object_state(version.item_type, version.item_id) - lodging = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, lodging.name, = link_if_alive version, lodging.name,
admin_conference_lodgings_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_lodgings_path(conference_short_title),
conference
- when 'Room' - when 'Room'
= 'room' room
- room = current_or_last_object_state(version.item_type, version.item_id) - room = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, room.name, = link_if_alive version, room.name,
admin_conference_venue_rooms_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_venue_rooms_path(conference_short_title),
conference
- when 'Sponsor' - when 'Sponsor'
= 'sponsor' sponsor
- sponsor = current_or_last_object_state(version.item_type, version.item_id) - sponsor = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, sponsor.name, = link_if_alive version, sponsor.name,
admin_conference_sponsors_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_sponsors_path(conference_short_title),
conference
- when 'SponsorshipLevel' - when 'SponsorshipLevel'
= 'sponsorship level' sponsorship level
- sponsorship_level = current_or_last_object_state(version.item_type, version.item_id) - sponsorship_level = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, sponsorship_level.title, = link_if_alive version, sponsorship_level.title,
admin_conference_sponsorship_levels_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_sponsorship_levels_path(conference_short_title),
conference
- when 'Ticket' - when 'Ticket'
= 'ticket' ticket
- ticket = current_or_last_object_state(version.item_type, version.item_id) - ticket = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, ticket.title, = link_if_alive version, ticket.title,
admin_conference_ticket_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) admin_conference_ticket_path(conference_short_title, version.item_id),
conference
- when 'Campaign' - when 'Campaign'
= 'campaign' campaign
- campaign = current_or_last_object_state(version.item_type, version.item_id) - campaign = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, campaign.name, = link_if_alive version, campaign.name,
admin_conference_campaigns_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_campaigns_path(conference_short_title),
conference
- when 'DifficultyLevel' - when 'DifficultyLevel'
= 'difficulty level' difficulty level
- difficulty_level = current_or_last_object_state(version.item_type, version.item_id) - difficulty_level = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, difficulty_level.title, = link_if_alive version, difficulty_level.title,
admin_conference_program_difficulty_level_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) admin_conference_program_difficulty_level_path(conference_short_title, version.item_id),
conference
- when 'Splashpage' - when 'Splashpage'
= link_if_alive version, 'splashpage', = link_if_alive version, 'splashpage',
admin_conference_splashpage_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_splashpage_path(conference_short_title),
conference
- when 'EmailSettings' - when 'EmailSettings'
= link_if_alive version, 'email settings', = link_if_alive version, 'email settings',
admin_conference_emails_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_emails_path(conference_short_title),
conference
- when 'User' - when 'User'
- if version.event == 'update' - if version.event == 'update'
= 'user' user
= link_to (current_or_last_object_state('User', version.item_id).try(:name) || 'deleted user'), admin_user_path(id: version.item_id) = link_to_user(version.item_id)
- unless %w(Conference Subscription Registration User).include?(version.item_type) - unless %w(Conference Subscription Registration User Organization).include?(version.item_type)
= "in conference" - if (version.item_type == 'Role' && role_name == 'organization_admin') || (version.item_type == 'UsersRole' && role.name == 'organization_admin')
= link_to Conference.find(version.conference_id).short_title, in organization
edit_admin_conference_path(id: Conference.find(version.conference_id).short_title) = link_to_organization(version.conference_id)
- else
in conference
= link_to_conference(version.conference_id)

View file

@ -1,6 +1,16 @@
.row .row
.col-md-12 .col-md-12
.page-header .page-header
.dropdown.pull-right
%button.btn.btn-success.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button' }
= @conference.nil? ? 'All Conferences' : @conference.short_title
%span.caret
%ul.dropdown-menu
%li= link_to 'All Conferences & Users', admin_revision_history_path
- @conferences_with_role.each do |conference_short_title|
%li= link_to conference_short_title, admin_conference_revision_history_path(conference_id: conference_short_title)
%h1 Revision History %h1 Revision History
%p.text-muted %p.text-muted
Log of changes made to conferences and associated resources Log of changes made to conferences and associated resources

View file

@ -0,0 +1,30 @@
.container
.row
.col-md-8
= semantic_form_for(@booth, url: @url, html: { multipart: true }) do |f|
= f.input :title, as: :string, autofocus: true, required: true
= f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
hint: 'This field becomes public upon request acceptance'
= f.input :reasoning, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'How it fits the conference'
= f.input :submitter_relationship, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'Submitter\'s relation',
hint: 'e.g. employee, comunity manager, etc'
= f.input :website_url
= responsibles_selector_input f
= image_tag f.object.picture.thumb.url if f.object.picture?
= f.input :picture
%p.text-right
- if @booth.new_record?
= f.submit 'Create Booth Request', class: 'btn btn-success'
- else
= f.submit 'Update Booth Request', class: 'btn btn-success'
:javascript
$(document).ready(function() {
$('#booth_responsible_ids').selectize({
plugins: ['remove_button'],
minItems: 2
} )
});

View file

@ -0,0 +1,6 @@
.container
%h1
Editing
= @booth.title
= render 'form'

View file

@ -0,0 +1,51 @@
.container
.row
.col-md-12.page-header
%h1
Your booth requests for
= @conference.title
.row
.col-md-12
.margin-booth-table
%table.table.table-striped.table-hover
%thead
%th
%b State
%th
%b Logo
%th
%b Title
%th
%b Actions
- @booths.each do |booth|
%tr
%td{ style: "padding:20px 8px 20px 8px;" }
- if (booth.state == 'to_accept' || booth.state == 'to_reject')
- show_state = 'new'
- else
- show_state = booth.state
%span{ title: show_state, class: "fa #{booth_status_icon(booth)}" }
%td
- if booth.logo_link
= image_tag(booth.picture.thumb.url, width: '20%')
%td
= link_to booth.title, conference_booth_path(@conference.short_title, booth)
%td
-if can? :edit, booth
= link_to 'Edit', edit_conference_booth_path(@conference.short_title, booth.id),
class: 'btn btn-default'
- if booth.transition_possible? :withdraw
= link_to 'Withdraw',
withdraw_conference_booth_path(@conference.short_title, booth),
method: :patch, class: 'btn btn-mini btn-warning', id: "withdraw_booth_#{booth.id}",
data: { confirm: 'Are you sure you really want to withdraw this request?' }
- if booth.transition_possible? :confirm
= link_to 'Confirm',
confirm_conference_booth_path(@conference.short_title, booth),
method: :patch, class: 'btn btn-mini btn-success', id: "confirm_booth_#{booth.id}"
- if booth.transition_possible? :restart
= link_to 'Re-submit',
restart_conference_booth_path(@conference.short_title, booth),
method: :patch, class: 'btn btn-mini btn-success', id: "restart_booth_#{booth.id}"
.pull-right
= link_to 'Add Booth', new_conference_booth_path(@conference.short_title), class: 'button btn btn-primary'

View file

@ -0,0 +1,4 @@
.container
%h1 Request a booth
= render 'form'

View file

@ -0,0 +1,60 @@
.container
.row
.col-md-12
%h3
- if @booth.logo_link
= image_tag(@booth.picture.thumb.url, size: '20%', alt: '')
= @booth.title
.btn-group.pull-right
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, @booth), class: 'btn btn-mini btn-primary'
.row
.col-md-12
%table.table
%tr
%td.col-md-2
%b Description
%td
= markdown(@booth.description)
%tr
%td.col-md-2
%b Reasoning
%td
= markdown(@booth.reasoning)
%tr
%td.col-md-2
%b Website
%td
- if @booth.website_url.present?
= link_to @booth.website_url, @booth.website_url
%tr
%td.col-md-2
%b Submitter
%td
= link_to @booth.submitter.name, user_path(@booth.submitter)
%tr
%td.col-md-2
%b Submitter's relationship
%td
= @booth.submitter_relationship
%tr
%td.col-md-2
%b Responsibles
%td
- @booth.responsibles.each_with_index do |responsibles, i|
.responsibles
= link_to responsibles.name, user_path(responsibles)
(
= responsibles.email
)
= ", " unless i == @booth.responsibles.length - 1
%tr
%td.col-md-2
%b Submitted on
%td
= @booth.created_at
%tr
%td.col-md-2
%b Last updated on
%td
= @booth.updated_at

View file

@ -0,0 +1,24 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#booths' } Booths
.container
.row
.col-md-12.text-center
%h2 Booths
- @conference.booths.confirmed.each_slice(3).with_index do |slice, index_for_row|
.row.row-centered
- slice.each.with_index do |booth, index_for_column|
.col-md-4.col-sm-4.col-xs-10.col-centered.col-top
.thumbnail
- if booth.logo_link
= link_to booth.website_url, class: 'thumbnail' do
= image_tag booth.picture.large.url
.caption
%h3.text-center
= booth.title
%p.text-center.text-muted
= link_to "#show_descrition_#{index_for_row}_#{index_for_column}", "data-toggle"=>"collapse" do
learn more
.collapse{ id: "show_descrition_#{index_for_row}_#{index_for_column}" }
= markdown(booth.description)

View file

@ -0,0 +1,30 @@
= content_for :splash_nav do
%li
%a.smoothscroll{ href: '#callfortracks' } Call For Tracks
.container
.row
.col-md-12.text-center
%h2
Call for Tracks
%p.lead
We are ready to accept requests for tracks!
.row
.col-md-6.col-md-offset-3.col-sm-10.col-sm-offset-1
%p
The submission period for track requests has begun
%em.notranslate
= @conference.program.cfps.for_tracks.start_date.strftime('%A, %B %-d. %Y')
and closes
%em.notranslate
= @conference.program.cfps.for_tracks.end_date.strftime('%A, %B %-d. %Y.')
- if @conference.program.cfps.for_tracks.try(:open?)
That means you have only
%b.notranslate= pluralize(@conference.program.cfps.for_tracks.remaining_days, 'day')
left!
- else
The submission period for track requests is closed.
.row
.col-md-12.text-center
%p.cta-button
= link_to "Submit your request for track", conference_program_tracks_path(@conference.short_title), class: 'btn btn-success btn-lg text-center'

View file

@ -30,10 +30,18 @@
= link_to "Register", new_conference_conference_registration_path(conference.short_title), class: "btn btn-default", disabled: cannot?(:new, Registration.new(conference_id: conference.id)) = link_to "Register", new_conference_conference_registration_path(conference.short_title), class: "btn btn-default", disabled: cannot?(:new, Registration.new(conference_id: conference.id))
- if cannot?(:new, Registration.new(conference_id: conference.id)) && conference.registration_limit_exceeded? - if cannot?(:new, Registration.new(conference_id: conference.id)) && conference.registration_limit_exceeded?
Sorry, no places left Sorry, no places left
- if !current_user.nil? && current_user.tracks.where(program: conference.program).length > 0
= link_to "My Track Requests", conference_program_tracks_path(conference.short_title), class: 'btn btn-default'
- elsif can? :new, conference.program.tracks.new
= link_to "Submit Track Request", new_conference_program_track_path(conference.short_title), class: 'btn btn-default'
- if !current_user.nil? && current_user.proposal_count(conference) > 0 - if !current_user.nil? && current_user.proposal_count(conference) > 0
= link_to "My Proposals", conference_program_proposals_path(conference.short_title), class: 'btn btn-default' = link_to "My Proposals", conference_program_proposals_path(conference.short_title), class: 'btn btn-default'
- elsif can? :new, conference.program.events.new - elsif can? :new, conference.program.events.new
= link_to "Submit Proposal", new_conference_program_proposal_path(conference.short_title), class: 'btn btn-default' = link_to "Submit Proposal", new_conference_program_proposal_path(conference.short_title), class: 'btn btn-default'
- if current_user && current_user.booths.where(conference_id: conference.id).count > 0
= link_to 'My Booth Requests', conference_booths_path(conference.short_title), class: 'btn btn-default'
- elsif can? :new, conference.booths.new
= link_to 'Request Booth', new_conference_booth_path(conference.short_title), class: 'btn btn-default'
- if current_user.nil? || !current_user.subscribed?(conference) - if current_user.nil? || !current_user.subscribed?(conference)
= link_to 'Subscribe', conference_subscriptions_path(conference.short_title), method: :post, class: 'btn btn-default' = link_to 'Subscribe', conference_subscriptions_path(conference.short_title), method: :post, class: 'btn btn-default'
- else - else

View file

@ -12,22 +12,26 @@
= @conference.venue.city = @conference.venue.city
%p.lead %p.lead
We recommend these affordable lodging accommodations for your visit. We recommend these affordable lodging accommodations for your visit.
- @conference.lodgings.each_slice(3) do |slice|
.row.row-centered .row.row-centered{ style:"display: flex; flex-wrap: wrap" }
- slice.each do |lodging| - @conference.lodgings.each do |lodging|
.col-md-4.col-sm-4.ticket.col-centered.col-top .col-md-4.col-sm-4.col-centered.col-top{ style:"display:flex;" }
.thumbnail .thumbnail
- unless lodging.picture? - if lodging.picture?
%p.text-center -if lodging.website_link.present?
%i.fa.fa-home.fa-5x = link_to(lodging.website_link, class: 'thumbnail') do
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging'
- else - else
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging'
- else
%p.text-center
-if lodging.website_link.present? -if lodging.website_link.present?
= link_to(lodging.website_link, class: 'thumbnail') do = link_to(lodging.website_link, class: 'thumbnail') do
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging' %i.fa.fa-home.fa-5x
- else - else
= image_tag lodging.picture.large.url, class: 'img-responsive img-lodging' %i.fa.fa-home.fa-5x
.caption .caption
%h3.text-center %h3.text-center
= lodging.name = lodging.name
-if lodging.description.present? -if lodging.description.present?
= markdown(lodging.description) = markdown(lodging.description)

View file

@ -10,13 +10,22 @@
- if @conference.splashpage and @conference.program.tracks.any? and @conference.splashpage.include_tracks - if @conference.splashpage and @conference.program.tracks.any? and @conference.splashpage.include_tracks
See rock-star speakers cover the topics of See rock-star speakers cover the topics of
- if @conference.splashpage and @conference.splashpage.include_tracks - if @conference.splashpage and @conference.splashpage.include_tracks
- @conference.program.tracks.each_slice(3) do |slice| - @conference.program.tracks.confirmed.cfp_active.each_slice(3) do |slice|
.row.row-centered .row.row-centered
- slice.each do |track| - slice.each do |track|
.col-md-4.col-sm-4.col-centered.col-top.track .col-md-4.col-sm-4.col-centered.col-top.track
%h4.text-center %h4.text-center
= track.name = track.name
= markdown(track.description) = markdown(track.description)
- if track.start_date
%br
From: #{track.start_date.strftime('%A, %B %-d. %Y')}
- if track.end_date
%br
To: #{track.end_date.strftime('%A, %B %-d. %Y')}
- if track.room
%br
In: #{track.room.name}
- if @conference.program and @conference.program.schedule_public - if @conference.program and @conference.program.schedule_public
.row .row

View file

@ -45,6 +45,10 @@
%section#program %section#program
= render 'schedule_splashpage' = render 'schedule_splashpage'
- if @conference.program.cfps.for_tracks.try(:open?) && @conference.splashpage.include_cfp
%section#callfortracks
= render 'call_for_tracks'
- if @conference.program.cfp_open? and @conference.splashpage.include_cfp - if @conference.program.cfp_open? and @conference.splashpage.include_cfp
%section#callforpapers %section#callforpapers
= render 'call_for_paper' = render 'call_for_paper'
@ -61,6 +65,10 @@
%section#tickets %section#tickets
= render 'tickets' = render 'tickets'
- if @conference.booths.confirmed.any? and @conference.splashpage.include_booths
%section#booths
= render 'booths'
- if @conference.sponsors.any? and @conference.splashpage.include_sponsors - if @conference.sponsors.any? and @conference.splashpage.include_sponsors
%section#sponsors %section#sponsors
= render 'sponsors' = render 'sponsors'

View file

@ -1,4 +1,4 @@
%ul.nav.nav-stacked.nav-pills.mySidebar %ul.nav.nav-stacked.nav-pills.mySidebar.collapse.navbar-collapse#side-nav
.btn-group .btn-group
%button{type:'button', class: 'btn btn-default btn-link dropdown-toggle', 'data-toggle'=>'dropdown'} %button{type:'button', class: 'btn btn-default btn-link dropdown-toggle', 'data-toggle'=>'dropdown'}
%span.fa.fa-cog %span.fa.fa-cog
@ -116,7 +116,11 @@
- if can? :update, @conference.tickets.build - if can? :update, @conference.tickets.build
%li{class: active_nav_li(admin_conference_tickets_path(@conference.short_title)) } %li{class: active_nav_li(admin_conference_tickets_path(@conference.short_title)) }
= link_to 'Tickets', admin_conference_tickets_path(@conference.short_title) = link_to 'Tickets', admin_conference_tickets_path(@conference.short_title)
- if can? :manage, @conference.booths.build
%li
= link_to admin_conference_booths_path(@conference.short_title) do
%span.fa.fa-shopping-bag
Booths
- if (can? :manage, @conference.targets.build) || (can? :manage, @conference.campaigns.build) - if (can? :manage, @conference.targets.build) || (can? :manage, @conference.campaigns.build)
%li %li
%a %a
@ -139,8 +143,15 @@
= link_to(admin_conference_roles_path(@conference.short_title)) do = link_to(admin_conference_roles_path(@conference.short_title)) do
%span.fa.fa-group %span.fa.fa-group
Roles Roles
- if can? :index, @conference.resources.new - if can? :index, @conference.resources.new
%li %li
= link_to admin_conference_resources_path(@conference.short_title) do = link_to admin_conference_resources_path(@conference.short_title) do
%span.fa.fa-pencil-square %span.fa.fa-pencil-square
Resources Resources
- if can?(:index, PaperTrail::Version.new(conference_id: @conference.id, item_type: 'Event')) || can?(:index, PaperTrail::Version.new(conference_id: @conference.id, item_type: 'Registration'))
%li{:class=> active_nav_li(admin_conference_revision_history_path(@conference.short_title))}
= link_to(admin_conference_revision_history_path(@conference.short_title)) do
%span.fa.fa-history
Revision History

Some files were not shown because too many files have changed in this diff Show more